feat(app): wire dashboard administration flows
This commit is contained in:
+94
-1
@@ -1,16 +1,21 @@
|
||||
import { tap, expect } from '@git.zone/tstest/tapbundle';
|
||||
|
||||
import { App } from '../ts/reception/classes.app.js';
|
||||
import { AppConnection } from '../ts/reception/classes.appconnection.js';
|
||||
import { OidcAccessToken } from '../ts/reception/classes.oidcaccesstoken.js';
|
||||
import { OidcAuthorizationCode } from '../ts/reception/classes.oidcauthorizationcode.js';
|
||||
import { OidcManager } from '../ts/reception/classes.oidcmanager.js';
|
||||
import { OidcRefreshToken } from '../ts/reception/classes.oidcrefreshtoken.js';
|
||||
import { OidcUserConsent } from '../ts/reception/classes.oidcuserconsent.js';
|
||||
import { Role } from '../ts/reception/classes.role.js';
|
||||
import { User } from '../ts/reception/classes.user.js';
|
||||
|
||||
const createTestOidcManager = () => {
|
||||
const createTestOidcManager = (receptionOverridesArg: Record<string, any> = {}) => {
|
||||
const oidcManager = new OidcManager({
|
||||
db: { smartdataDb: {} },
|
||||
typedrouter: { addTypedRouter: () => undefined },
|
||||
options: { baseUrl: 'https://idp.example' },
|
||||
...receptionOverridesArg,
|
||||
} as any);
|
||||
void oidcManager.stop();
|
||||
return oidcManager;
|
||||
@@ -205,4 +210,92 @@ tap.test('prepares OAuth authorization as ready when consent already exists', as
|
||||
await oidcManager.stop();
|
||||
});
|
||||
|
||||
tap.test('includes connected app role mappings in roles-scope claims', async () => {
|
||||
const user = new User();
|
||||
user.id = 'user-1';
|
||||
user.data = {
|
||||
name: 'Finance User',
|
||||
username: 'finance-user',
|
||||
email: 'finance@example.com',
|
||||
status: 'active',
|
||||
connectedOrgs: ['org-1'],
|
||||
};
|
||||
|
||||
const role = new Role();
|
||||
role.id = 'role-1';
|
||||
role.data = {
|
||||
userId: user.id,
|
||||
organizationId: 'org-1',
|
||||
roles: ['finance'],
|
||||
};
|
||||
|
||||
const app = new App();
|
||||
app.id = 'app-1';
|
||||
app.type = 'global';
|
||||
app.data = {
|
||||
name: 'Accounting',
|
||||
description: 'Accounting app',
|
||||
logoUrl: '',
|
||||
appUrl: 'https://accounting.example',
|
||||
category: 'finance',
|
||||
isActive: true,
|
||||
createdAt: Date.now(),
|
||||
createdByUserId: 'admin-1',
|
||||
oauthCredentials: {
|
||||
clientId: 'client-1',
|
||||
clientSecretHash: 'secret-hash',
|
||||
redirectUris: ['https://accounting.example/callback'],
|
||||
allowedScopes: ['openid', 'roles'],
|
||||
grantTypes: ['authorization_code'],
|
||||
},
|
||||
};
|
||||
|
||||
const connection = new AppConnection();
|
||||
connection.id = 'connection-1';
|
||||
connection.data = {
|
||||
organizationId: 'org-1',
|
||||
appId: app.id,
|
||||
appType: 'global',
|
||||
status: 'active',
|
||||
connectedAt: Date.now(),
|
||||
connectedByUserId: 'admin-1',
|
||||
grantedScopes: ['openid', 'roles'],
|
||||
roleMappings: [{
|
||||
orgRoleKey: 'finance',
|
||||
appRoles: ['accountant'],
|
||||
permissions: ['invoices:read'],
|
||||
scopes: ['billing'],
|
||||
}],
|
||||
};
|
||||
|
||||
const oidcManager = createTestOidcManager({
|
||||
userManager: {
|
||||
CUser: {
|
||||
getInstance: async () => user,
|
||||
},
|
||||
},
|
||||
roleManager: {
|
||||
getAllRolesForUser: async () => [role],
|
||||
},
|
||||
appManager: {
|
||||
CApp: {
|
||||
getInstances: async () => [app],
|
||||
},
|
||||
},
|
||||
appConnectionManager: {
|
||||
CAppConnection: {
|
||||
getInstances: async () => [connection],
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const claims = await (oidcManager as any).getUserClaims(user.id, ['roles'], 'client-1');
|
||||
|
||||
expect(claims.app_roles).toEqual(['accountant']);
|
||||
expect(claims.app_permissions).toEqual(['invoices:read']);
|
||||
expect(claims.app_scopes).toEqual(['billing']);
|
||||
|
||||
await oidcManager.stop();
|
||||
});
|
||||
|
||||
export default tap.start();
|
||||
|
||||
Reference in New Issue
Block a user