@nu-art/user-account-backend 0.400.5
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/SlackReporter.d.ts +8 -0
- package/SlackReporter.js +27 -0
- package/_entity/account/ModuleBE_AccountDB.d.ts +97 -0
- package/_entity/account/ModuleBE_AccountDB.js +333 -0
- package/_entity/account/ModuleBE_SAML.d.ts +37 -0
- package/_entity/account/ModuleBE_SAML.js +92 -0
- package/_entity/account/index.d.ts +3 -0
- package/_entity/account/index.js +3 -0
- package/_entity/account/module-pack.d.ts +3 -0
- package/_entity/account/module-pack.js +7 -0
- package/_entity/failed-login-attempt/ModuleBE_FailedLoginAttemptDB.d.ts +50 -0
- package/_entity/failed-login-attempt/ModuleBE_FailedLoginAttemptDB.js +105 -0
- package/_entity/failed-login-attempt/index.d.ts +2 -0
- package/_entity/failed-login-attempt/index.js +2 -0
- package/_entity/failed-login-attempt/module-pack.d.ts +1 -0
- package/_entity/failed-login-attempt/module-pack.js +3 -0
- package/_entity/login-attempts/ModuleBE_LoginAttemptDB.d.ts +36 -0
- package/_entity/login-attempts/ModuleBE_LoginAttemptDB.js +51 -0
- package/_entity/login-attempts/dispatchers.d.ts +5 -0
- package/_entity/login-attempts/dispatchers.js +2 -0
- package/_entity/login-attempts/index.d.ts +2 -0
- package/_entity/login-attempts/index.js +2 -0
- package/_entity/login-attempts/module-pack.d.ts +1 -0
- package/_entity/login-attempts/module-pack.js +3 -0
- package/_entity/session/ModuleBE_JWT.d.ts +46 -0
- package/_entity/session/ModuleBE_JWT.js +86 -0
- package/_entity/session/ModuleBE_SessionDB.d.ts +77 -0
- package/_entity/session/ModuleBE_SessionDB.js +233 -0
- package/_entity/session/consts.d.ts +22 -0
- package/_entity/session/consts.js +33 -0
- package/_entity/session/index.d.ts +3 -0
- package/_entity/session/index.js +3 -0
- package/_entity/session/module-pack.d.ts +2 -0
- package/_entity/session/module-pack.js +2 -0
- package/_entity.d.ts +8 -0
- package/_entity.js +8 -0
- package/index.d.ts +3 -0
- package/index.js +20 -0
- package/module-pack.d.ts +3 -0
- package/module-pack.js +35 -0
- package/package.json +81 -0
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
import { ApiException, currentTimeMillis, Day, Dispatcher, filterKeys, isErrorOfType, JwtTools, md5, MUSTNeverHappenException } from '@nu-art/ts-common';
|
|
2
|
+
import { ModuleBE_BaseDB } from '@nu-art/thunderstorm-backend';
|
|
3
|
+
import { DBDef_Session } from '@nu-art/user-account-shared';
|
|
4
|
+
import { Header_Authorization, MemKey_DB_Session, MemKey_Jwt, MemKey_SessionData, SessionKey_Account_BE } from './consts.js';
|
|
5
|
+
import { MemKey_HttpResponse } from '@nu-art/thunderstorm-backend/modules/server/consts';
|
|
6
|
+
import { ResponseHeaderKey_JWTToken } from '@nu-art/thunderstorm-shared';
|
|
7
|
+
import { ModuleBE_JWT } from './ModuleBE_JWT.js';
|
|
8
|
+
import { HttpCodes } from '@nu-art/ts-common/core/exceptions/http-codes';
|
|
9
|
+
export const dispatch_CollectSessionData = new Dispatcher('__collectSessionData');
|
|
10
|
+
export const Const_Default_SessionJWT_SecretKey = 'jwt-signer--account-session';
|
|
11
|
+
export class ModuleBE_SessionDB_Class extends ModuleBE_BaseDB {
|
|
12
|
+
jwtHandler;
|
|
13
|
+
constructor() {
|
|
14
|
+
super(DBDef_Session);
|
|
15
|
+
this.setDefaultConfig({
|
|
16
|
+
sessionTTLms: Day,
|
|
17
|
+
rotationFactor: 0.5,
|
|
18
|
+
maxPrevSession: 10,
|
|
19
|
+
jwtSigner: {
|
|
20
|
+
secretKey: Const_Default_SessionJWT_SecretKey
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
init() {
|
|
25
|
+
super.init();
|
|
26
|
+
this.jwtHandler = ModuleBE_JWT.jwtHandler({
|
|
27
|
+
label: 'Session-JWT',
|
|
28
|
+
ttlInMs: Day,
|
|
29
|
+
rotationIntervalInMs: 2 * Day,
|
|
30
|
+
...this.config.jwtSigner
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
collectSessionData = async (content, transaction) => {
|
|
34
|
+
const collectedData = (await dispatch_CollectSessionData.dispatchModuleAsync(content, transaction));
|
|
35
|
+
return collectedData.reduce((sessionData, moduleSessionData) => {
|
|
36
|
+
// We don't skip existing keys. This allows us to override session data provided by infra, with session data provided by app. If wanted, add flag to symbolize this is intentional to all relevant places.
|
|
37
|
+
sessionData[moduleSessionData.key] = moduleSessionData.value;
|
|
38
|
+
return sessionData;
|
|
39
|
+
}, { ...content });
|
|
40
|
+
};
|
|
41
|
+
token = {
|
|
42
|
+
create: async (initialClaims, ttlInMs, transaction) => {
|
|
43
|
+
const claims = await this.collectSessionData(initialClaims, transaction);
|
|
44
|
+
return await this.jwtHandler.create(claims, ttlInMs ?? this.config.sessionTTLms);
|
|
45
|
+
},
|
|
46
|
+
refresh: async (jwtOrigin) => {
|
|
47
|
+
const claims = await this.token.verify(jwtOrigin);
|
|
48
|
+
return await this.jwtHandler.create(claims, (claims.exp - claims.iat) * 1000);
|
|
49
|
+
},
|
|
50
|
+
verify: async (jwt) => {
|
|
51
|
+
const result = await this.jwtHandler.verifySignature(jwt);
|
|
52
|
+
if (!result.validated)
|
|
53
|
+
throw HttpCodes._4XX.UNAUTHORIZED('JWT received in request is invalid');
|
|
54
|
+
return result.claims;
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
__session = {
|
|
58
|
+
shouldRefresh: async (jwt) => {
|
|
59
|
+
// Decode the JWT to retrieve its claims (issued and expiry time).
|
|
60
|
+
const sessionData = await this.jwtHandler.assert(jwt);
|
|
61
|
+
if (SessionKey_Account_BE.get(sessionData).type === 'service') {
|
|
62
|
+
this.logWarning('Cannot refresh session for a service account. This is not allowed.');
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
// Extract timestamps from the session data.
|
|
66
|
+
const issuedAt = sessionData.iat; // Issued timestamp (in seconds since epoch).
|
|
67
|
+
const expiresAt = sessionData.exp; // Expiry timestamp.
|
|
68
|
+
// Compute total session TTL (in seconds).
|
|
69
|
+
const totalTTL = expiresAt - issuedAt;
|
|
70
|
+
// Compute the remaining time to expiry.
|
|
71
|
+
const remainingTTL = expiresAt - Math.floor(currentTimeMillis() / 1000); // Current time in seconds.
|
|
72
|
+
// Determine if the session should be rotated:
|
|
73
|
+
return remainingTTL / totalTTL < this.config.rotationFactor;
|
|
74
|
+
},
|
|
75
|
+
refresh: async (dbSession = MemKey_DB_Session.get(), transaction) => {
|
|
76
|
+
this.logInfo(`Refreshing JWT for Account: ${dbSession.accountId}`);
|
|
77
|
+
const jwt = await this.token.refresh(dbSession.sessionIdJwt);
|
|
78
|
+
const content = {
|
|
79
|
+
linkedSessionId: dbSession._id,
|
|
80
|
+
prevSessions: dbSession.validSessionJwtMd5s,
|
|
81
|
+
initialClaims: {
|
|
82
|
+
accountId: dbSession.accountId,
|
|
83
|
+
deviceId: dbSession.deviceId,
|
|
84
|
+
label: `refreshed from ${dbSession._id}`,
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
return await this._session.save(content, jwt, transaction);
|
|
88
|
+
},
|
|
89
|
+
reissue: async (dbSession = MemKey_DB_Session.get(), transaction) => {
|
|
90
|
+
this.logInfo(`Reissuing JWT for Account: ${dbSession.accountId} from Session: ${dbSession._id}`);
|
|
91
|
+
const claims = await this.token.verify(dbSession.sessionIdJwt);
|
|
92
|
+
const initialClaims = {
|
|
93
|
+
accountId: claims.accountId,
|
|
94
|
+
deviceId: claims.deviceId,
|
|
95
|
+
label: `reissued from ${dbSession._id}`,
|
|
96
|
+
};
|
|
97
|
+
const jwt = await this.token.create(initialClaims, (claims.exp - claims.iat) * 1000, transaction);
|
|
98
|
+
const content = {
|
|
99
|
+
linkedSessionId: dbSession._id,
|
|
100
|
+
prevSessions: dbSession.validSessionJwtMd5s,
|
|
101
|
+
initialClaims: initialClaims
|
|
102
|
+
};
|
|
103
|
+
return await this._session.save(content, jwt, transaction);
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
_session = {
|
|
107
|
+
query: {
|
|
108
|
+
byJwt: async (jwt, transaction) => {
|
|
109
|
+
return await this.query.uniqueCustom({
|
|
110
|
+
// We use an md5 to save and query for the session object. The original sessionId(JWT) is too big.
|
|
111
|
+
where: { validSessionJwtMd5s: { $ac: md5(jwt) } },
|
|
112
|
+
orderBy: [{ key: '__created', order: 'desc' }],
|
|
113
|
+
limit: 1
|
|
114
|
+
}, transaction);
|
|
115
|
+
}
|
|
116
|
+
},
|
|
117
|
+
return: async (dbSession) => {
|
|
118
|
+
const jwt = dbSession.sessionIdJwt;
|
|
119
|
+
MemKey_HttpResponse.get().setHeader(ResponseHeaderKey_JWTToken, jwt);
|
|
120
|
+
MemKey_SessionData.set(await JwtTools.decode(jwt));
|
|
121
|
+
MemKey_Jwt.set(jwt);
|
|
122
|
+
return jwt;
|
|
123
|
+
},
|
|
124
|
+
save: async (content, jwt, transaction) => {
|
|
125
|
+
const _id = md5(jwt);
|
|
126
|
+
const validSessionJwtMd5s = content.prevSessions ? [_id, ...content.prevSessions] : [_id];
|
|
127
|
+
if (validSessionJwtMd5s.length > this.config.maxPrevSession)
|
|
128
|
+
validSessionJwtMd5s.length = this.config.maxPrevSession;
|
|
129
|
+
const dbSession = filterKeys({
|
|
130
|
+
_id,
|
|
131
|
+
linkedSessionId: content.linkedSessionId,
|
|
132
|
+
validSessionJwtMd5s: validSessionJwtMd5s,
|
|
133
|
+
accountId: content.initialClaims.accountId,
|
|
134
|
+
deviceId: content.initialClaims.deviceId,
|
|
135
|
+
label: content.initialClaims.label,
|
|
136
|
+
sessionIdJwt: jwt,
|
|
137
|
+
}, ['linkedSessionId', 'label']);
|
|
138
|
+
return await this.set.item(dbSession, transaction);
|
|
139
|
+
},
|
|
140
|
+
create: Object.assign(async (content, ttlInMs, transaction) => {
|
|
141
|
+
this.logInfo(`Creating JWT for Account: ${content.initialClaims.accountId}`);
|
|
142
|
+
const jwt = await this.token.create(content.initialClaims, ttlInMs, transaction);
|
|
143
|
+
return await this._session.save(content, jwt, transaction);
|
|
144
|
+
}, {
|
|
145
|
+
andReturn: async (content, ttlInMs, transaction) => {
|
|
146
|
+
const dbSession = await this._session.create(content, ttlInMs, transaction);
|
|
147
|
+
return await this._session.return(dbSession);
|
|
148
|
+
},
|
|
149
|
+
}),
|
|
150
|
+
rotate: {
|
|
151
|
+
refreshIfNeeded: {
|
|
152
|
+
byJwt: async (jwt, transaction) => {
|
|
153
|
+
if (!(await this.__session.shouldRefresh(jwt)))
|
|
154
|
+
return;
|
|
155
|
+
const dbSession = await this._session.query.byJwt(jwt, transaction);
|
|
156
|
+
this.logInfo(`Refreshing Session by JWT for account(${dbSession.accountId}) sessionId(${dbSession._id})`);
|
|
157
|
+
return await this.__session.refresh(dbSession, transaction);
|
|
158
|
+
},
|
|
159
|
+
bySession: async (dbSession = MemKey_DB_Session.get(), transaction) => {
|
|
160
|
+
if (!(await this.__session.shouldRefresh(dbSession.sessionIdJwt)))
|
|
161
|
+
return dbSession;
|
|
162
|
+
this.logInfo(`Refreshing Session by dbSession for account(${dbSession.accountId}) sessionId(${dbSession._id})`);
|
|
163
|
+
return await this.__session.refresh(dbSession, transaction);
|
|
164
|
+
}
|
|
165
|
+
},
|
|
166
|
+
reissue: {
|
|
167
|
+
byJwt: async (jwt, transaction) => {
|
|
168
|
+
await this.jwtHandler.assert(jwt);
|
|
169
|
+
const dbSession = await this._session.query.byJwt(jwt, transaction);
|
|
170
|
+
return await this.__session.reissue(dbSession, transaction);
|
|
171
|
+
},
|
|
172
|
+
bySession: async (dbSession = MemKey_DB_Session.get(), transaction) => {
|
|
173
|
+
await this.jwtHandler.assert(dbSession.sessionIdJwt);
|
|
174
|
+
return await this.__session.reissue(dbSession, transaction);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
},
|
|
178
|
+
invalidate: {
|
|
179
|
+
byJwt: async (jwt, transaction) => {
|
|
180
|
+
const session = await this._session.query.byJwt(jwt, transaction);
|
|
181
|
+
return await this._session.invalidate.bySession(session, transaction);
|
|
182
|
+
},
|
|
183
|
+
bySession: async (dbSession = MemKey_DB_Session.get(), transaction) => {
|
|
184
|
+
if (!dbSession)
|
|
185
|
+
throw HttpCodes._4XX.UNAUTHORIZED('No session in context to invalidate');
|
|
186
|
+
await this.set.item({ ...dbSession, validSessionJwtMd5s: [] }, transaction);
|
|
187
|
+
this.logInfo(`Session invalidated for account: ${dbSession.accountId}, sessionId: ${dbSession._id}`);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
};
|
|
191
|
+
Middleware = async () => {
|
|
192
|
+
const jwt = Header_Authorization.get(); //jwt
|
|
193
|
+
const expired = await this.jwtHandler.isExpired(jwt);
|
|
194
|
+
if (expired)
|
|
195
|
+
throw HttpCodes._4XX.UNAUTHORIZED('JWT received in request is expired');
|
|
196
|
+
const validationResult = await this.jwtHandler.verifySignature(jwt);
|
|
197
|
+
if (!validationResult.validated)
|
|
198
|
+
throw HttpCodes._4XX.FORBIDDEN('JWT received in request is invalid');
|
|
199
|
+
await this.locateSession(jwt);
|
|
200
|
+
};
|
|
201
|
+
async locateSession(jwt) {
|
|
202
|
+
try {
|
|
203
|
+
const { dbSession, claims } = await this.runTransaction(async (t) => {
|
|
204
|
+
let dbSession = await this._session.query.byJwt(jwt);
|
|
205
|
+
const latestJwtValidationResult = await this.jwtHandler.verifySignature(dbSession.sessionIdJwt);
|
|
206
|
+
if (!latestJwtValidationResult.validated)
|
|
207
|
+
throw new MUSTNeverHappenException(`JWT received from DB is invalid Session id = ${dbSession._id}`);
|
|
208
|
+
dbSession = await this._session.rotate.refreshIfNeeded.bySession(dbSession);
|
|
209
|
+
return { dbSession, claims: latestJwtValidationResult.claims };
|
|
210
|
+
});
|
|
211
|
+
MemKey_DB_Session.set(dbSession);
|
|
212
|
+
MemKey_SessionData.set(claims);
|
|
213
|
+
MemKey_Jwt.set(dbSession.sessionIdJwt);
|
|
214
|
+
MemKey_HttpResponse.get().setHeader(ResponseHeaderKey_JWTToken, dbSession.sessionIdJwt);
|
|
215
|
+
}
|
|
216
|
+
catch (err) {
|
|
217
|
+
if (isErrorOfType(err, ApiException))
|
|
218
|
+
throw err;
|
|
219
|
+
this.logErrorBold(jwt);
|
|
220
|
+
throw HttpCodes._4XX.UNAUTHORIZED('JWT received in request is invalid', err);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
async __collectSessionData(data) {
|
|
224
|
+
return {
|
|
225
|
+
key: 'session',
|
|
226
|
+
value: {
|
|
227
|
+
deviceId: data.deviceId,
|
|
228
|
+
}
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
;
|
|
233
|
+
export const ModuleBE_SessionDB = new ModuleBE_SessionDB_Class();
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { MemKey } from '@nu-art/ts-common/mem-storage/MemStorage';
|
|
2
|
+
import { RecursiveObjectOfPrimitives, TypedKeyValue } from '@nu-art/ts-common';
|
|
3
|
+
import { DB_Session } from '@nu-art/user-account-shared';
|
|
4
|
+
import { HeaderKey } from '@nu-art/thunderstorm-backend';
|
|
5
|
+
import { _SessionKey_Account } from '@nu-art/user-account-shared';
|
|
6
|
+
export declare const MemKey_AccountEmail: MemKey<string>;
|
|
7
|
+
export declare const MemKey_AccountId: MemKey<string>;
|
|
8
|
+
export declare const MemKey_AccountType: MemKey<string>;
|
|
9
|
+
export declare const MemKey_DB_Session: MemKey<DB_Session>;
|
|
10
|
+
export declare const MemKey_SessionData: MemKey<RecursiveObjectOfPrimitives>;
|
|
11
|
+
export declare const MemKey_Jwt: MemKey<string>;
|
|
12
|
+
export declare const Header_Authorization: HeaderKey;
|
|
13
|
+
export declare const Header_Origin: HeaderKey;
|
|
14
|
+
export declare const Header_TabId: HeaderKey;
|
|
15
|
+
export declare const Header_DeviceId: HeaderKey;
|
|
16
|
+
export declare class SessionKey_BE<Binder extends TypedKeyValue<string | number, any>> {
|
|
17
|
+
private readonly key;
|
|
18
|
+
constructor(key: Binder['key']);
|
|
19
|
+
get(sessionData?: RecursiveObjectOfPrimitives): Binder['value'];
|
|
20
|
+
}
|
|
21
|
+
export declare const SessionKey_Account_BE: SessionKey_BE<_SessionKey_Account>;
|
|
22
|
+
export declare function getAuditorId(): Promise<string>;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { MemKey } from '@nu-art/ts-common/mem-storage/MemStorage';
|
|
2
|
+
import { BadImplementationException, ImplementationMissingException } from '@nu-art/ts-common';
|
|
3
|
+
import { HeaderKey } from '@nu-art/thunderstorm-backend';
|
|
4
|
+
import { HeaderKey_Authorization, HeaderKey_DeviceId, HeaderKey_Origin, HeaderKey_TabId } from '@nu-art/thunderstorm-shared/headers';
|
|
5
|
+
export const MemKey_AccountEmail = new MemKey('accounts--email', true);
|
|
6
|
+
export const MemKey_AccountId = new MemKey('accounts--id', true);
|
|
7
|
+
export const MemKey_AccountType = new MemKey('accounts--type', true);
|
|
8
|
+
export const MemKey_DB_Session = new MemKey('db-session-object', false);
|
|
9
|
+
export const MemKey_SessionData = new MemKey('jwt-claims', false);
|
|
10
|
+
export const MemKey_Jwt = new MemKey('jwt-token', false);
|
|
11
|
+
export const Header_Authorization = new HeaderKey(HeaderKey_Authorization, 403)
|
|
12
|
+
.setProcessor((v) => (v ?? '').trim().replace(/^bearer\s+/i, ''));
|
|
13
|
+
export const Header_Origin = new HeaderKey(HeaderKey_Origin, 403);
|
|
14
|
+
export const Header_TabId = new HeaderKey(HeaderKey_TabId);
|
|
15
|
+
export const Header_DeviceId = new HeaderKey(HeaderKey_DeviceId);
|
|
16
|
+
export class SessionKey_BE {
|
|
17
|
+
key;
|
|
18
|
+
constructor(key) {
|
|
19
|
+
this.key = key;
|
|
20
|
+
}
|
|
21
|
+
get(sessionData = MemKey_SessionData.get()) {
|
|
22
|
+
if (!(this.key in sessionData))
|
|
23
|
+
throw new BadImplementationException(`Couldn't find key "${this.key}" in session data`);
|
|
24
|
+
return sessionData[this.key];
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
export const SessionKey_Account_BE = new SessionKey_BE('account');
|
|
28
|
+
export async function getAuditorId() {
|
|
29
|
+
const sessionData = SessionKey_Account_BE.get();
|
|
30
|
+
if (!sessionData)
|
|
31
|
+
throw new ImplementationMissingException('Trying to add auditorId without session data!');
|
|
32
|
+
return sessionData._id;
|
|
33
|
+
}
|
package/_entity.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export * from './_entity/account/index.js';
|
|
2
|
+
export * from './_entity/account/index.js';
|
|
3
|
+
export * from './_entity/session/index.js';
|
|
4
|
+
export * from './_entity/session/index.js';
|
|
5
|
+
export * from './_entity/login-attempts/index.js';
|
|
6
|
+
export * from './_entity/login-attempts/index.js';
|
|
7
|
+
export * from './_entity/failed-login-attempt/index.js';
|
|
8
|
+
export * from './_entity/failed-login-attempt/index.js';
|
package/_entity.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export * from './_entity/account/index.js';
|
|
2
|
+
export * from './_entity/account/index.js';
|
|
3
|
+
export * from './_entity/session/index.js';
|
|
4
|
+
export * from './_entity/session/index.js';
|
|
5
|
+
export * from './_entity/login-attempts/index.js';
|
|
6
|
+
export * from './_entity/login-attempts/index.js';
|
|
7
|
+
export * from './_entity/failed-login-attempt/index.js';
|
|
8
|
+
export * from './_entity/failed-login-attempt/index.js';
|
package/index.d.ts
ADDED
package/index.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* User secured registration and login management system..
|
|
3
|
+
*
|
|
4
|
+
* Copyright (C) 2020 Adam van der Kruk aka TacB0sS
|
|
5
|
+
*
|
|
6
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
|
+
* you may not use this file except in compliance with the License.
|
|
8
|
+
* You may obtain a copy of the License at
|
|
9
|
+
*
|
|
10
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
*
|
|
12
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
13
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
14
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
15
|
+
* See the License for the specific language governing permissions and
|
|
16
|
+
* limitations under the License.
|
|
17
|
+
*/
|
|
18
|
+
export * from './module-pack.js';
|
|
19
|
+
export * from './_entity.js';
|
|
20
|
+
export * from './SlackReporter.js';
|
package/module-pack.d.ts
ADDED
package/module-pack.js
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* User secured registration and login management system..
|
|
3
|
+
*
|
|
4
|
+
* Copyright (C) 2020 Adam van der Kruk aka TacB0sS
|
|
5
|
+
*
|
|
6
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
|
+
* you may not use this file except in compliance with the License.
|
|
8
|
+
* You may obtain a copy of the License at
|
|
9
|
+
*
|
|
10
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
*
|
|
12
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
13
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
14
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
15
|
+
* See the License for the specific language governing permissions and
|
|
16
|
+
* limitations under the License.
|
|
17
|
+
*/
|
|
18
|
+
import { ModulePackBE_AccountDB, ModulePackBE_FailedLoginAttemptDB, ModulePackBE_SAML, ModulePackBE_SessionDB } from './_entity.js';
|
|
19
|
+
import { ModuleBE_SecretManager } from '@nu-art/google-services-backend/modules/ModuleBE_SecretManager';
|
|
20
|
+
import { ModulePackBE_LoginAttemptDB } from './_entity/login-attempts/index.js';
|
|
21
|
+
export const ModulePackBE_Accounts = [
|
|
22
|
+
...ModulePackBE_AccountDB,
|
|
23
|
+
...ModulePackBE_SAML,
|
|
24
|
+
...ModulePackBE_SessionDB,
|
|
25
|
+
...ModulePackBE_LoginAttemptDB,
|
|
26
|
+
...ModulePackBE_FailedLoginAttemptDB,
|
|
27
|
+
ModuleBE_SecretManager
|
|
28
|
+
];
|
|
29
|
+
export const ModulePackBE_Accounts_WOSAML = [
|
|
30
|
+
...ModulePackBE_AccountDB,
|
|
31
|
+
...ModulePackBE_SessionDB,
|
|
32
|
+
...ModulePackBE_LoginAttemptDB,
|
|
33
|
+
...ModulePackBE_FailedLoginAttemptDB,
|
|
34
|
+
ModuleBE_SecretManager
|
|
35
|
+
];
|
package/package.json
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@nu-art/user-account-backend",
|
|
3
|
+
"version": "0.400.5",
|
|
4
|
+
"description": "User Account Backend",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"TacB0sS",
|
|
7
|
+
"create account",
|
|
8
|
+
"express",
|
|
9
|
+
"infra",
|
|
10
|
+
"login",
|
|
11
|
+
"nu-art",
|
|
12
|
+
"saml",
|
|
13
|
+
"thunderstorm",
|
|
14
|
+
"typescript",
|
|
15
|
+
"user-account"
|
|
16
|
+
],
|
|
17
|
+
"homepage": "https://github.com/nu-art-js/user-account",
|
|
18
|
+
"bugs": {
|
|
19
|
+
"url": "https://github.com/nu-art-js/user-account/issues"
|
|
20
|
+
},
|
|
21
|
+
"publishConfig": {
|
|
22
|
+
"directory": "dist",
|
|
23
|
+
"linkDirectory": true
|
|
24
|
+
},
|
|
25
|
+
"repository": {
|
|
26
|
+
"type": "git",
|
|
27
|
+
"url": "git+ssh://git@github.com:nu-art-js/user-account.git"
|
|
28
|
+
},
|
|
29
|
+
"license": "Apache-2.0",
|
|
30
|
+
"author": "TacB0sS",
|
|
31
|
+
"scripts": {
|
|
32
|
+
"build": "tsc",
|
|
33
|
+
"run-tests": "firebase emulators:exec \"npm run test\"",
|
|
34
|
+
"test": "ts-mocha -w -p src/test/tsconfig.json --timeout 0 --inspect=8107 --watch-files 'src/test/**/*.test.ts' src/test/**/*.test.ts"
|
|
35
|
+
},
|
|
36
|
+
"dependencies": {
|
|
37
|
+
"@nu-art/user-account-shared": "0.400.5",
|
|
38
|
+
"@nu-art/firebase-backend": "0.400.5",
|
|
39
|
+
"@nu-art/firebase-shared": "0.400.5",
|
|
40
|
+
"@nu-art/slack-backend": "0.400.5",
|
|
41
|
+
"@nu-art/slack-shared": "0.400.5",
|
|
42
|
+
"@nu-art/thunderstorm-backend": "0.400.5",
|
|
43
|
+
"@nu-art/thunderstorm-shared": "0.400.5",
|
|
44
|
+
"@nu-art/ts-common": "0.400.5",
|
|
45
|
+
"@nu-art/ts-styles": "0.400.5",
|
|
46
|
+
"express": "^4.18.2",
|
|
47
|
+
"firebase": "^11.9.0",
|
|
48
|
+
"firebase-admin": "13.4.0",
|
|
49
|
+
"firebase-functions": "6.3.2",
|
|
50
|
+
"moment": "^2.29.4",
|
|
51
|
+
"pako": "^2.1.0",
|
|
52
|
+
"react": "^18.0.0",
|
|
53
|
+
"request": "^2.88.0",
|
|
54
|
+
"saml2-js": "^4.0.1",
|
|
55
|
+
"xmlbuilder": "^15.1.1"
|
|
56
|
+
},
|
|
57
|
+
"devDependencies": {
|
|
58
|
+
"@nu-art/google-services-backend": "0.400.5",
|
|
59
|
+
"@types/react": "^18.0.0",
|
|
60
|
+
"@types/express": "^4.17.17",
|
|
61
|
+
"@types/history": "^4.7.2",
|
|
62
|
+
"@types/request": "^2.48.1",
|
|
63
|
+
"@types/saml2-js": "^1.6.8",
|
|
64
|
+
"@types/pako": "^2.0.0",
|
|
65
|
+
"@types/jsonwebtoken": "^9.0.6"
|
|
66
|
+
},
|
|
67
|
+
"unitConfig": {
|
|
68
|
+
"type": "typescript-lib"
|
|
69
|
+
},
|
|
70
|
+
"type": "module",
|
|
71
|
+
"exports": {
|
|
72
|
+
".": {
|
|
73
|
+
"types": "./index.d.ts",
|
|
74
|
+
"import": "./index.js"
|
|
75
|
+
},
|
|
76
|
+
"./*": {
|
|
77
|
+
"types": "./*.d.ts",
|
|
78
|
+
"import": "./*.js"
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|