@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 +11 -0
- package/lib/auth.d.ts +8 -0
- package/lib/auth.js +47 -0
- package/lib/auth.js.map +1 -0
- package/lib/config/rbac.d.ts +1 -0
- package/lib/config/rbac.js +33 -0
- package/lib/config/rbac.js.map +1 -0
- package/lib/index.d.ts +11 -0
- package/lib/index.js +54 -0
- package/lib/index.js.map +1 -0
- package/lib/interfaces.d.ts +88 -0
- package/lib/interfaces.js +17 -0
- package/lib/interfaces.js.map +1 -0
- package/lib/migrations/RBACInitial_2022_06_28_01_13_00.d.ts +5 -0
- package/lib/migrations/RBACInitial_2022_06_28_01_13_00.js +43 -0
- package/lib/migrations/RBACInitial_2022_06_28_01_13_00.js.map +1 -0
- package/lib/models/User.d.ts +41 -0
- package/lib/models/User.js +44 -0
- package/lib/models/User.js.map +1 -0
- package/lib/models/UserMetadata.d.ts +6 -0
- package/lib/models/UserMetadata.js +25 -0
- package/lib/models/UserMetadata.js.map +1 -0
- package/lib/password.d.ts +16 -0
- package/lib/password.js +55 -0
- package/lib/password.js.map +1 -0
- package/lib/rbac.js +7 -0
- package/lib/session.d.ts +32 -0
- package/lib/session.js +96 -0
- package/lib/session.js.map +1 -0
- package/package.json +58 -0
package/README.md
ADDED
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
|
package/lib/auth.js.map
ADDED
|
@@ -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
|
package/lib/index.js.map
ADDED
|
@@ -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,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,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
|
+
}
|
package/lib/password.js
ADDED
|
@@ -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
package/lib/session.d.ts
ADDED
|
@@ -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
|
+
}
|