chore: commit pending admin-panel, api auth and parity doc changes
Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Haiku 5.5
parent
55856cac89
commit
cf014e1f6c
@@ -0,0 +1,85 @@
|
||||
import { ForbiddenException, type ExecutionContext } from '@nestjs/common';
|
||||
import { Reflector } from '@nestjs/core';
|
||||
import { PermissionsGuard, RequirePermission, SuperAdminOnly } from './guards';
|
||||
import type { AuthenticatedAdmin } from './jwt.strategy';
|
||||
import { SUPER_ADMIN_MOBILE, withSuperAdminRids } from './super-admin';
|
||||
|
||||
class Routes {
|
||||
@SuperAdminOnly()
|
||||
@RequirePermission('config.wallet')
|
||||
superOnly() {}
|
||||
|
||||
@SuperAdminOnly({ allowBranch: true })
|
||||
@RequirePermission('order.list')
|
||||
superOrBranch() {}
|
||||
|
||||
@RequirePermission('order.list', 'order.omde', 'order.tamin')
|
||||
anyOf() {}
|
||||
|
||||
open() {}
|
||||
}
|
||||
|
||||
function admin(over: Partial<AuthenticatedAdmin> = {}): AuthenticatedAdmin {
|
||||
return {
|
||||
id: 'a1',
|
||||
fullName: 'x',
|
||||
mobile: '09120000000',
|
||||
role: 'SUPER_ADMIN',
|
||||
userTypeId: 85,
|
||||
branchId: null,
|
||||
permissions: ['config.wallet', 'order.list', 'order.omde'],
|
||||
...over,
|
||||
};
|
||||
}
|
||||
|
||||
function run(handler: keyof Routes, user: AuthenticatedAdmin) {
|
||||
const ctx = {
|
||||
getHandler: () => Routes.prototype[handler],
|
||||
getClass: () => Routes,
|
||||
switchToHttp: () => ({ getRequest: () => ({ user }) }),
|
||||
} as unknown as ExecutionContext;
|
||||
return new PermissionsGuard(new Reflector()).canActivate(ctx);
|
||||
}
|
||||
|
||||
describe('PermissionsGuard — super-admin-only routes', () => {
|
||||
it('admits the super admin', () => {
|
||||
expect(run('superOnly', admin({ mobile: SUPER_ADMIN_MOBILE }))).toBe(true);
|
||||
});
|
||||
|
||||
it('refuses any other admin, even one holding the rid and the SUPER_ADMIN role', () => {
|
||||
expect(() => run('superOnly', admin())).toThrow(ForbiddenException);
|
||||
});
|
||||
|
||||
it('refuses a branch admin unless the route allows branches', () => {
|
||||
expect(() => run('superOnly', admin({ branchId: 'b1' }))).toThrow(ForbiddenException);
|
||||
expect(run('superOrBranch', admin({ branchId: 'b1' }))).toBe(true);
|
||||
expect(() => run('superOrBranch', admin())).toThrow(ForbiddenException);
|
||||
});
|
||||
|
||||
it('still requires the rid from a branch admin', () => {
|
||||
expect(() => run('superOrBranch', admin({ branchId: 'b1', permissions: [] }))).toThrow(
|
||||
ForbiddenException,
|
||||
);
|
||||
});
|
||||
|
||||
it('leaves routes without the decorator alone', () => {
|
||||
expect(run('open', admin({ permissions: [] }))).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('PermissionsGuard — several rids', () => {
|
||||
it('admits a holder of any one of them', () => {
|
||||
expect(run('anyOf', admin({ permissions: ['order.tamin'] }))).toBe(true);
|
||||
});
|
||||
|
||||
it('refuses a holder of none', () => {
|
||||
expect(() => run('anyOf', admin({ permissions: ['product.list'] }))).toThrow(ForbiddenException);
|
||||
});
|
||||
});
|
||||
|
||||
describe('withSuperAdminRids', () => {
|
||||
it('adds the super-admin rids for the super admin only', () => {
|
||||
expect(withSuperAdminRids(SUPER_ADMIN_MOBILE, [])).toContain('config.wallet');
|
||||
expect(withSuperAdminRids('09120000000', ['product.list'])).toEqual(['product.list']);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user