fix: allow oauth login without workspace payload

This commit is contained in:
inman
2026-04-29 14:33:41 +08:00
parent 85b1863bd7
commit 3b252250cd
2 changed files with 116 additions and 11 deletions

View File

@@ -501,6 +501,77 @@ describe('HttpYinianControlPlane', () => {
expect((await storage.getSession())?.refreshToken).toBe('refresh_onefeel');
});
it('creates a local organization session when oauth token response has no profile payload', async () => {
const storage = createMemoryYinianStorage();
const controlPlane = new HttpYinianControlPlane({
apiBaseUrl: 'https://api.example.test',
storage,
});
installFetchRoutes({
'POST /auth/oauth2/token': {
access_token: 'access_without_profile',
refresh_token: 'refresh_without_profile',
expires_in: 3600,
},
});
const session = await controlPlane.loginWithPassword({
account: 'tmt1',
password: '123456',
});
expect(session.authenticated).toBe(true);
expect(session.user).toMatchObject({
id: 'tmt1',
name: 'tmt1',
});
expect(session.hotels).toEqual([
expect.objectContaining({
id: 'service_default',
name: 'tmt1的组织空间',
}),
]);
expect(session.currentHotelId).toBe('service_default');
expect((await storage.getSession())?.refreshToken).toBe('refresh_without_profile');
});
it('uses JWT claims as a fallback profile for oauth token responses', async () => {
const storage = createMemoryYinianStorage();
const controlPlane = new HttpYinianControlPlane({
apiBaseUrl: 'https://api.example.test',
storage,
});
const claims = Buffer.from(JSON.stringify({
user_id: 'jwt-user-1',
user_name: 'jwt-user',
tenant_id: 'tenant-9',
tenant_name: 'JWT 组织',
})).toString('base64url');
installFetchRoutes({
'POST /auth/oauth2/token': {
access_token: `header.${claims}.signature`,
refresh_token: 'refresh_jwt',
expires_in: 3600,
},
});
const session = await controlPlane.loginWithPassword({
account: 'fallback-account',
password: '123456',
});
expect(session.user).toMatchObject({
id: 'jwt-user-1',
name: 'jwt-user',
});
expect(session.hotels).toEqual([
expect.objectContaining({
id: 'service_tenant-9',
name: 'JWT 组织',
}),
]);
});
it('reports HTTP server status through health endpoint', async () => {
const controlPlane = new HttpYinianControlPlane({
apiBaseUrl: 'https://api.example.test',