@spinajs/rbac 1.2.108

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 ADDED
@@ -0,0 +1,11 @@
1
+ # `rbac`
2
+
3
+ > TODO: description
4
+
5
+ ## Usage
6
+
7
+ ```
8
+ const rbac = require('rbac');
9
+
10
+ // TODO: DEMONSTRATE API
11
+ ```
package/lib/auth.d.ts ADDED
@@ -0,0 +1,8 @@
1
+ import { AuthProvider } from './interfaces';
2
+ import { User } from './models/User';
3
+ import { IContainer } from '@spinajs/di';
4
+ export declare class SimpleDbAuthProvider implements AuthProvider<User> {
5
+ protected Container: IContainer;
6
+ exists(user: User | string): Promise<boolean>;
7
+ authenticate(email: string, password: string): Promise<User>;
8
+ }
package/lib/auth.js ADDED
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ 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;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.SimpleDbAuthProvider = void 0;
13
+ const interfaces_1 = require("./interfaces");
14
+ const User_1 = require("./models/User");
15
+ const di_1 = require("@spinajs/di");
16
+ class SimpleDbAuthProvider {
17
+ async exists(user) {
18
+ const result = await User_1.User.where('Email', user instanceof User_1.User ? user.Email : user).first();
19
+ if (result) {
20
+ return true;
21
+ }
22
+ return false;
23
+ }
24
+ async authenticate(email, password) {
25
+ const pwd = this.Container.resolve(interfaces_1.PasswordProvider);
26
+ const result = await User_1.User.where({
27
+ Email: email,
28
+ })
29
+ .andWhere('DeletedAt', null)
30
+ .populate('Metadata')
31
+ .first();
32
+ if (!result) {
33
+ return null;
34
+ }
35
+ const valid = await pwd.verify(result.Password, password);
36
+ if (valid) {
37
+ return result;
38
+ }
39
+ return null;
40
+ }
41
+ }
42
+ __decorate([
43
+ (0, di_1.Autoinject)(di_1.Container),
44
+ __metadata("design:type", Object)
45
+ ], SimpleDbAuthProvider.prototype, "Container", void 0);
46
+ exports.SimpleDbAuthProvider = SimpleDbAuthProvider;
47
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,6CAA8D;AAC9D,wCAAqC;AACrC,oCAAgE;AAEhE,MAAa,oBAAoB;IAIxB,KAAK,CAAC,MAAM,CAAC,IAAmB;QACrC,MAAM,MAAM,GAAG,MAAM,WAAI,CAAC,KAAK,CAAC,OAAO,EAAE,IAAI,YAAY,WAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC;QAC3F,IAAI,MAAM,EAAE;YACV,OAAO,IAAI,CAAC;SACb;QAED,OAAO,KAAK,CAAC;IACf,CAAC;IAEM,KAAK,CAAC,YAAY,CAAC,KAAa,EAAE,QAAgB;QACvD,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,6BAAgB,CAAC,CAAC;QACrD,MAAM,MAAM,GAAG,MAAM,WAAI,CAAC,KAAK,CAAC;YAC9B,KAAK,EAAE,KAAK;SACb,CAAC;aACC,QAAQ,CAAC,WAAW,EAAE,IAAI,CAAC;aAC3B,QAAQ,CAAC,UAAU,CAAC;aACpB,KAAK,EAAE,CAAC;QAEX,IAAI,CAAC,MAAM,EAAE;YACX,OAAO,IAAI,CAAC;SACb;QAED,MAAM,KAAK,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAC1D,IAAI,KAAK,EAAE;YACT,OAAO,MAAM,CAAC;SACf;QAED,OAAO,IAAI,CAAC;IACd,CAAC;CACF;AA/BC;IADC,IAAA,eAAU,EAAC,cAAS,CAAC;;uDACU;AAFlC,oDAiCC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const path_1 = require("path");
4
+ function dir(path) {
5
+ return (0, path_1.resolve)((0, path_1.normalize)((0, path_1.join)(__dirname, path)));
6
+ }
7
+ module.exports = {
8
+ system: {
9
+ dirs: {
10
+ migrations: [dir('./../migrations')],
11
+ models: [dir('./../models')],
12
+ },
13
+ },
14
+ rbac: {
15
+ // default roles to manage users & guest account
16
+ roles: [
17
+ {
18
+ Name: 'Admin',
19
+ Description: 'Administrator',
20
+ },
21
+ {
22
+ Name: 'User',
23
+ Description: 'Simple account without any privlidge',
24
+ },
25
+ ],
26
+ defaultRole: 'guest',
27
+ session: {
28
+ // 2h session expiration time
29
+ expiration: 120,
30
+ },
31
+ },
32
+ };
33
+ //# sourceMappingURL=rbac.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rbac.js","sourceRoot":"","sources":["../../src/config/rbac.ts"],"names":[],"mappings":";;AAAA,+BAAgD;AAEhD,SAAS,GAAG,CAAC,IAAY;IACvB,OAAO,IAAA,cAAO,EAAC,IAAA,gBAAS,EAAC,IAAA,WAAI,EAAC,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;AACnD,CAAC;AAED,MAAM,CAAC,OAAO,GAAG;IACf,MAAM,EAAE;QACN,IAAI,EAAE;YACJ,UAAU,EAAE,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;YACpC,MAAM,EAAE,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;SAC7B;KACF;IACD,IAAI,EAAE;QACJ,gDAAgD;QAChD,KAAK,EAAE;YACL;gBACE,IAAI,EAAE,OAAO;gBACb,WAAW,EAAE,eAAe;aAC7B;YACD;gBACE,IAAI,EAAE,MAAM;gBACZ,WAAW,EAAE,sCAAsC;aACpD;SACF;QACD,WAAW,EAAE,OAAO;QACpB,OAAO,EAAE;YACP,8BAA8B;YAC9B,UAAU,EAAE,GAAG;SAChB;KACF;CACF,CAAC"}
package/lib/index.d.ts ADDED
@@ -0,0 +1,11 @@
1
+ import { Bootstrapper } from '@spinajs/di';
2
+ export * from './interfaces';
3
+ export * from './auth';
4
+ export * from './password';
5
+ export * from './session';
6
+ export * from './models/User';
7
+ export * from './models/UserMetadata';
8
+ export { AccessControl } from 'accesscontrol';
9
+ export declare class RbacBootstrapper extends Bootstrapper {
10
+ bootstrap(): void;
11
+ }
package/lib/index.js ADDED
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
14
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
15
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
16
+ 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;
17
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
18
+ };
19
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
20
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
21
+ };
22
+ Object.defineProperty(exports, "__esModule", { value: true });
23
+ exports.RbacBootstrapper = exports.AccessControl = void 0;
24
+ const di_1 = require("@spinajs/di");
25
+ const auth_1 = require("./auth");
26
+ const interfaces_1 = require("./interfaces");
27
+ const password_1 = require("./password");
28
+ const session_1 = require("./session");
29
+ const accesscontrol_1 = require("accesscontrol");
30
+ __exportStar(require("./interfaces"), exports);
31
+ __exportStar(require("./auth"), exports);
32
+ __exportStar(require("./password"), exports);
33
+ __exportStar(require("./session"), exports);
34
+ __exportStar(require("./models/User"), exports);
35
+ __exportStar(require("./models/UserMetadata"), exports);
36
+ var accesscontrol_2 = require("accesscontrol");
37
+ Object.defineProperty(exports, "AccessControl", { enumerable: true, get: function () { return accesscontrol_2.AccessControl; } });
38
+ let RbacBootstrapper = class RbacBootstrapper extends di_1.Bootstrapper {
39
+ bootstrap() {
40
+ di_1.DI.register(password_1.BasicPasswordProvider).as(interfaces_1.PasswordProvider);
41
+ di_1.DI.register(auth_1.SimpleDbAuthProvider).as(interfaces_1.AuthProvider);
42
+ di_1.DI.register(session_1.MemorySessionProvider).as(interfaces_1.SessionProvider);
43
+ const ac = new accesscontrol_1.AccessControl();
44
+ di_1.DI.register(ac).as('AccessControl');
45
+ ac.grant('admin.users').createAny('users').updateAny('users').deleteAny('users').readAny('users');
46
+ ac.grant('user').updateOwn('users', ['Email', 'Login', 'Password', 'NiceName']);
47
+ ac.grant('admin').extend('admin.users');
48
+ }
49
+ };
50
+ RbacBootstrapper = __decorate([
51
+ (0, di_1.Injectable)(di_1.Bootstrapper)
52
+ ], RbacBootstrapper);
53
+ exports.RbacBootstrapper = RbacBootstrapper;
54
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAAA,oCAA2D;AAC3D,iCAA8C;AAC9C,6CAA+E;AAC/E,yCAAmD;AACnD,uCAAkD;AAClD,iDAA8C;AAE9C,+CAA6B;AAC7B,yCAAuB;AACvB,6CAA2B;AAC3B,4CAA0B;AAC1B,gDAA8B;AAC9B,wDAAsC;AACtC,+CAA8C;AAArC,8GAAA,aAAa,OAAA;AAGtB,IAAa,gBAAgB,GAA7B,MAAa,gBAAiB,SAAQ,iBAAY;IACzC,SAAS;QACd,OAAE,CAAC,QAAQ,CAAC,gCAAqB,CAAC,CAAC,EAAE,CAAC,6BAAgB,CAAC,CAAC;QACxD,OAAE,CAAC,QAAQ,CAAC,2BAAoB,CAAC,CAAC,EAAE,CAAC,yBAAY,CAAC,CAAC;QACnD,OAAE,CAAC,QAAQ,CAAC,+BAAqB,CAAC,CAAC,EAAE,CAAC,4BAAe,CAAC,CAAC;QAEvD,MAAM,EAAE,GAAG,IAAI,6BAAa,EAAE,CAAC;QAC/B,OAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,eAAe,CAAC,CAAC;QAEpC,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAClG,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC;QAChF,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;IAC1C,CAAC;CACF,CAAA;AAbY,gBAAgB;IAD5B,IAAA,eAAU,EAAC,iBAAY,CAAC;GACZ,gBAAgB,CAa5B;AAbY,4CAAgB"}
@@ -0,0 +1,88 @@
1
+ import { User } from './models/User';
2
+ import { AsyncModule } from '@spinajs/di';
3
+ import { DateTime } from 'luxon';
4
+ export interface UserSessionData {
5
+ /**
6
+ * Session identifier
7
+ */
8
+ SessionId?: string;
9
+ /**
10
+ * Expiration date. After that date session is invalid
11
+ */
12
+ Expiration: DateTime;
13
+ /**
14
+ * Session creation date. After that date session is invalid
15
+ */
16
+ Creation?: DateTime;
17
+ /**
18
+ * Data holds by session
19
+ */
20
+ Data: any;
21
+ }
22
+ export interface UserSession extends UserSessionData {
23
+ /**
24
+ *
25
+ * Extends session lifetime
26
+ *
27
+ * @param minutes - how mutch to extend
28
+ */
29
+ extend(minutes: number): void;
30
+ }
31
+ /**
32
+ * Service used for generating random password & for hash raw string
33
+ */
34
+ export declare abstract class PasswordProvider {
35
+ /**
36
+ *
37
+ * Checks if hash is valid for given password
38
+ *
39
+ * @param hash - hasth to validate
40
+ * @param password - password to validate
41
+ */
42
+ abstract verify(hash: string, password: string): Promise<boolean>;
43
+ /**
44
+ *
45
+ * Generate hashed string from user password
46
+ *
47
+ * @param input - string to hash
48
+ */
49
+ abstract hash(input: string): Promise<string>;
50
+ /**
51
+ * Generates random user password
52
+ */
53
+ abstract generate(): string;
54
+ }
55
+ export declare abstract class AuthProvider<U = User> {
56
+ abstract exists(user: U): Promise<boolean>;
57
+ abstract authenticate(email: string, password: string): Promise<U>;
58
+ }
59
+ export declare abstract class SessionProvider<T = UserSession> extends AsyncModule {
60
+ /**
61
+ *
62
+ * Load session from store. If not exists or expired returns null
63
+ *
64
+ * @param sessionId - session identifier
65
+ */
66
+ abstract restoreSession(sessionId: string): Promise<T>;
67
+ /**
68
+ *
69
+ * Deletes session from store
70
+ *
71
+ * @param sessionId - session to delete
72
+ */
73
+ abstract deleteSession(sessionId: string): Promise<void>;
74
+ /**
75
+ *
76
+ * Adds or updates session in store
77
+ *
78
+ * @param session - session to update / insert
79
+ */
80
+ abstract updateSession(session: UserSession): Promise<void>;
81
+ /**
82
+ *
83
+ * Extends session expiration time. Extension is set in acl.session.expiration (in seconds)
84
+ *
85
+ * @param sessionId - session to refres
86
+ */
87
+ abstract refreshSession(sessionId: string | UserSession): Promise<void>;
88
+ }
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SessionProvider = exports.AuthProvider = exports.PasswordProvider = void 0;
4
+ const di_1 = require("@spinajs/di");
5
+ /**
6
+ * Service used for generating random password & for hash raw string
7
+ */
8
+ class PasswordProvider {
9
+ }
10
+ exports.PasswordProvider = PasswordProvider;
11
+ class AuthProvider {
12
+ }
13
+ exports.AuthProvider = AuthProvider;
14
+ class SessionProvider extends di_1.AsyncModule {
15
+ }
16
+ exports.SessionProvider = SessionProvider;
17
+ //# sourceMappingURL=interfaces.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interfaces.js","sourceRoot":"","sources":["../src/interfaces.ts"],"names":[],"mappings":";;;AACA,oCAA0C;AAmC1C;;GAEG;AACH,MAAsB,gBAAgB;CAsBrC;AAtBD,4CAsBC;AAED,MAAsB,YAAY;CAIjC;AAJD,oCAIC;AAED,MAAsB,eAAiC,SAAQ,gBAAW;CAgCzE;AAhCD,0CAgCC"}
@@ -0,0 +1,5 @@
1
+ import { OrmMigration, OrmDriver } from '@spinajs/orm';
2
+ export declare class RBACInitial_2022_06_28_01_13_00 extends OrmMigration {
3
+ up(connection: OrmDriver): Promise<void>;
4
+ down(_connection: OrmDriver): Promise<void>;
5
+ }
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ 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;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.RBACInitial_2022_06_28_01_13_00 = void 0;
10
+ /* eslint-disable @typescript-eslint/no-unused-vars */
11
+ const orm_1 = require("@spinajs/orm");
12
+ let RBACInitial_2022_06_28_01_13_00 = class RBACInitial_2022_06_28_01_13_00 extends orm_1.OrmMigration {
13
+ async up(connection) {
14
+ await connection.schema().createTable('users', (table) => {
15
+ table.int('Id').autoIncrement().primaryKey();
16
+ table.string('Login', 64).unique().notNull();
17
+ table.string('Email', 64).unique().notNull();
18
+ table.string('Password', 128).notNull();
19
+ table.string('NiceName', 64).notNull();
20
+ table.string('Role', 64).notNull();
21
+ table.dateTime('RegisteredAt');
22
+ table.dateTime('CreatedAt').notNull();
23
+ table.dateTime('DeletedAt');
24
+ });
25
+ await connection.schema().createTable('user_metadatas', (table) => {
26
+ table.int('Id').autoIncrement().primaryKey();
27
+ table.string('Key', 255).notNull();
28
+ table.text('Value').notNull();
29
+ table.int('user_id').notNull();
30
+ table.foreignKey('user_id').references('users', 'Id').cascade();
31
+ });
32
+ await connection.index().unique().table('users').name('users_email_idx').columns(['Email']);
33
+ await connection.index().unique().table('user_metadatas').name('owner_user_meta_key_idx').columns(['user_id', 'Key']);
34
+ }
35
+ // tslint:disable-next-line: no-empty
36
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
37
+ async down(_connection) { }
38
+ };
39
+ RBACInitial_2022_06_28_01_13_00 = __decorate([
40
+ (0, orm_1.Migration)('default')
41
+ ], RBACInitial_2022_06_28_01_13_00);
42
+ exports.RBACInitial_2022_06_28_01_13_00 = RBACInitial_2022_06_28_01_13_00;
43
+ //# sourceMappingURL=RBACInitial_2022_06_28_01_13_00.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RBACInitial_2022_06_28_01_13_00.js","sourceRoot":"","sources":["../../src/migrations/RBACInitial_2022_06_28_01_13_00.ts"],"names":[],"mappings":";;;;;;;;;AAAA,sDAAsD;AACtD,sCAAkE;AAGlE,IAAa,+BAA+B,GAA5C,MAAa,+BAAgC,SAAQ,kBAAY;IACxD,KAAK,CAAC,EAAE,CAAC,UAAqB;QACnC,MAAM,UAAU,CAAC,MAAM,EAAE,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;YACvD,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,aAAa,EAAE,CAAC,UAAU,EAAE,CAAC;YAC7C,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,CAAC;YAC7C,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,CAAC;YAC7C,KAAK,CAAC,MAAM,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC;YACxC,KAAK,CAAC,MAAM,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC;YACvC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC;YACnC,KAAK,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC;YAC/B,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,OAAO,EAAE,CAAC;YACtC,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;QAC9B,CAAC,CAAC,CAAC;QAEH,MAAM,UAAU,CAAC,MAAM,EAAE,CAAC,WAAW,CAAC,gBAAgB,EAAE,CAAC,KAAK,EAAE,EAAE;YAChE,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,aAAa,EAAE,CAAC,UAAU,EAAE,CAAC;YAC7C,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC;YACnC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,CAAC;YAC9B,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,CAAC;YAC/B,KAAK,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,UAAU,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC;QAClE,CAAC,CAAC,CAAC;QAEH,MAAM,UAAU,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;QAE5F,MAAM,UAAU,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC,CAAC;IACxH,CAAC;IAED,qCAAqC;IACrC,gEAAgE;IACzD,KAAK,CAAC,IAAI,CAAC,WAAsB,IAAkB,CAAC;CAC5D,CAAA;AA9BY,+BAA+B;IAD3C,IAAA,eAAS,EAAC,SAAS,CAAC;GACR,+BAA+B,CA8B3C;AA9BY,0EAA+B"}
@@ -0,0 +1,41 @@
1
+ import { DateTime } from 'luxon';
2
+ import { ModelBase, Relation } from '@spinajs/orm';
3
+ import { UserMetadata } from './UserMetadata';
4
+ /**
5
+ * Base modele for users used by ACL
6
+ *
7
+ * To add / extend fields simply extend this model and register as default user model in ACL service
8
+ */
9
+ export declare class User extends ModelBase {
10
+ Id: number;
11
+ Email: string;
12
+ Login: string;
13
+ /**
14
+ * Hashed password for user
15
+ */
16
+ Password: string;
17
+ /**
18
+ * Registration date. User is registered when clicked confirmation link sended to provided email.
19
+ */
20
+ RegisteredAt: DateTime;
21
+ /**
22
+ * Displayed name ( for others to see )
23
+ */
24
+ NiceName: string;
25
+ /**
26
+ * User role
27
+ */
28
+ Role: string;
29
+ /**
30
+ * User creation date
31
+ */
32
+ CreatedAt: DateTime;
33
+ /**
34
+ * User deletion date
35
+ */
36
+ DeletedAt: DateTime;
37
+ /**
38
+ * User additional information. Can be anything
39
+ */
40
+ Metadata: Relation<UserMetadata>;
41
+ }
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ 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;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.User = void 0;
13
+ const luxon_1 = require("luxon");
14
+ const orm_1 = require("@spinajs/orm");
15
+ const UserMetadata_1 = require("./UserMetadata");
16
+ /**
17
+ * Base modele for users used by ACL
18
+ *
19
+ * To add / extend fields simply extend this model and register as default user model in ACL service
20
+ */
21
+ let User = class User extends orm_1.ModelBase {
22
+ };
23
+ __decorate([
24
+ (0, orm_1.Primary)(),
25
+ __metadata("design:type", Number)
26
+ ], User.prototype, "Id", void 0);
27
+ __decorate([
28
+ (0, orm_1.CreatedAt)(),
29
+ __metadata("design:type", luxon_1.DateTime)
30
+ ], User.prototype, "CreatedAt", void 0);
31
+ __decorate([
32
+ (0, orm_1.SoftDelete)(),
33
+ __metadata("design:type", luxon_1.DateTime)
34
+ ], User.prototype, "DeletedAt", void 0);
35
+ __decorate([
36
+ (0, orm_1.HasMany)(UserMetadata_1.UserMetadata),
37
+ __metadata("design:type", orm_1.Relation)
38
+ ], User.prototype, "Metadata", void 0);
39
+ User = __decorate([
40
+ (0, orm_1.Connection)('default'),
41
+ (0, orm_1.Model)('users')
42
+ ], User);
43
+ exports.User = User;
44
+ //# sourceMappingURL=User.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"User.js","sourceRoot":"","sources":["../../src/models/User.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,iCAAiC;AACjC,sCAA+G;AAC/G,iDAA8C;AAE9C;;;;GAIG;AAGH,IAAa,IAAI,GAAjB,MAAa,IAAK,SAAQ,eAAS;CA6ClC,CAAA;AA3CC;IADC,IAAA,aAAO,GAAE;;gCACQ;AA8BlB;IADC,IAAA,eAAS,GAAE;8BACM,gBAAQ;uCAAC;AAM3B;IADC,IAAA,gBAAU,GAAE;8BACK,gBAAQ;uCAAC;AAM3B;IADC,IAAA,aAAO,EAAC,2BAAY,CAAC;8BACL,cAAQ;sCAAe;AA5C7B,IAAI;IAFhB,IAAA,gBAAU,EAAC,SAAS,CAAC;IACrB,IAAA,WAAK,EAAC,OAAO,CAAC;GACF,IAAI,CA6ChB;AA7CY,oBAAI"}
@@ -0,0 +1,6 @@
1
+ import { ModelBase } from '@spinajs/orm';
2
+ export declare class UserMetadata extends ModelBase {
3
+ Id: number;
4
+ Key: string;
5
+ Value: string;
6
+ }
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ 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;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.UserMetadata = void 0;
13
+ const orm_1 = require("@spinajs/orm");
14
+ let UserMetadata = class UserMetadata extends orm_1.ModelBase {
15
+ };
16
+ __decorate([
17
+ (0, orm_1.Primary)(),
18
+ __metadata("design:type", Number)
19
+ ], UserMetadata.prototype, "Id", void 0);
20
+ UserMetadata = __decorate([
21
+ (0, orm_1.Connection)('default'),
22
+ (0, orm_1.Model)('user_metadatas')
23
+ ], UserMetadata);
24
+ exports.UserMetadata = UserMetadata;
25
+ //# sourceMappingURL=UserMetadata.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UserMetadata.js","sourceRoot":"","sources":["../../src/models/UserMetadata.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,sCAAqE;AAIrE,IAAa,YAAY,GAAzB,MAAa,YAAa,SAAQ,eAAS;CAO1C,CAAA;AALC;IADC,IAAA,aAAO,GAAE;;wCACQ;AAFP,YAAY;IAFxB,IAAA,gBAAU,EAAC,SAAS,CAAC;IACrB,IAAA,WAAK,EAAC,gBAAgB,CAAC;GACX,YAAY,CAOxB;AAPY,oCAAY"}
@@ -0,0 +1,16 @@
1
+ import { PasswordProvider } from './interfaces';
2
+ /**
3
+ * Simple password service that use argon2 hash alghoritm and entropy-string to generate password
4
+ */
5
+ export declare class BasicPasswordProvider implements PasswordProvider {
6
+ hash(input: string): Promise<string>;
7
+ /**
8
+ *
9
+ * Checks if hash is valid for given password
10
+ *
11
+ * @param hash - hash to validate
12
+ * @param password - password to validate
13
+ */
14
+ verify(hash: string, password: string): Promise<boolean>;
15
+ generate(): string;
16
+ }
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.BasicPasswordProvider = void 0;
27
+ // tslint:disable-next-line: no-var-requires
28
+ const { Entropy, charset32 } = require('entropy-string');
29
+ const argon = __importStar(require("argon2"));
30
+ /**
31
+ * Simple password service that use argon2 hash alghoritm and entropy-string to generate password
32
+ */
33
+ class BasicPasswordProvider {
34
+ async hash(input) {
35
+ // uses default argon settings, no need to tweak
36
+ return await argon.hash(input);
37
+ }
38
+ /**
39
+ *
40
+ * Checks if hash is valid for given password
41
+ *
42
+ * @param hash - hash to validate
43
+ * @param password - password to validate
44
+ */
45
+ async verify(hash, password) {
46
+ return await argon.verify(hash, password);
47
+ }
48
+ generate() {
49
+ // generates password with entropy of 60 bits ( balance of ease vs value )
50
+ const random = new Entropy({ charset: charset32 });
51
+ return random.string(60);
52
+ }
53
+ }
54
+ exports.BasicPasswordProvider = BasicPasswordProvider;
55
+ //# sourceMappingURL=password.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"password.js","sourceRoot":"","sources":["../src/password.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAEA,4CAA4C;AAC5C,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;AACzD,8CAAgC;AAEhC;;GAEG;AACH,MAAa,qBAAqB;IACzB,KAAK,CAAC,IAAI,CAAC,KAAa;QAC7B,gDAAgD;QAChD,OAAO,MAAM,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACjC,CAAC;IAED;;;;;;OAMG;IACI,KAAK,CAAC,MAAM,CAAC,IAAY,EAAE,QAAgB;QAChD,OAAO,MAAM,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IAC5C,CAAC;IAEM,QAAQ;QACb,0EAA0E;QAC1E,MAAM,MAAM,GAAG,IAAI,OAAO,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC,CAAC;QACnD,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAC3B,CAAC;CACF;AAtBD,sDAsBC"}
package/lib/rbac.js ADDED
@@ -0,0 +1,7 @@
1
+ 'use strict';
2
+
3
+ module.exports = rbac;
4
+
5
+ function rbac() {
6
+ // TODO
7
+ }
@@ -0,0 +1,32 @@
1
+ import { DateTime } from 'luxon';
2
+ import { SessionProvider, UserSession, UserSessionData } from './interfaces';
3
+ import { Configuration } from '@spinajs/configuration';
4
+ /**
5
+ * Session base class
6
+ */
7
+ export declare class Session implements UserSession {
8
+ protected SessionExpirationTime: number;
9
+ SessionId: string;
10
+ Expiration: DateTime;
11
+ Data: any;
12
+ Creation: DateTime;
13
+ constructor(data?: UserSessionData);
14
+ /**
15
+ * Extends lifetime of session
16
+ *
17
+ * @param minutes - hom mutch to extend
18
+ */
19
+ extend(minutes: number): void;
20
+ }
21
+ /**
22
+ * Simple session storage in memory
23
+ */
24
+ export declare class MemorySessionProvider<T = UserSession> extends SessionProvider<T> {
25
+ protected Configuration: Configuration;
26
+ protected Sessions: Map<string, UserSession>;
27
+ restoreSession(sessionId: string): Promise<T>;
28
+ resolveAsync(): Promise<void>;
29
+ deleteSession(sessionId: string): Promise<void>;
30
+ updateSession(session: UserSession): Promise<void>;
31
+ refreshSession(sessionId: string): Promise<void>;
32
+ }
package/lib/session.js ADDED
@@ -0,0 +1,96 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ 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;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.MemorySessionProvider = exports.Session = void 0;
13
+ const luxon_1 = require("luxon");
14
+ const interfaces_1 = require("./interfaces");
15
+ const di_1 = require("@spinajs/di");
16
+ const configuration_1 = require("@spinajs/configuration");
17
+ const uuid_1 = require("uuid");
18
+ /**
19
+ * Session base class
20
+ */
21
+ let Session = class Session {
22
+ constructor(data) {
23
+ if (data) {
24
+ Object.assign(this, data);
25
+ }
26
+ if (!this.SessionId) {
27
+ this.SessionId = (0, uuid_1.v4)();
28
+ }
29
+ /**
30
+ * always extend session time
31
+ */
32
+ this.Expiration = luxon_1.DateTime.now().plus({ minutes: this.SessionExpirationTime });
33
+ if (!this.Creation) {
34
+ this.Creation = luxon_1.DateTime.now();
35
+ }
36
+ }
37
+ /**
38
+ * Extends lifetime of session
39
+ *
40
+ * @param minutes - hom mutch to extend
41
+ */
42
+ extend(minutes) {
43
+ this.Expiration.plus({ minutes });
44
+ }
45
+ };
46
+ __decorate([
47
+ (0, configuration_1.Config)('rbac.session.expiration'),
48
+ __metadata("design:type", Number)
49
+ ], Session.prototype, "SessionExpirationTime", void 0);
50
+ Session = __decorate([
51
+ (0, di_1.NewInstance)(),
52
+ __metadata("design:paramtypes", [Object])
53
+ ], Session);
54
+ exports.Session = Session;
55
+ /**
56
+ * Simple session storage in memory
57
+ */
58
+ class MemorySessionProvider extends interfaces_1.SessionProvider {
59
+ constructor() {
60
+ super(...arguments);
61
+ this.Sessions = new Map();
62
+ }
63
+ async restoreSession(sessionId) {
64
+ if (this.Sessions.has(sessionId)) {
65
+ const session = this.Sessions.get(sessionId);
66
+ if (session.Expiration <= luxon_1.DateTime.now()) {
67
+ this.deleteSession(session.SessionId);
68
+ return null;
69
+ }
70
+ return session;
71
+ }
72
+ return null;
73
+ }
74
+ // tslint:disable-next-line: no-empty
75
+ async resolveAsync() { }
76
+ async deleteSession(sessionId) {
77
+ if (this.Sessions.has(sessionId)) {
78
+ this.Sessions.delete(sessionId);
79
+ }
80
+ }
81
+ async updateSession(session) {
82
+ this.Sessions.set(session.SessionId, session);
83
+ }
84
+ async refreshSession(sessionId) {
85
+ if (this.Sessions.has(sessionId)) {
86
+ const session = this.Sessions.get(sessionId);
87
+ session.extend(this.Configuration.get('acl.session.expiration', 10));
88
+ }
89
+ }
90
+ }
91
+ __decorate([
92
+ (0, di_1.Autoinject)(),
93
+ __metadata("design:type", configuration_1.Configuration)
94
+ ], MemorySessionProvider.prototype, "Configuration", void 0);
95
+ exports.MemorySessionProvider = MemorySessionProvider;
96
+ //# sourceMappingURL=session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.js","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,iCAAiC;AACjC,6CAA6E;AAC7E,oCAAsD;AACtD,0DAA+D;AAC/D,+BAAoC;AAEpC;;GAEG;AAEH,IAAa,OAAO,GAApB,MAAa,OAAO;IAYlB,YAAY,IAAsB;QAChC,IAAI,IAAI,EAAE;YACR,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;SAC3B;QAED,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE;YACnB,IAAI,CAAC,SAAS,GAAG,IAAA,SAAM,GAAE,CAAC;SAC3B;QAED;;WAEG;QACH,IAAI,CAAC,UAAU,GAAG,gBAAQ,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,qBAAqB,EAAE,CAAC,CAAC;QAE/E,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE;YAClB,IAAI,CAAC,QAAQ,GAAG,gBAAQ,CAAC,GAAG,EAAE,CAAC;SAChC;IACH,CAAC;IAED;;;;OAIG;IACI,MAAM,CAAC,OAAe;QAC3B,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC;IACpC,CAAC;CACF,CAAA;AArCC;IADC,IAAA,sBAAM,EAAC,yBAAyB,CAAC;;sDACM;AAF7B,OAAO;IADnB,IAAA,gBAAW,GAAE;;GACD,OAAO,CAuCnB;AAvCY,0BAAO;AAyCpB;;GAEG;AACH,MAAa,qBAAuC,SAAQ,4BAAkB;IAA9E;;QAIY,aAAQ,GAA6B,IAAI,GAAG,EAAuB,CAAC;IAqChF,CAAC;IAnCQ,KAAK,CAAC,cAAc,CAAC,SAAiB;QAC3C,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE;YAChC,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;YAE7C,IAAI,OAAO,CAAC,UAAU,IAAI,gBAAQ,CAAC,GAAG,EAAE,EAAE;gBACxC,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;gBACtC,OAAO,IAAI,CAAC;aACb;YAED,OAAO,OAAc,CAAC;SACvB;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAED,qCAAqC;IAC9B,KAAK,CAAC,YAAY,KAAI,CAAC;IAEvB,KAAK,CAAC,aAAa,CAAC,SAAiB;QAC1C,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE;YAChC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;SACjC;IACH,CAAC;IAEM,KAAK,CAAC,aAAa,CAAC,OAAoB;QAC7C,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IAChD,CAAC;IAEM,KAAK,CAAC,cAAc,CAAC,SAAiB;QAC3C,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE;YAChC,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;YAE7C,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAS,wBAAwB,EAAE,EAAE,CAAC,CAAC,CAAC;SAC9E;IACH,CAAC;CACF;AAvCC;IADC,IAAA,eAAU,GAAE;8BACY,6BAAa;4DAAC;AAFzC,sDAyCC"}
package/package.json ADDED
@@ -0,0 +1,58 @@
1
+ {
2
+ "name": "@spinajs/rbac",
3
+ "version": "1.2.108",
4
+ "description": "Role and Attribute based Access Control for SpinaJS framework",
5
+ "main": "lib/index.js",
6
+ "private": false,
7
+ "scripts": {
8
+ "build": "npm run clean && npm run compile",
9
+ "compile": "tsc -p tsconfig.build.json",
10
+ "clean": "",
11
+ "test": "ts-mocha -p tsconfig.json test/**/*.test.ts",
12
+ "coverage": "nyc npm run test",
13
+ "build-docs": "rimraf docs && typedoc --options typedoc.json src/",
14
+ "prepare": "npm run build",
15
+ "format": "prettier --write \"src/**/*.ts\"",
16
+ "lint": "eslint -c .eslintrc.js --ext .ts src --fix",
17
+ "prepublishOnly": "npm test && npm run lint",
18
+ "preversion": "npm run lint",
19
+ "version": "npm run format && git add -A src",
20
+ "postversion": "git push && git push --tags"
21
+ },
22
+ "files": [
23
+ "lib/**/*"
24
+ ],
25
+ "types": "lib",
26
+ "repository": {
27
+ "type": "git",
28
+ "url": "git+https://github.com/spinajs/main.git"
29
+ },
30
+ "keywords": [
31
+ "spinajs",
32
+ "rbac"
33
+ ],
34
+ "author": "SpinaJS <spinajs@coderush.pl> (https://github.com/spinajs/main)",
35
+ "license": "MIT",
36
+ "bugs": {
37
+ "url": "https://github.com/spinajs/main/issues"
38
+ },
39
+ "homepage": "https://github.com/spinajs/main#readme",
40
+ "dependencies": {
41
+ "@spinajs/configuration": "^1.2.81",
42
+ "@spinajs/di": "^1.2.81",
43
+ "@spinajs/exceptions": "^1.2.81",
44
+ "@spinajs/log": "^1.2.103",
45
+ "@spinajs/orm": "^1.2.108",
46
+ "@spinajs/reflection": "^1.2.103",
47
+ "accesscontrol": "^2.2.1",
48
+ "argon2": "^0.28.5",
49
+ "entropy-string": "^4.2.0",
50
+ "lodash": "^4.17.21",
51
+ "luxon": "^2.4.0",
52
+ "uuid": "^8.1.0"
53
+ },
54
+ "devDependencies": {
55
+ "@spinajs/orm-sqlite": "^1.2.108"
56
+ },
57
+ "gitHead": "81e996198a9d4dac8970f71181b0f5eaf6070918"
58
+ }