@spinajs/rbac-http-token 2.0.507
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +152 -0
- package/lib/cjs/actions.d.ts +119 -0
- package/lib/cjs/actions.d.ts.map +1 -0
- package/lib/cjs/actions.js +257 -0
- package/lib/cjs/actions.js.map +1 -0
- package/lib/cjs/cli/CreateToken.d.ts +13 -0
- package/lib/cjs/cli/CreateToken.d.ts.map +1 -0
- package/lib/cjs/cli/CreateToken.js +56 -0
- package/lib/cjs/cli/CreateToken.js.map +1 -0
- package/lib/cjs/cli/DeleteExpiredTokens.d.ts +11 -0
- package/lib/cjs/cli/DeleteExpiredTokens.d.ts.map +1 -0
- package/lib/cjs/cli/DeleteExpiredTokens.js +39 -0
- package/lib/cjs/cli/DeleteExpiredTokens.js.map +1 -0
- package/lib/cjs/cli/DeleteToken.d.ts +7 -0
- package/lib/cjs/cli/DeleteToken.d.ts.map +1 -0
- package/lib/cjs/cli/DeleteToken.js +36 -0
- package/lib/cjs/cli/DeleteToken.js.map +1 -0
- package/lib/cjs/cli/GrantTokenRole.d.ts +7 -0
- package/lib/cjs/cli/GrantTokenRole.d.ts.map +1 -0
- package/lib/cjs/cli/GrantTokenRole.js +37 -0
- package/lib/cjs/cli/GrantTokenRole.js.map +1 -0
- package/lib/cjs/cli/RevokeTokenRole.d.ts +12 -0
- package/lib/cjs/cli/RevokeTokenRole.d.ts.map +1 -0
- package/lib/cjs/cli/RevokeTokenRole.js +42 -0
- package/lib/cjs/cli/RevokeTokenRole.js.map +1 -0
- package/lib/cjs/config/rbac-http-token.d.ts +71 -0
- package/lib/cjs/config/rbac-http-token.d.ts.map +1 -0
- package/lib/cjs/config/rbac-http-token.js +98 -0
- package/lib/cjs/config/rbac-http-token.js.map +1 -0
- package/lib/cjs/controllers/AccessTokenController.d.ts +139 -0
- package/lib/cjs/controllers/AccessTokenController.d.ts.map +1 -0
- package/lib/cjs/controllers/AccessTokenController.js +264 -0
- package/lib/cjs/controllers/AccessTokenController.js.map +1 -0
- package/lib/cjs/dto/create-token-dto.d.ts +34 -0
- package/lib/cjs/dto/create-token-dto.d.ts.map +1 -0
- package/lib/cjs/dto/create-token-dto.js +35 -0
- package/lib/cjs/dto/create-token-dto.js.map +1 -0
- package/lib/cjs/events/AccessTokenCreated.d.ts +4 -0
- package/lib/cjs/events/AccessTokenCreated.d.ts.map +1 -0
- package/lib/cjs/events/AccessTokenCreated.js +18 -0
- package/lib/cjs/events/AccessTokenCreated.js.map +1 -0
- package/lib/cjs/events/AccessTokenDeleted.d.ts +4 -0
- package/lib/cjs/events/AccessTokenDeleted.d.ts.map +1 -0
- package/lib/cjs/events/AccessTokenDeleted.js +18 -0
- package/lib/cjs/events/AccessTokenDeleted.js.map +1 -0
- package/lib/cjs/events/AccessTokenEvent.d.ts +10 -0
- package/lib/cjs/events/AccessTokenEvent.d.ts.map +1 -0
- package/lib/cjs/events/AccessTokenEvent.js +26 -0
- package/lib/cjs/events/AccessTokenEvent.js.map +1 -0
- package/lib/cjs/events/AccessTokenRoleGranted.d.ts +7 -0
- package/lib/cjs/events/AccessTokenRoleGranted.d.ts.map +1 -0
- package/lib/cjs/events/AccessTokenRoleGranted.js +27 -0
- package/lib/cjs/events/AccessTokenRoleGranted.js.map +1 -0
- package/lib/cjs/events/AccessTokenRoleRevoked.d.ts +7 -0
- package/lib/cjs/events/AccessTokenRoleRevoked.d.ts.map +1 -0
- package/lib/cjs/events/AccessTokenRoleRevoked.js +27 -0
- package/lib/cjs/events/AccessTokenRoleRevoked.js.map +1 -0
- package/lib/cjs/events/index.d.ts +6 -0
- package/lib/cjs/events/index.d.ts.map +1 -0
- package/lib/cjs/events/index.js +22 -0
- package/lib/cjs/events/index.js.map +1 -0
- package/lib/cjs/generator.d.ts +12 -0
- package/lib/cjs/generator.d.ts.map +1 -0
- package/lib/cjs/generator.js +42 -0
- package/lib/cjs/generator.js.map +1 -0
- package/lib/cjs/index.d.ts +20 -0
- package/lib/cjs/index.d.ts.map +1 -0
- package/lib/cjs/index.js +39 -0
- package/lib/cjs/index.js.map +1 -0
- package/lib/cjs/interfaces.d.ts +57 -0
- package/lib/cjs/interfaces.d.ts.map +1 -0
- package/lib/cjs/interfaces.js +11 -0
- package/lib/cjs/interfaces.js.map +1 -0
- package/lib/cjs/middlewares.d.ts +76 -0
- package/lib/cjs/middlewares.d.ts.map +1 -0
- package/lib/cjs/middlewares.js +181 -0
- package/lib/cjs/middlewares.js.map +1 -0
- package/lib/cjs/migrations/RbacHttpTokenInitial_2026_08_11_01_00_00.d.ts +6 -0
- package/lib/cjs/migrations/RbacHttpTokenInitial_2026_08_11_01_00_00.d.ts.map +1 -0
- package/lib/cjs/migrations/RbacHttpTokenInitial_2026_08_11_01_00_00.js +38 -0
- package/lib/cjs/migrations/RbacHttpTokenInitial_2026_08_11_01_00_00.js.map +1 -0
- package/lib/cjs/models/AccessToken.d.ts +55 -0
- package/lib/cjs/models/AccessToken.d.ts.map +1 -0
- package/lib/cjs/models/AccessToken.js +73 -0
- package/lib/cjs/models/AccessToken.js.map +1 -0
- package/lib/cjs/package.json +1 -0
- package/lib/cjs/policies/NoImpersonationPolicy.d.ts +28 -0
- package/lib/cjs/policies/NoImpersonationPolicy.d.ts.map +1 -0
- package/lib/cjs/policies/NoImpersonationPolicy.js +45 -0
- package/lib/cjs/policies/NoImpersonationPolicy.js.map +1 -0
- package/lib/cjs/policies/NoTokenAuthPolicy.d.ts +12 -0
- package/lib/cjs/policies/NoTokenAuthPolicy.d.ts.map +1 -0
- package/lib/cjs/policies/NoTokenAuthPolicy.js +24 -0
- package/lib/cjs/policies/NoTokenAuthPolicy.js.map +1 -0
- package/lib/cjs/policies/TokenPolicy.d.ts +49 -0
- package/lib/cjs/policies/TokenPolicy.d.ts.map +1 -0
- package/lib/cjs/policies/TokenPolicy.js +79 -0
- package/lib/cjs/policies/TokenPolicy.js.map +1 -0
- package/lib/mjs/actions.d.ts +119 -0
- package/lib/mjs/actions.d.ts.map +1 -0
- package/lib/mjs/actions.js +242 -0
- package/lib/mjs/actions.js.map +1 -0
- package/lib/mjs/cli/CreateToken.d.ts +13 -0
- package/lib/mjs/cli/CreateToken.d.ts.map +1 -0
- package/lib/mjs/cli/CreateToken.js +53 -0
- package/lib/mjs/cli/CreateToken.js.map +1 -0
- package/lib/mjs/cli/DeleteExpiredTokens.d.ts +11 -0
- package/lib/mjs/cli/DeleteExpiredTokens.d.ts.map +1 -0
- package/lib/mjs/cli/DeleteExpiredTokens.js +36 -0
- package/lib/mjs/cli/DeleteExpiredTokens.js.map +1 -0
- package/lib/mjs/cli/DeleteToken.d.ts +7 -0
- package/lib/mjs/cli/DeleteToken.d.ts.map +1 -0
- package/lib/mjs/cli/DeleteToken.js +33 -0
- package/lib/mjs/cli/DeleteToken.js.map +1 -0
- package/lib/mjs/cli/GrantTokenRole.d.ts +7 -0
- package/lib/mjs/cli/GrantTokenRole.d.ts.map +1 -0
- package/lib/mjs/cli/GrantTokenRole.js +34 -0
- package/lib/mjs/cli/GrantTokenRole.js.map +1 -0
- package/lib/mjs/cli/RevokeTokenRole.d.ts +12 -0
- package/lib/mjs/cli/RevokeTokenRole.d.ts.map +1 -0
- package/lib/mjs/cli/RevokeTokenRole.js +39 -0
- package/lib/mjs/cli/RevokeTokenRole.js.map +1 -0
- package/lib/mjs/config/rbac-http-token.d.ts +71 -0
- package/lib/mjs/config/rbac-http-token.d.ts.map +1 -0
- package/lib/mjs/config/rbac-http-token.js +96 -0
- package/lib/mjs/config/rbac-http-token.js.map +1 -0
- package/lib/mjs/controllers/AccessTokenController.d.ts +139 -0
- package/lib/mjs/controllers/AccessTokenController.d.ts.map +1 -0
- package/lib/mjs/controllers/AccessTokenController.js +261 -0
- package/lib/mjs/controllers/AccessTokenController.js.map +1 -0
- package/lib/mjs/dto/create-token-dto.d.ts +34 -0
- package/lib/mjs/dto/create-token-dto.d.ts.map +1 -0
- package/lib/mjs/dto/create-token-dto.js +32 -0
- package/lib/mjs/dto/create-token-dto.js.map +1 -0
- package/lib/mjs/events/AccessTokenCreated.d.ts +4 -0
- package/lib/mjs/events/AccessTokenCreated.d.ts.map +1 -0
- package/lib/mjs/events/AccessTokenCreated.js +15 -0
- package/lib/mjs/events/AccessTokenCreated.js.map +1 -0
- package/lib/mjs/events/AccessTokenDeleted.d.ts +4 -0
- package/lib/mjs/events/AccessTokenDeleted.d.ts.map +1 -0
- package/lib/mjs/events/AccessTokenDeleted.js +15 -0
- package/lib/mjs/events/AccessTokenDeleted.js.map +1 -0
- package/lib/mjs/events/AccessTokenEvent.d.ts +10 -0
- package/lib/mjs/events/AccessTokenEvent.d.ts.map +1 -0
- package/lib/mjs/events/AccessTokenEvent.js +23 -0
- package/lib/mjs/events/AccessTokenEvent.js.map +1 -0
- package/lib/mjs/events/AccessTokenRoleGranted.d.ts +7 -0
- package/lib/mjs/events/AccessTokenRoleGranted.d.ts.map +1 -0
- package/lib/mjs/events/AccessTokenRoleGranted.js +24 -0
- package/lib/mjs/events/AccessTokenRoleGranted.js.map +1 -0
- package/lib/mjs/events/AccessTokenRoleRevoked.d.ts +7 -0
- package/lib/mjs/events/AccessTokenRoleRevoked.d.ts.map +1 -0
- package/lib/mjs/events/AccessTokenRoleRevoked.js +24 -0
- package/lib/mjs/events/AccessTokenRoleRevoked.js.map +1 -0
- package/lib/mjs/events/index.d.ts +6 -0
- package/lib/mjs/events/index.d.ts.map +1 -0
- package/lib/mjs/events/index.js +6 -0
- package/lib/mjs/events/index.js.map +1 -0
- package/lib/mjs/generator.d.ts +12 -0
- package/lib/mjs/generator.d.ts.map +1 -0
- package/lib/mjs/generator.js +39 -0
- package/lib/mjs/generator.js.map +1 -0
- package/lib/mjs/index.d.ts +20 -0
- package/lib/mjs/index.d.ts.map +1 -0
- package/lib/mjs/index.js +23 -0
- package/lib/mjs/index.js.map +1 -0
- package/lib/mjs/interfaces.d.ts +57 -0
- package/lib/mjs/interfaces.d.ts.map +1 -0
- package/lib/mjs/interfaces.js +7 -0
- package/lib/mjs/interfaces.js.map +1 -0
- package/lib/mjs/middlewares.d.ts +76 -0
- package/lib/mjs/middlewares.d.ts.map +1 -0
- package/lib/mjs/middlewares.js +178 -0
- package/lib/mjs/middlewares.js.map +1 -0
- package/lib/mjs/migrations/RbacHttpTokenInitial_2026_08_11_01_00_00.d.ts +6 -0
- package/lib/mjs/migrations/RbacHttpTokenInitial_2026_08_11_01_00_00.d.ts.map +1 -0
- package/lib/mjs/migrations/RbacHttpTokenInitial_2026_08_11_01_00_00.js +35 -0
- package/lib/mjs/migrations/RbacHttpTokenInitial_2026_08_11_01_00_00.js.map +1 -0
- package/lib/mjs/models/AccessToken.d.ts +55 -0
- package/lib/mjs/models/AccessToken.d.ts.map +1 -0
- package/lib/mjs/models/AccessToken.js +70 -0
- package/lib/mjs/models/AccessToken.js.map +1 -0
- package/lib/mjs/package.json +1 -0
- package/lib/mjs/policies/NoImpersonationPolicy.d.ts +28 -0
- package/lib/mjs/policies/NoImpersonationPolicy.d.ts.map +1 -0
- package/lib/mjs/policies/NoImpersonationPolicy.js +41 -0
- package/lib/mjs/policies/NoImpersonationPolicy.js.map +1 -0
- package/lib/mjs/policies/NoTokenAuthPolicy.d.ts +12 -0
- package/lib/mjs/policies/NoTokenAuthPolicy.d.ts.map +1 -0
- package/lib/mjs/policies/NoTokenAuthPolicy.js +20 -0
- package/lib/mjs/policies/NoTokenAuthPolicy.js.map +1 -0
- package/lib/mjs/policies/TokenPolicy.d.ts +49 -0
- package/lib/mjs/policies/TokenPolicy.d.ts.map +1 -0
- package/lib/mjs/policies/TokenPolicy.js +75 -0
- package/lib/mjs/policies/TokenPolicy.js.map +1 -0
- package/lib/tsconfig.cjs.tsbuildinfo +1 -0
- package/lib/tsconfig.mjs.tsbuildinfo +1 -0
- package/package.json +78 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AccessTokenDeleted.js","sourceRoot":"","sources":["../../../src/events/AccessTokenDeleted.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AACvC,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAGlD,IAAM,kBAAkB,GAAxB,MAAM,kBAAmB,SAAQ,gBAAgB;CAAG,CAAA;AAA9C,kBAAkB;IAD9B,KAAK,EAAE;GACK,kBAAkB,CAA4B"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { QueueEvent } from '@spinajs/queue';
|
|
2
|
+
import { AccessToken } from '../models/AccessToken.js';
|
|
3
|
+
export declare class AccessTokenEvent extends QueueEvent {
|
|
4
|
+
/**
|
|
5
|
+
* Public token identifier. Never the token material.
|
|
6
|
+
*/
|
|
7
|
+
TokenUuid: string;
|
|
8
|
+
constructor(token: AccessToken);
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=AccessTokenEvent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AccessTokenEvent.d.ts","sourceRoot":"","sources":["../../../src/events/AccessTokenEvent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAS,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAEvD,qBACa,gBAAiB,SAAQ,UAAU;IAC9C;;OAEG;IACI,SAAS,EAAE,MAAM,CAAC;IAEzB,YAAY,KAAK,EAAE,WAAW,EAG7B;CACF"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
+
};
|
|
10
|
+
import { QueueEvent, Event } from '@spinajs/queue';
|
|
11
|
+
import { AccessToken } from '../models/AccessToken.js';
|
|
12
|
+
let AccessTokenEvent = class AccessTokenEvent extends QueueEvent {
|
|
13
|
+
constructor(token) {
|
|
14
|
+
super();
|
|
15
|
+
this.TokenUuid = token.Uuid;
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
AccessTokenEvent = __decorate([
|
|
19
|
+
Event(),
|
|
20
|
+
__metadata("design:paramtypes", [AccessToken])
|
|
21
|
+
], AccessTokenEvent);
|
|
22
|
+
export { AccessTokenEvent };
|
|
23
|
+
//# sourceMappingURL=AccessTokenEvent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AccessTokenEvent.js","sourceRoot":"","sources":["../../../src/events/AccessTokenEvent.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAGhD,IAAM,gBAAgB,GAAtB,MAAM,gBAAiB,SAAQ,UAAU;IAM9C,YAAY,KAAkB;QAC5B,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC;IAC9B,CAAC;CACF,CAAA;AAVY,gBAAgB;IAD5B,KAAK,EAAE;qCAOa,WAAW;GANnB,gBAAgB,CAU5B"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { AccessToken } from '../models/AccessToken.js';
|
|
2
|
+
import { AccessTokenEvent } from './AccessTokenEvent.js';
|
|
3
|
+
export declare class AccessTokenRoleGranted extends AccessTokenEvent {
|
|
4
|
+
Role: string;
|
|
5
|
+
constructor(token: AccessToken, Role: string);
|
|
6
|
+
}
|
|
7
|
+
//# sourceMappingURL=AccessTokenRoleGranted.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AccessTokenRoleGranted.d.ts","sourceRoot":"","sources":["../../../src/events/AccessTokenRoleGranted.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAEzD,qBACa,sBAAuB,SAAQ,gBAAgB;IACnB,IAAI,EAAE,MAAM;IAAnD,YAAY,KAAK,EAAE,WAAW,EAAS,IAAI,EAAE,MAAM,EAElD;CACF"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
+
};
|
|
10
|
+
import { Event } from '@spinajs/queue';
|
|
11
|
+
import { AccessToken } from '../models/AccessToken.js';
|
|
12
|
+
import { AccessTokenEvent } from './AccessTokenEvent.js';
|
|
13
|
+
let AccessTokenRoleGranted = class AccessTokenRoleGranted extends AccessTokenEvent {
|
|
14
|
+
constructor(token, Role) {
|
|
15
|
+
super(token);
|
|
16
|
+
this.Role = Role;
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
AccessTokenRoleGranted = __decorate([
|
|
20
|
+
Event(),
|
|
21
|
+
__metadata("design:paramtypes", [AccessToken, String])
|
|
22
|
+
], AccessTokenRoleGranted);
|
|
23
|
+
export { AccessTokenRoleGranted };
|
|
24
|
+
//# sourceMappingURL=AccessTokenRoleGranted.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AccessTokenRoleGranted.js","sourceRoot":"","sources":["../../../src/events/AccessTokenRoleGranted.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AACvC,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAGlD,IAAM,sBAAsB,GAA5B,MAAM,sBAAuB,SAAQ,gBAAgB;IAC1D,YAAY,KAAkB,EAAS,IAAY;QACjD,KAAK,CAAC,KAAK,CAAC,CAAC;oBADwB,IAAI;IAE3C,CAAC;CACF,CAAA;AAJY,sBAAsB;IADlC,KAAK,EAAE;qCAEa,WAAW;GADnB,sBAAsB,CAIlC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { AccessToken } from '../models/AccessToken.js';
|
|
2
|
+
import { AccessTokenEvent } from './AccessTokenEvent.js';
|
|
3
|
+
export declare class AccessTokenRoleRevoked extends AccessTokenEvent {
|
|
4
|
+
Role: string;
|
|
5
|
+
constructor(token: AccessToken, Role: string);
|
|
6
|
+
}
|
|
7
|
+
//# sourceMappingURL=AccessTokenRoleRevoked.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AccessTokenRoleRevoked.d.ts","sourceRoot":"","sources":["../../../src/events/AccessTokenRoleRevoked.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAEzD,qBACa,sBAAuB,SAAQ,gBAAgB;IACnB,IAAI,EAAE,MAAM;IAAnD,YAAY,KAAK,EAAE,WAAW,EAAS,IAAI,EAAE,MAAM,EAElD;CACF"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
+
};
|
|
10
|
+
import { Event } from '@spinajs/queue';
|
|
11
|
+
import { AccessToken } from '../models/AccessToken.js';
|
|
12
|
+
import { AccessTokenEvent } from './AccessTokenEvent.js';
|
|
13
|
+
let AccessTokenRoleRevoked = class AccessTokenRoleRevoked extends AccessTokenEvent {
|
|
14
|
+
constructor(token, Role) {
|
|
15
|
+
super(token);
|
|
16
|
+
this.Role = Role;
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
AccessTokenRoleRevoked = __decorate([
|
|
20
|
+
Event(),
|
|
21
|
+
__metadata("design:paramtypes", [AccessToken, String])
|
|
22
|
+
], AccessTokenRoleRevoked);
|
|
23
|
+
export { AccessTokenRoleRevoked };
|
|
24
|
+
//# sourceMappingURL=AccessTokenRoleRevoked.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AccessTokenRoleRevoked.js","sourceRoot":"","sources":["../../../src/events/AccessTokenRoleRevoked.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AACvC,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAGlD,IAAM,sBAAsB,GAA5B,MAAM,sBAAuB,SAAQ,gBAAgB;IAC1D,YAAY,KAAkB,EAAS,IAAY;QACjD,KAAK,CAAC,KAAK,CAAC,CAAC;oBADwB,IAAI;IAE3C,CAAC;CACF,CAAA;AAJY,sBAAsB;IADlC,KAAK,EAAE;qCAEa,WAAW;GADnB,sBAAsB,CAIlC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/events/index.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,yBAAyB,CAAC;AACxC,cAAc,yBAAyB,CAAC;AACxC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,6BAA6B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/events/index.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,yBAAyB,CAAC;AACxC,cAAc,yBAAyB,CAAC;AACxC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,6BAA6B,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { AccessTokenGenerationProvider, IGeneratedToken } from './interfaces.js';
|
|
2
|
+
/**
|
|
3
|
+
* Default token algorithm: `<prefix>` + N crypto-random bytes base64url encoded.
|
|
4
|
+
* The stable prefix makes leaked tokens findable by secret scanners.
|
|
5
|
+
*/
|
|
6
|
+
export declare class SecureRandomTokenProvider extends AccessTokenGenerationProvider {
|
|
7
|
+
protected Prefix: string;
|
|
8
|
+
protected Length: number;
|
|
9
|
+
generate(): Promise<IGeneratedToken>;
|
|
10
|
+
hash(plaintext: string): string;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=generator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generator.d.ts","sourceRoot":"","sources":["../../src/generator.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,6BAA6B,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAEjF;;;GAGG;AACH,qBACa,yBAA0B,SAAQ,6BAA6B;IAE1E,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC;IAGzB,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC;IAEZ,QAAQ,IAAI,OAAO,CAAC,eAAe,CAAC,CAGhD;IAEM,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAErC;CACF"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
+
};
|
|
10
|
+
import { randomBytes, createHash } from 'crypto';
|
|
11
|
+
import { Injectable } from '@spinajs/di';
|
|
12
|
+
import { Config } from '@spinajs/configuration';
|
|
13
|
+
import { AccessTokenGenerationProvider } from './interfaces.js';
|
|
14
|
+
/**
|
|
15
|
+
* Default token algorithm: `<prefix>` + N crypto-random bytes base64url encoded.
|
|
16
|
+
* The stable prefix makes leaked tokens findable by secret scanners.
|
|
17
|
+
*/
|
|
18
|
+
let SecureRandomTokenProvider = class SecureRandomTokenProvider extends AccessTokenGenerationProvider {
|
|
19
|
+
async generate() {
|
|
20
|
+
const plaintext = `${this.Prefix}${randomBytes(this.Length).toString('base64url')}`;
|
|
21
|
+
return { Plaintext: plaintext, Hash: this.hash(plaintext) };
|
|
22
|
+
}
|
|
23
|
+
hash(plaintext) {
|
|
24
|
+
return createHash('sha256').update(plaintext).digest('hex');
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
__decorate([
|
|
28
|
+
Config('rbac.token.prefix', { defaultValue: 'spt_' }),
|
|
29
|
+
__metadata("design:type", String)
|
|
30
|
+
], SecureRandomTokenProvider.prototype, "Prefix", void 0);
|
|
31
|
+
__decorate([
|
|
32
|
+
Config('rbac.token.length', { defaultValue: 32 }),
|
|
33
|
+
__metadata("design:type", Number)
|
|
34
|
+
], SecureRandomTokenProvider.prototype, "Length", void 0);
|
|
35
|
+
SecureRandomTokenProvider = __decorate([
|
|
36
|
+
Injectable(AccessTokenGenerationProvider)
|
|
37
|
+
], SecureRandomTokenProvider);
|
|
38
|
+
export { SecureRandomTokenProvider };
|
|
39
|
+
//# sourceMappingURL=generator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generator.js","sourceRoot":"","sources":["../../src/generator.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAEhD,OAAO,EAAE,6BAA6B,EAAmB,MAAM,iBAAiB,CAAC;AAEjF;;;GAGG;AAEI,IAAM,yBAAyB,GAA/B,MAAM,yBAA0B,SAAQ,6BAA6B;IAOnE,KAAK,CAAC,QAAQ;QACnB,MAAM,SAAS,GAAG,GAAG,IAAI,CAAC,MAAM,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;QACpF,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;IAC9D,CAAC;IAEM,IAAI,CAAC,SAAiB;QAC3B,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC9D,CAAC;CACF,CAAA;AAbW;IADT,MAAM,CAAC,mBAAmB,EAAE,EAAE,YAAY,EAAE,MAAM,EAAE,CAAC;;yDAC7B;AAGf;IADT,MAAM,CAAC,mBAAmB,EAAE,EAAE,YAAY,EAAE,EAAE,EAAE,CAAC;;yDACzB;AALd,yBAAyB;IADrC,UAAU,CAAC,6BAA6B,CAAC;GAC7B,yBAAyB,CAerC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import './generator.js';
|
|
2
|
+
import './middlewares.js';
|
|
3
|
+
export * from './interfaces.js';
|
|
4
|
+
export * from './models/AccessToken.js';
|
|
5
|
+
export * from './migrations/RbacHttpTokenInitial_2026_08_11_01_00_00.js';
|
|
6
|
+
export * from './generator.js';
|
|
7
|
+
export * from './events/index.js';
|
|
8
|
+
export * from './actions.js';
|
|
9
|
+
export * from './middlewares.js';
|
|
10
|
+
export * from './policies/TokenPolicy.js';
|
|
11
|
+
export * from './policies/NoTokenAuthPolicy.js';
|
|
12
|
+
export * from './policies/NoImpersonationPolicy.js';
|
|
13
|
+
export * from './controllers/AccessTokenController.js';
|
|
14
|
+
export * from './dto/create-token-dto.js';
|
|
15
|
+
export * from './cli/CreateToken.js';
|
|
16
|
+
export * from './cli/DeleteToken.js';
|
|
17
|
+
export * from './cli/GrantTokenRole.js';
|
|
18
|
+
export * from './cli/RevokeTokenRole.js';
|
|
19
|
+
export * from './cli/DeleteExpiredTokens.js';
|
|
20
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,gBAAgB,CAAC;AACxB,OAAO,kBAAkB,CAAC;AAE1B,cAAc,iBAAiB,CAAC;AAChC,cAAc,yBAAyB,CAAC;AACxC,cAAc,0DAA0D,CAAC;AACzE,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,cAAc,cAAc,CAAC;AAC7B,cAAc,kBAAkB,CAAC;AACjC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,iCAAiC,CAAC;AAChD,cAAc,qCAAqC,CAAC;AACpD,cAAc,wCAAwC,CAAC;AACvD,cAAc,2BAA2B,CAAC;AAC1C,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,yBAAyB,CAAC;AACxC,cAAc,0BAA0B,CAAC;AACzC,cAAc,8BAA8B,CAAC"}
|
package/lib/mjs/index.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// Side effect imports - these modules register Injectables ( the token
|
|
2
|
+
// generator and the token authorization middleware ) the moment they are
|
|
3
|
+
// loaded, so they must run even if a consumer imports nothing from them.
|
|
4
|
+
import './generator.js';
|
|
5
|
+
import './middlewares.js';
|
|
6
|
+
export * from './interfaces.js';
|
|
7
|
+
export * from './models/AccessToken.js';
|
|
8
|
+
export * from './migrations/RbacHttpTokenInitial_2026_08_11_01_00_00.js';
|
|
9
|
+
export * from './generator.js';
|
|
10
|
+
export * from './events/index.js';
|
|
11
|
+
export * from './actions.js';
|
|
12
|
+
export * from './middlewares.js';
|
|
13
|
+
export * from './policies/TokenPolicy.js';
|
|
14
|
+
export * from './policies/NoTokenAuthPolicy.js';
|
|
15
|
+
export * from './policies/NoImpersonationPolicy.js';
|
|
16
|
+
export * from './controllers/AccessTokenController.js';
|
|
17
|
+
export * from './dto/create-token-dto.js';
|
|
18
|
+
export * from './cli/CreateToken.js';
|
|
19
|
+
export * from './cli/DeleteToken.js';
|
|
20
|
+
export * from './cli/GrantTokenRole.js';
|
|
21
|
+
export * from './cli/RevokeTokenRole.js';
|
|
22
|
+
export * from './cli/DeleteExpiredTokens.js';
|
|
23
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,yEAAyE;AACzE,yEAAyE;AACzE,OAAO,gBAAgB,CAAC;AACxB,OAAO,kBAAkB,CAAC;AAE1B,cAAc,iBAAiB,CAAC;AAChC,cAAc,yBAAyB,CAAC;AACxC,cAAc,0DAA0D,CAAC;AACzE,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,cAAc,cAAc,CAAC;AAC7B,cAAc,kBAAkB,CAAC;AACjC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,iCAAiC,CAAC;AAChD,cAAc,qCAAqC,CAAC;AACpD,cAAc,wCAAwC,CAAC;AACvD,cAAc,2BAA2B,CAAC;AAC1C,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,yBAAyB,CAAC;AACxC,cAAc,0BAA0B,CAAC;AACzC,cAAc,8BAA8B,CAAC"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
export interface IGeneratedToken {
|
|
2
|
+
/**
|
|
3
|
+
* Full token as handed to the user, e.g. `spt_<base64url>`. Shown exactly once.
|
|
4
|
+
*/
|
|
5
|
+
Plaintext: string;
|
|
6
|
+
/**
|
|
7
|
+
* SHA-256 hex digest of the plaintext - the only thing that is persisted.
|
|
8
|
+
*/
|
|
9
|
+
Hash: string;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Token generation algorithm. Replaceable via config
|
|
13
|
+
* `rbac.token.generation.service` - same pattern as `rbac.password.service`.
|
|
14
|
+
*/
|
|
15
|
+
export declare abstract class AccessTokenGenerationProvider {
|
|
16
|
+
/**
|
|
17
|
+
* Generates a fresh token. Plaintext leaves the server once; only the hash is stored.
|
|
18
|
+
*/
|
|
19
|
+
abstract generate(): Promise<IGeneratedToken>;
|
|
20
|
+
/**
|
|
21
|
+
* Deterministic hash of a presented plaintext, used for DB lookup.
|
|
22
|
+
*/
|
|
23
|
+
abstract hash(plaintext: string): string;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Marker stored on request async storage when a request was authenticated
|
|
27
|
+
* with an access token instead of a session.
|
|
28
|
+
*/
|
|
29
|
+
export interface ITokenAuthInfo {
|
|
30
|
+
/**
|
|
31
|
+
* Uuid of the AccessToken row - safe to log; never the token itself.
|
|
32
|
+
*/
|
|
33
|
+
Uuid: string;
|
|
34
|
+
}
|
|
35
|
+
declare module '@spinajs/rbac' {
|
|
36
|
+
interface IRbacAsyncStorage {
|
|
37
|
+
/**
|
|
38
|
+
* Set by TokenAuthMiddleware when the request carries a valid access token.
|
|
39
|
+
*/
|
|
40
|
+
TokenAuth?: ITokenAuthInfo;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* The http request-local storage is a SEPARATE interface from rbac's
|
|
45
|
+
* `IRbacAsyncStorage` ( `@spinajs/rbac-http` augments it the same way with
|
|
46
|
+
* User / Session / ActiveRole ), so the marker has to be declared on both -
|
|
47
|
+
* the one above for rbac's execution context, this one for `req.storage`.
|
|
48
|
+
*/
|
|
49
|
+
declare module '@spinajs/http' {
|
|
50
|
+
interface IActionLocalStoregeContext {
|
|
51
|
+
/**
|
|
52
|
+
* Set by TokenAuthMiddleware when the request carries a valid access token.
|
|
53
|
+
*/
|
|
54
|
+
TokenAuth?: ITokenAuthInfo;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=interfaces.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interfaces.d.ts","sourceRoot":"","sources":["../../src/interfaces.ts"],"names":[],"mappings":"AAUA,MAAM,WAAW,eAAe;IAC9B;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;GAGG;AACH,8BAAsB,6BAA6B;IACjD;;OAEG;IACH,SAAgB,QAAQ,IAAI,OAAO,CAAC,eAAe,CAAC,CAAC;IAErD;;OAEG;IACH,SAAgB,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAAC;CACjD;AAED;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;CACd;AAED,OAAO,QAAQ,eAAe,CAAC;IAC7B,UAAU,iBAAiB;QACzB;;WAEG;QACH,SAAS,CAAC,EAAE,cAAc,CAAC;KAC5B;CACF;AAED;;;;;GAKG;AACH,OAAO,QAAQ,eAAe,CAAC;IAC7B,UAAU,0BAA0B;QAClC;;WAEG;QACH,SAAS,CAAC,EAAE,cAAc,CAAC;KAC5B;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interfaces.js","sourceRoot":"","sources":["../../src/interfaces.ts"],"names":[],"mappings":"AAsBA;;;GAGG;AACH,MAAM,OAAgB,6BAA6B;CAUlD"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import * as express from 'express';
|
|
2
|
+
import { Log } from '@spinajs/log';
|
|
3
|
+
import { Request as sRequest, ServerMiddleware } from '@spinajs/http';
|
|
4
|
+
import { User } from '@spinajs/rbac';
|
|
5
|
+
import './interfaces.js';
|
|
6
|
+
/**
|
|
7
|
+
* Authenticates requests carrying an access token in `Authorization: Bearer`
|
|
8
|
+
* or the configured fallback header. Runs AFTER RbacMiddleware ( Order 0 )
|
|
9
|
+
* so a session, when present, always wins - a request cannot mix both.
|
|
10
|
+
*
|
|
11
|
+
* On success `req.storage.User` carries the owner with Role narrowed to the
|
|
12
|
+
* token's effective roles, so every downstream permission check ( RbacPolicy
|
|
13
|
+
* helpers, orm rbac query middleware, ownership ) works unchanged.
|
|
14
|
+
*
|
|
15
|
+
* `req.storage.ActiveRole` is deliberately CLEARED, and that is load bearing.
|
|
16
|
+
* Both consumers of the field resolve the roles to authorize with as
|
|
17
|
+
* `ActiveRole ? [ActiveRole] : User.Role` ( `checkRoutePermission` in
|
|
18
|
+
* `rbac-http/src/policies/RbacPolicy.ts`, and the orm rbac query middleware in
|
|
19
|
+
* `rbac/src/middleware.ts` ), so whatever single role sits there collapses the
|
|
20
|
+
* request down to that one role.
|
|
21
|
+
*
|
|
22
|
+
* A session can afford that collapse because it can switch its active role at
|
|
23
|
+
* runtime ( `POST /auth/active-role` ), so the narrowing is both deliberate and
|
|
24
|
+
* reversible. A token carries no session and has no way to switch, so picking
|
|
25
|
+
* one of its roles - the first, arbitrarily - would permanently authorize the
|
|
26
|
+
* token with a strict subset of what it was issued for: a token holding
|
|
27
|
+
* `[ 'user', 'admin' ]` would never satisfy an admin-only grant.
|
|
28
|
+
*
|
|
29
|
+
* Leaving it undefined makes both consumers fall back to `User.Role`, which the
|
|
30
|
+
* narrowing above has ALREADY reduced to exactly the effective role set - the
|
|
31
|
+
* intersection of what the token carries and its owner still holds. That is the
|
|
32
|
+
* correct authorization scope for a token, and nothing wider.
|
|
33
|
+
*
|
|
34
|
+
* The field has to be assigned `undefined` rather than skipped: `RbacMiddleware`
|
|
35
|
+
* runs first and, on a session-less request, stamps the GUEST account's first
|
|
36
|
+
* role into it, which would otherwise survive into the token's own request.
|
|
37
|
+
*
|
|
38
|
+
* Never throws: an invalid token leaves the request as guest and lets the
|
|
39
|
+
* route's policy produce the rejection.
|
|
40
|
+
*/
|
|
41
|
+
export declare class TokenAuthMiddleware extends ServerMiddleware {
|
|
42
|
+
protected Log: Log;
|
|
43
|
+
protected HeaderName: string;
|
|
44
|
+
protected LastUsedUpdateInterval: number;
|
|
45
|
+
constructor();
|
|
46
|
+
before(): (req: sRequest, res: express.Response, next: express.NextFunction) => void;
|
|
47
|
+
after(): null;
|
|
48
|
+
/**
|
|
49
|
+
* Narrows the loaded owner to the token's effective roles WITHOUT letting the
|
|
50
|
+
* narrowing reach the database.
|
|
51
|
+
*
|
|
52
|
+
* `Role` is a real `@Set()` column, and this very instance is what controllers
|
|
53
|
+
* receive through the `@User()` route argument. `update()` writes whatever
|
|
54
|
+
* differs from the model's snapshot, so a controller doing an unrelated edit
|
|
55
|
+
* ( "change my login" ) and calling `.update()` would silently persist the
|
|
56
|
+
* narrowed list - permanently stripping every role the token did not carry.
|
|
57
|
+
*
|
|
58
|
+
* Re-taking the snapshot right after the narrowing makes it invisible to that
|
|
59
|
+
* diff: the instance then behaves exactly like a freshly loaded row whose roles
|
|
60
|
+
* happen to be the effective ones, and a later `.update()` writes only what the
|
|
61
|
+
* controller itself changed. The full instance is kept rather than copied so
|
|
62
|
+
* that `Id`, `Password`, the `Metadata` relation and the prototype accessors
|
|
63
|
+
* ( `IsBanned`, `can()` ) all survive - `dehydrate()` drops the `@Hidden()`
|
|
64
|
+
* columns, so a dehydrate/rehydrate copy would arrive without `Id`.
|
|
65
|
+
*
|
|
66
|
+
* `takeSnapshot()` also discards the relation baselines, which the orm's
|
|
67
|
+
* subject builder needs to tell an already-persisted related row from a new
|
|
68
|
+
* one, so they are recorded again immediately.
|
|
69
|
+
*/
|
|
70
|
+
protected narrowRoles(user: User, roles: string[]): User;
|
|
71
|
+
/**
|
|
72
|
+
* Bearer scheme first, configured fallback header second.
|
|
73
|
+
*/
|
|
74
|
+
protected extract(req: sRequest): string | null;
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=middlewares.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"middlewares.d.ts","sourceRoot":"","sources":["../../src/middlewares.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,SAAS,CAAC;AAGnC,OAAO,EAAE,GAAG,EAAU,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEtE,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAGrC,OAAO,iBAAiB,CAAC;AAQzB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,qBACa,mBAAoB,SAAQ,gBAAgB;IAEvD,SAAS,CAAC,GAAG,EAAE,GAAG,CAAC;IAGnB,SAAS,CAAC,UAAU,EAAE,MAAM,CAAC;IAG7B,SAAS,CAAC,sBAAsB,EAAE,MAAM,CAAC;IAEzC,cAIC;IAEM,MAAM,IAAI,CAAC,GAAG,EAAE,QAAQ,EAAE,GAAG,EAAE,OAAO,CAAC,QAAQ,EAAE,IAAI,EAAE,OAAO,CAAC,YAAY,KAAK,IAAI,CAkD1F;IAEM,KAAK,IAAI,IAAI,CAEnB;IAED;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,SAAS,CAAC,WAAW,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CASvD;IAED;;OAEG;IACH,SAAS,CAAC,OAAO,CAAC,GAAG,EAAE,QAAQ,GAAG,MAAM,GAAG,IAAI,CAgB9C;CACF"}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
+
};
|
|
10
|
+
import { Injectable } from '@spinajs/di';
|
|
11
|
+
import { Config } from '@spinajs/configuration';
|
|
12
|
+
import { Log, Logger } from '@spinajs/log';
|
|
13
|
+
import { ServerMiddleware } from '@spinajs/http';
|
|
14
|
+
import { ErrorCode } from '@spinajs/exceptions';
|
|
15
|
+
import { validateToken, touchToken } from './actions.js';
|
|
16
|
+
import './interfaces.js';
|
|
17
|
+
/**
|
|
18
|
+
* `Authorization: Bearer <token>`. RFC 7235 makes the scheme name
|
|
19
|
+
* case-insensitive, and clients do send `bearer`.
|
|
20
|
+
*/
|
|
21
|
+
const BEARER_SCHEME = /^bearer\s+/i;
|
|
22
|
+
/**
|
|
23
|
+
* Authenticates requests carrying an access token in `Authorization: Bearer`
|
|
24
|
+
* or the configured fallback header. Runs AFTER RbacMiddleware ( Order 0 )
|
|
25
|
+
* so a session, when present, always wins - a request cannot mix both.
|
|
26
|
+
*
|
|
27
|
+
* On success `req.storage.User` carries the owner with Role narrowed to the
|
|
28
|
+
* token's effective roles, so every downstream permission check ( RbacPolicy
|
|
29
|
+
* helpers, orm rbac query middleware, ownership ) works unchanged.
|
|
30
|
+
*
|
|
31
|
+
* `req.storage.ActiveRole` is deliberately CLEARED, and that is load bearing.
|
|
32
|
+
* Both consumers of the field resolve the roles to authorize with as
|
|
33
|
+
* `ActiveRole ? [ActiveRole] : User.Role` ( `checkRoutePermission` in
|
|
34
|
+
* `rbac-http/src/policies/RbacPolicy.ts`, and the orm rbac query middleware in
|
|
35
|
+
* `rbac/src/middleware.ts` ), so whatever single role sits there collapses the
|
|
36
|
+
* request down to that one role.
|
|
37
|
+
*
|
|
38
|
+
* A session can afford that collapse because it can switch its active role at
|
|
39
|
+
* runtime ( `POST /auth/active-role` ), so the narrowing is both deliberate and
|
|
40
|
+
* reversible. A token carries no session and has no way to switch, so picking
|
|
41
|
+
* one of its roles - the first, arbitrarily - would permanently authorize the
|
|
42
|
+
* token with a strict subset of what it was issued for: a token holding
|
|
43
|
+
* `[ 'user', 'admin' ]` would never satisfy an admin-only grant.
|
|
44
|
+
*
|
|
45
|
+
* Leaving it undefined makes both consumers fall back to `User.Role`, which the
|
|
46
|
+
* narrowing above has ALREADY reduced to exactly the effective role set - the
|
|
47
|
+
* intersection of what the token carries and its owner still holds. That is the
|
|
48
|
+
* correct authorization scope for a token, and nothing wider.
|
|
49
|
+
*
|
|
50
|
+
* The field has to be assigned `undefined` rather than skipped: `RbacMiddleware`
|
|
51
|
+
* runs first and, on a session-less request, stamps the GUEST account's first
|
|
52
|
+
* role into it, which would otherwise survive into the token's own request.
|
|
53
|
+
*
|
|
54
|
+
* Never throws: an invalid token leaves the request as guest and lets the
|
|
55
|
+
* route's policy produce the rejection.
|
|
56
|
+
*/
|
|
57
|
+
let TokenAuthMiddleware = class TokenAuthMiddleware extends ServerMiddleware {
|
|
58
|
+
constructor() {
|
|
59
|
+
super();
|
|
60
|
+
// After RbacMiddleware ( Order 0 ): session auth takes precedence.
|
|
61
|
+
this.Order = 1;
|
|
62
|
+
}
|
|
63
|
+
before() {
|
|
64
|
+
return async (req, res, next) => {
|
|
65
|
+
try {
|
|
66
|
+
// Session user already authenticated - tokens do not apply.
|
|
67
|
+
if (req.storage?.Session) {
|
|
68
|
+
return next();
|
|
69
|
+
}
|
|
70
|
+
const plaintext = this.extract(req);
|
|
71
|
+
if (!plaintext) {
|
|
72
|
+
return next();
|
|
73
|
+
}
|
|
74
|
+
let result;
|
|
75
|
+
try {
|
|
76
|
+
result = await validateToken(plaintext);
|
|
77
|
+
}
|
|
78
|
+
catch (err) {
|
|
79
|
+
// Deliberately vague towards the client; specific in the log. The uuid
|
|
80
|
+
// is what makes a rejection actionable ( "which key broke" ) and is
|
|
81
|
+
// safe to write down - `validateToken` attaches it as `data.token` on
|
|
82
|
+
// every failure past the lookup. The presented plaintext is NEVER
|
|
83
|
+
// logged, here or anywhere else.
|
|
84
|
+
const data = err instanceof ErrorCode ? err.data : undefined;
|
|
85
|
+
this.Log.warn(`Access token rejected: ${err.message}`, { Ip: req.ip, Token: data?.token });
|
|
86
|
+
return next();
|
|
87
|
+
}
|
|
88
|
+
req.storage.User = this.narrowRoles(result.User, result.EffectiveRoles);
|
|
89
|
+
req.storage.TokenAuth = { Uuid: result.Token.Uuid };
|
|
90
|
+
// CLEARED, not merely left alone - see the class docblock for why a
|
|
91
|
+
// token must carry no active role at all. `RbacMiddleware` has already
|
|
92
|
+
// run by now and, finding no session, wrote the GUEST user's first role
|
|
93
|
+
// here ( `rbac-http/src/middlewares.ts`, the `else` branch ). Leaving
|
|
94
|
+
// that in place would authorize every token request as `guest`.
|
|
95
|
+
req.storage.ActiveRole = undefined;
|
|
96
|
+
// Token-authenticated responses must never land in a shared cache.
|
|
97
|
+
res.setHeader('Cache-Control', 'no-store');
|
|
98
|
+
// Fire-and-forget throttled usage stamp. A non-Error rejection has no
|
|
99
|
+
// `.message`; reading one off it would throw inside the handler and
|
|
100
|
+
// surface as an unhandled rejection.
|
|
101
|
+
void touchToken(result.Token, this.LastUsedUpdateInterval).catch((err) => this.Log.warn(`Failed to update token LastUsedAt: ${err instanceof Error ? err.message : String(err)}`, { Token: result.Token.Uuid }));
|
|
102
|
+
next();
|
|
103
|
+
}
|
|
104
|
+
catch (err) {
|
|
105
|
+
next(err);
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
after() {
|
|
110
|
+
return null;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Narrows the loaded owner to the token's effective roles WITHOUT letting the
|
|
114
|
+
* narrowing reach the database.
|
|
115
|
+
*
|
|
116
|
+
* `Role` is a real `@Set()` column, and this very instance is what controllers
|
|
117
|
+
* receive through the `@User()` route argument. `update()` writes whatever
|
|
118
|
+
* differs from the model's snapshot, so a controller doing an unrelated edit
|
|
119
|
+
* ( "change my login" ) and calling `.update()` would silently persist the
|
|
120
|
+
* narrowed list - permanently stripping every role the token did not carry.
|
|
121
|
+
*
|
|
122
|
+
* Re-taking the snapshot right after the narrowing makes it invisible to that
|
|
123
|
+
* diff: the instance then behaves exactly like a freshly loaded row whose roles
|
|
124
|
+
* happen to be the effective ones, and a later `.update()` writes only what the
|
|
125
|
+
* controller itself changed. The full instance is kept rather than copied so
|
|
126
|
+
* that `Id`, `Password`, the `Metadata` relation and the prototype accessors
|
|
127
|
+
* ( `IsBanned`, `can()` ) all survive - `dehydrate()` drops the `@Hidden()`
|
|
128
|
+
* columns, so a dehydrate/rehydrate copy would arrive without `Id`.
|
|
129
|
+
*
|
|
130
|
+
* `takeSnapshot()` also discards the relation baselines, which the orm's
|
|
131
|
+
* subject builder needs to tell an already-persisted related row from a new
|
|
132
|
+
* one, so they are recorded again immediately.
|
|
133
|
+
*/
|
|
134
|
+
narrowRoles(user, roles) {
|
|
135
|
+
user.Role = roles;
|
|
136
|
+
user.takeSnapshot();
|
|
137
|
+
for (const [name] of user.ModelDescriptor?.Relations ?? []) {
|
|
138
|
+
user.snapshotRelation(name);
|
|
139
|
+
}
|
|
140
|
+
return user;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Bearer scheme first, configured fallback header second.
|
|
144
|
+
*/
|
|
145
|
+
extract(req) {
|
|
146
|
+
// A header sent twice arrives as an array. Anything that is not a single
|
|
147
|
+
// string is malformed and has to read as "no token presented" - calling
|
|
148
|
+
// `.startsWith` / `.trim` on it would throw, and this middleware is
|
|
149
|
+
// contractually not allowed to turn a bad request into a 500.
|
|
150
|
+
const header = (name) => {
|
|
151
|
+
const value = req.headers?.[name];
|
|
152
|
+
return typeof value === 'string' ? value : null;
|
|
153
|
+
};
|
|
154
|
+
const auth = header('authorization');
|
|
155
|
+
if (auth && BEARER_SCHEME.test(auth)) {
|
|
156
|
+
return auth.replace(BEARER_SCHEME, '').trim() || null;
|
|
157
|
+
}
|
|
158
|
+
return header(this.HeaderName.toLowerCase())?.trim() || null;
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
__decorate([
|
|
162
|
+
Logger('rbac-http-token'),
|
|
163
|
+
__metadata("design:type", Log)
|
|
164
|
+
], TokenAuthMiddleware.prototype, "Log", void 0);
|
|
165
|
+
__decorate([
|
|
166
|
+
Config('rbac.token.headerName', { defaultValue: 'x-api-key' }),
|
|
167
|
+
__metadata("design:type", String)
|
|
168
|
+
], TokenAuthMiddleware.prototype, "HeaderName", void 0);
|
|
169
|
+
__decorate([
|
|
170
|
+
Config('rbac.token.lastUsedUpdateInterval', { defaultValue: 60 }),
|
|
171
|
+
__metadata("design:type", Number)
|
|
172
|
+
], TokenAuthMiddleware.prototype, "LastUsedUpdateInterval", void 0);
|
|
173
|
+
TokenAuthMiddleware = __decorate([
|
|
174
|
+
Injectable(ServerMiddleware),
|
|
175
|
+
__metadata("design:paramtypes", [])
|
|
176
|
+
], TokenAuthMiddleware);
|
|
177
|
+
export { TokenAuthMiddleware };
|
|
178
|
+
//# sourceMappingURL=middlewares.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"middlewares.js","sourceRoot":"","sources":["../../src/middlewares.ts"],"names":[],"mappings":";;;;;;;;;AACA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAuB,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACtE,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAGhD,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AACzD,OAAO,iBAAiB,CAAC;AAEzB;;;GAGG;AACH,MAAM,aAAa,GAAG,aAAa,CAAC;AAEpC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAEI,IAAM,mBAAmB,GAAzB,MAAM,mBAAoB,SAAQ,gBAAgB;IAUvD;QACE,KAAK,EAAE,CAAC;QACR,mEAAmE;QACnE,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC;IACjB,CAAC;IAEM,MAAM;QACX,OAAO,KAAK,EAAE,GAAa,EAAE,GAAqB,EAAE,IAA0B,EAAE,EAAE;YAChF,IAAI,CAAC;gBACH,4DAA4D;gBAC5D,IAAI,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC;oBACzB,OAAO,IAAI,EAAE,CAAC;gBAChB,CAAC;gBAED,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;gBACpC,IAAI,CAAC,SAAS,EAAE,CAAC;oBACf,OAAO,IAAI,EAAE,CAAC;gBAChB,CAAC;gBAED,IAAI,MAAM,CAAC;gBACX,IAAI,CAAC;oBACH,MAAM,GAAG,MAAM,aAAa,CAAC,SAAS,CAAC,CAAC;gBAC1C,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,uEAAuE;oBACvE,oEAAoE;oBACpE,sEAAsE;oBACtE,kEAAkE;oBAClE,iCAAiC;oBACjC,MAAM,IAAI,GAAG,GAAG,YAAY,SAAS,CAAC,CAAC,CAAE,GAAG,CAAC,IAAuC,CAAC,CAAC,CAAC,SAAS,CAAC;oBACjG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,0BAA2B,GAAa,CAAC,OAAO,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;oBACtG,OAAO,IAAI,EAAE,CAAC;gBAChB,CAAC;gBAED,GAAG,CAAC,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,cAAc,CAAC,CAAC;gBACxE,GAAG,CAAC,OAAO,CAAC,SAAS,GAAG,EAAE,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;gBAEpD,oEAAoE;gBACpE,uEAAuE;gBACvE,wEAAwE;gBACxE,sEAAsE;gBACtE,gEAAgE;gBAChE,GAAG,CAAC,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC;gBAEnC,mEAAmE;gBACnE,GAAG,CAAC,SAAS,CAAC,eAAe,EAAE,UAAU,CAAC,CAAC;gBAE3C,sEAAsE;gBACtE,oEAAoE;gBACpE,qCAAqC;gBACrC,KAAK,UAAU,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,sBAAsB,CAAC,CAAC,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,sCAAsC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;gBAE1N,IAAI,EAAE,CAAC;YACT,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,IAAI,CAAC,GAAG,CAAC,CAAC;YACZ,CAAC;QACH,CAAC,CAAC;IACJ,CAAC;IAEM,KAAK;QACV,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;;;;;;;;;;;;;;;;;OAqBG;IACO,WAAW,CAAC,IAAU,EAAE,KAAe;QAC/C,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC;QAClB,IAAI,CAAC,YAAY,EAAE,CAAC;QAEpB,KAAK,MAAM,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,eAAe,EAAE,SAAS,IAAI,EAAE,EAAE,CAAC;YAC3D,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC;QAC9B,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;OAEG;IACO,OAAO,CAAC,GAAa;QAC7B,yEAAyE;QACzE,wEAAwE;QACxE,oEAAoE;QACpE,8DAA8D;QAC9D,MAAM,MAAM,GAAG,CAAC,IAAY,EAAiB,EAAE;YAC7C,MAAM,KAAK,GAAG,GAAG,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,CAAC;YAClC,OAAO,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;QAClD,CAAC,CAAC;QAEF,MAAM,IAAI,GAAG,MAAM,CAAC,eAAe,CAAC,CAAC;QACrC,IAAI,IAAI,IAAI,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YACrC,OAAO,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,IAAI,CAAC;QACxD,CAAC;QAED,OAAO,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,WAAW,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,IAAI,CAAC;IAC/D,CAAC;CACF,CAAA;AA3HW;IADT,MAAM,CAAC,iBAAiB,CAAC;8BACX,GAAG;gDAAC;AAGT;IADT,MAAM,CAAC,uBAAuB,EAAE,EAAE,YAAY,EAAE,WAAW,EAAE,CAAC;;uDAClC;AAGnB;IADT,MAAM,CAAC,mCAAmC,EAAE,EAAE,YAAY,EAAE,EAAE,EAAE,CAAC;;mEACzB;AAR9B,mBAAmB;IAD/B,UAAU,CAAC,gBAAgB,CAAC;;GAChB,mBAAmB,CA6H/B"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { OrmMigration, OrmDriver } from '@spinajs/orm';
|
|
2
|
+
export declare class RbacHttpTokenInitial_2026_08_11_01_00_00 extends OrmMigration {
|
|
3
|
+
up(connection: OrmDriver): Promise<void>;
|
|
4
|
+
down(_connection: OrmDriver): Promise<void>;
|
|
5
|
+
}
|
|
6
|
+
//# sourceMappingURL=RbacHttpTokenInitial_2026_08_11_01_00_00.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RbacHttpTokenInitial_2026_08_11_01_00_00.d.ts","sourceRoot":"","sources":["../../../src/migrations/RbacHttpTokenInitial_2026_08_11_01_00_00.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,SAAS,EAAa,MAAM,cAAc,CAAC;AAElE,qBACa,wCAAyC,SAAQ,YAAY;IAC3D,EAAE,CAAC,UAAU,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAkBpD;IAGY,IAAI,CAAC,WAAW,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAG;CAC5D"}
|