@smartsoft001/auth-shell-app-services 2.75.0 → 2.80.0
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/index.js +315 -0
- package/package.json +1 -1
- package/src/lib/services/auth/auth.service.d.ts +12 -0
- package/src/lib/services/{index.ts → index.d.ts} +1 -3
- package/.eslintrc.json +0 -26
- package/jest.config.ts +0 -26
- package/project.json +0 -44
- package/src/lib/services/auth/auth.service.spec.ts +0 -114
- package/src/lib/services/auth/auth.service.ts +0 -66
- package/tsconfig.json +0 -13
- package/tsconfig.lib.json +0 -11
- package/tsconfig.spec.json +0 -20
- /package/src/{index.ts → index.d.ts} +0 -0
- /package/{test-setup.ts → test-setup.d.ts} +0 -0
package/index.js
ADDED
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __decorateClass = (decorators, target, key, kind) => {
|
|
4
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
5
|
+
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
6
|
+
if (decorator = decorators[i])
|
|
7
|
+
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
8
|
+
if (kind && result)
|
|
9
|
+
__defProp(target, key, result);
|
|
10
|
+
return result;
|
|
11
|
+
};
|
|
12
|
+
var __decorateParam = (index, decorator) => (target, key) => decorator(target, key, index);
|
|
13
|
+
|
|
14
|
+
// packages/auth/shell/app-services/src/lib/services/auth/auth.service.ts
|
|
15
|
+
import { Injectable as Injectable3, Logger } from "@nestjs/common";
|
|
16
|
+
|
|
17
|
+
// packages/auth/domain/src/lib/entities/user.entity.ts
|
|
18
|
+
import { Column, Entity, PrimaryGeneratedColumn } from "typeorm";
|
|
19
|
+
var User = class {
|
|
20
|
+
};
|
|
21
|
+
__decorateClass([
|
|
22
|
+
PrimaryGeneratedColumn()
|
|
23
|
+
], User.prototype, "id", 2);
|
|
24
|
+
__decorateClass([
|
|
25
|
+
Column("permissions")
|
|
26
|
+
], User.prototype, "permissions", 2);
|
|
27
|
+
__decorateClass([
|
|
28
|
+
Column("username")
|
|
29
|
+
], User.prototype, "username", 2);
|
|
30
|
+
__decorateClass([
|
|
31
|
+
Column("password")
|
|
32
|
+
], User.prototype, "password", 2);
|
|
33
|
+
__decorateClass([
|
|
34
|
+
Column("disabled")
|
|
35
|
+
], User.prototype, "disabled", 2);
|
|
36
|
+
__decorateClass([
|
|
37
|
+
Column("lastLoginDate")
|
|
38
|
+
], User.prototype, "lastLoginDate", 2);
|
|
39
|
+
__decorateClass([
|
|
40
|
+
Column("authRefreshToken")
|
|
41
|
+
], User.prototype, "authRefreshToken", 2);
|
|
42
|
+
__decorateClass([
|
|
43
|
+
Column("facebookUserId")
|
|
44
|
+
], User.prototype, "facebookUserId", 2);
|
|
45
|
+
__decorateClass([
|
|
46
|
+
Column("googleUserId")
|
|
47
|
+
], User.prototype, "googleUserId", 2);
|
|
48
|
+
User = __decorateClass([
|
|
49
|
+
Entity("users")
|
|
50
|
+
], User);
|
|
51
|
+
|
|
52
|
+
// packages/auth/domain/src/lib/feature-create-token/token.factory.ts
|
|
53
|
+
import { Injectable } from "@nestjs/common";
|
|
54
|
+
import { InjectRepository } from "@nestjs/typeorm";
|
|
55
|
+
import { Guid as Guid2 } from "guid-typescript";
|
|
56
|
+
|
|
57
|
+
// packages/shared/models/src/lib/symbols.ts
|
|
58
|
+
var SYMBOL_MODEL = Symbol.for("smartsoft:model");
|
|
59
|
+
var SYMBOL_FIELD = Symbol.for("smartsoft:field");
|
|
60
|
+
|
|
61
|
+
// packages/shared/models/src/lib/decorators/model/model.decorator.ts
|
|
62
|
+
import "reflect-metadata";
|
|
63
|
+
|
|
64
|
+
// packages/shared/models/src/lib/decorators/field/field.decorator.ts
|
|
65
|
+
import "reflect-metadata";
|
|
66
|
+
|
|
67
|
+
// packages/shared/utils/src/lib/services/password/password.service.ts
|
|
68
|
+
import * as md5_ from "md5";
|
|
69
|
+
var md5 = md5_;
|
|
70
|
+
var PasswordService = class _PasswordService {
|
|
71
|
+
/**
|
|
72
|
+
* Hash password text
|
|
73
|
+
* @param p {string} - text
|
|
74
|
+
* @return - hashed text
|
|
75
|
+
*/
|
|
76
|
+
static hash(p) {
|
|
77
|
+
return Promise.resolve(md5(p));
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Compare password text with hashed text
|
|
81
|
+
* @param p {string} - password text
|
|
82
|
+
* @param h {string} - hashed text
|
|
83
|
+
*/
|
|
84
|
+
static async compare(p, h) {
|
|
85
|
+
const hp = await _PasswordService.hash(p);
|
|
86
|
+
return hp === h;
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
// packages/shared/utils/src/lib/services/object/object.service.ts
|
|
91
|
+
import { stringify } from "flatted";
|
|
92
|
+
|
|
93
|
+
// packages/shared/utils/src/lib/services/guid/guid.service.ts
|
|
94
|
+
import { Guid } from "guid-typescript";
|
|
95
|
+
|
|
96
|
+
// packages/shared/utils/src/lib/services/array/array.service.ts
|
|
97
|
+
import * as _ from "lodash";
|
|
98
|
+
|
|
99
|
+
// packages/shared/domain-core/src/lib/errors.ts
|
|
100
|
+
var DomainValidationError = class _DomainValidationError extends Error {
|
|
101
|
+
constructor(msg) {
|
|
102
|
+
super(msg);
|
|
103
|
+
this.type = _DomainValidationError;
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
// packages/auth/domain/src/lib/feature-create-token/token.factory.ts
|
|
108
|
+
var TokenFactory = class {
|
|
109
|
+
constructor(config, repository, jwtService, fbService, googleService) {
|
|
110
|
+
this.config = config;
|
|
111
|
+
this.repository = repository;
|
|
112
|
+
this.jwtService = jwtService;
|
|
113
|
+
this.fbService = fbService;
|
|
114
|
+
this.googleService = googleService;
|
|
115
|
+
this._invalidUsernameOrPasswordMessage = "Invalid username or password";
|
|
116
|
+
}
|
|
117
|
+
static getQuery(config, customProvider = false) {
|
|
118
|
+
switch (config.grant_type) {
|
|
119
|
+
case "fb":
|
|
120
|
+
return { facebookUserId: config.fb_user_id };
|
|
121
|
+
case "google":
|
|
122
|
+
return { googleUserId: config.google_user_id };
|
|
123
|
+
case "password":
|
|
124
|
+
return { username: config.username };
|
|
125
|
+
case "refresh_token":
|
|
126
|
+
return { authRefreshToken: config.refresh_token };
|
|
127
|
+
default:
|
|
128
|
+
if (!customProvider) {
|
|
129
|
+
throw new DomainValidationError("Invalid grand type");
|
|
130
|
+
}
|
|
131
|
+
return null;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
static checkDisabled(user) {
|
|
135
|
+
if (user.disabled)
|
|
136
|
+
throw new DomainValidationError("user disabled");
|
|
137
|
+
}
|
|
138
|
+
async create(options) {
|
|
139
|
+
if (options.request.grant_type === "fb") {
|
|
140
|
+
options.request.fb_user_id = await this.fbService.getUserId(
|
|
141
|
+
options.request.fb_token
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
if (options.request.grant_type === "google") {
|
|
145
|
+
options.request.google_user_id = await this.googleService.getUserId(
|
|
146
|
+
options.request.google_token
|
|
147
|
+
);
|
|
148
|
+
}
|
|
149
|
+
this.valid(options.request);
|
|
150
|
+
const query = TokenFactory.getQuery(
|
|
151
|
+
options.request,
|
|
152
|
+
!!options.userProvider
|
|
153
|
+
);
|
|
154
|
+
const user = options.userProvider ? await options.userProvider.get(query, options.request, options.httpReq) : await this.repository.findOne(query);
|
|
155
|
+
if (!options.validationProvider || !options.validationProvider.replace) {
|
|
156
|
+
this.checkUser(options.request, user);
|
|
157
|
+
TokenFactory.checkDisabled(user);
|
|
158
|
+
await this.checkPassword(options.request, user);
|
|
159
|
+
}
|
|
160
|
+
if (options.validationProvider) {
|
|
161
|
+
await options.validationProvider.check({
|
|
162
|
+
request: options.request,
|
|
163
|
+
user
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
const refreshToken = Guid2.raw();
|
|
167
|
+
await this.repository.update(
|
|
168
|
+
{
|
|
169
|
+
...query,
|
|
170
|
+
disabled: { $ne: true }
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
lastLoginDate: /* @__PURE__ */ new Date(),
|
|
174
|
+
authRefreshToken: refreshToken
|
|
175
|
+
}
|
|
176
|
+
);
|
|
177
|
+
const payload = {
|
|
178
|
+
permissions: user.permissions,
|
|
179
|
+
scope: options.request.scope
|
|
180
|
+
};
|
|
181
|
+
if (options.payloadProvider) {
|
|
182
|
+
await options.payloadProvider.change(payload, {
|
|
183
|
+
user,
|
|
184
|
+
request: options.request,
|
|
185
|
+
httpReq: options.httpReq
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
return {
|
|
189
|
+
expired_in: this.config.expiredIn,
|
|
190
|
+
token_type: "bearer",
|
|
191
|
+
access_token: this.jwtService.sign(payload, {
|
|
192
|
+
expiresIn: this.config.expiredIn,
|
|
193
|
+
subject: user.username
|
|
194
|
+
}),
|
|
195
|
+
refresh_token: refreshToken,
|
|
196
|
+
username: user.username
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
checkUser(config, user) {
|
|
200
|
+
if (!user)
|
|
201
|
+
throw new DomainValidationError(
|
|
202
|
+
config.grant_type === "password" ? this._invalidUsernameOrPasswordMessage : "Invalid token"
|
|
203
|
+
);
|
|
204
|
+
}
|
|
205
|
+
async checkPassword(config, user) {
|
|
206
|
+
if (config.grant_type === "password" && !await PasswordService.compare(config.password, user.password))
|
|
207
|
+
throw new DomainValidationError(this._invalidUsernameOrPasswordMessage);
|
|
208
|
+
}
|
|
209
|
+
valid(req) {
|
|
210
|
+
if (!req)
|
|
211
|
+
throw new DomainValidationError("config is empty");
|
|
212
|
+
if (!req.grant_type)
|
|
213
|
+
throw new DomainValidationError("grant_type is empty");
|
|
214
|
+
if (req.grant_type === "password") {
|
|
215
|
+
if (!req.username)
|
|
216
|
+
throw new DomainValidationError("username is empty");
|
|
217
|
+
if (!req.password)
|
|
218
|
+
throw new DomainValidationError("password is empty");
|
|
219
|
+
if (!req.client_id)
|
|
220
|
+
throw new DomainValidationError("client_id is empty");
|
|
221
|
+
if (!this.config.clients.some((c) => c === req.client_id))
|
|
222
|
+
throw new DomainValidationError("client_id is incorrect");
|
|
223
|
+
} else if (req.grant_type === "refresh_token") {
|
|
224
|
+
if (!req.refresh_token)
|
|
225
|
+
throw new DomainValidationError("refresh_token is empty");
|
|
226
|
+
} else if (req.grant_type === "fb") {
|
|
227
|
+
if (!req.fb_token)
|
|
228
|
+
throw new DomainValidationError("fb_token is empty");
|
|
229
|
+
if (!req.fb_user_id)
|
|
230
|
+
throw new DomainValidationError("fb_user_id is empty");
|
|
231
|
+
} else if (req.grant_type === "google") {
|
|
232
|
+
if (!req.google_token)
|
|
233
|
+
throw new DomainValidationError("google_token is empty");
|
|
234
|
+
if (!req.google_user_id)
|
|
235
|
+
throw new DomainValidationError("google_user_id is empty");
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
};
|
|
239
|
+
TokenFactory = __decorateClass([
|
|
240
|
+
Injectable(),
|
|
241
|
+
__decorateParam(1, InjectRepository(User))
|
|
242
|
+
], TokenFactory);
|
|
243
|
+
|
|
244
|
+
// packages/auth/domain/src/lib/feature-create-token/token.config.ts
|
|
245
|
+
import { Injectable as Injectable2 } from "@nestjs/common";
|
|
246
|
+
var TokenConfig = class {
|
|
247
|
+
constructor() {
|
|
248
|
+
this.clients = [];
|
|
249
|
+
}
|
|
250
|
+
};
|
|
251
|
+
TokenConfig = __decorateClass([
|
|
252
|
+
Injectable2()
|
|
253
|
+
], TokenConfig);
|
|
254
|
+
|
|
255
|
+
// packages/auth/domain/src/lib/feature-create-token/token-payload.provider.ts
|
|
256
|
+
var AUTH_TOKEN_PAYLOAD_PROVIDER = "AUTH_TOKEN_PAYLOAD_PROVIDER";
|
|
257
|
+
|
|
258
|
+
// packages/auth/domain/src/lib/feature-create-token/token-validation.provider.ts
|
|
259
|
+
var AUTH_TOKEN_VALIDATION_PROVIDER = "AUTH_TOKEN_VALIDATION_PROVIDER";
|
|
260
|
+
|
|
261
|
+
// packages/auth/domain/src/lib/feature-create-token/token-user.provider.ts
|
|
262
|
+
var AUTH_TOKEN_USER_PROVIDER = "AUTH_TOKEN_USER_PROVIDER";
|
|
263
|
+
|
|
264
|
+
// packages/auth/shell/app-services/src/lib/services/auth/auth.service.ts
|
|
265
|
+
var AuthService = class {
|
|
266
|
+
constructor(factory, moduleRef) {
|
|
267
|
+
this.factory = factory;
|
|
268
|
+
this.moduleRef = moduleRef;
|
|
269
|
+
}
|
|
270
|
+
create(req, httpReq) {
|
|
271
|
+
return this.factory.create({
|
|
272
|
+
httpReq,
|
|
273
|
+
request: req,
|
|
274
|
+
payloadProvider: this.getPayloadProvider(),
|
|
275
|
+
validationProvider: this.getValidationProvider(),
|
|
276
|
+
userProvider: this.getUserProvider()
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
getPayloadProvider() {
|
|
280
|
+
try {
|
|
281
|
+
return this.moduleRef.get(AUTH_TOKEN_PAYLOAD_PROVIDER, {
|
|
282
|
+
strict: false
|
|
283
|
+
});
|
|
284
|
+
} catch (e) {
|
|
285
|
+
Logger.debug(e.message, AuthService.name);
|
|
286
|
+
}
|
|
287
|
+
return null;
|
|
288
|
+
}
|
|
289
|
+
getValidationProvider() {
|
|
290
|
+
try {
|
|
291
|
+
return this.moduleRef.get(AUTH_TOKEN_VALIDATION_PROVIDER, {
|
|
292
|
+
strict: false
|
|
293
|
+
});
|
|
294
|
+
} catch (e) {
|
|
295
|
+
Logger.debug(e.message, AuthService.name);
|
|
296
|
+
}
|
|
297
|
+
return null;
|
|
298
|
+
}
|
|
299
|
+
getUserProvider() {
|
|
300
|
+
try {
|
|
301
|
+
return this.moduleRef.get(AUTH_TOKEN_USER_PROVIDER, {
|
|
302
|
+
strict: false
|
|
303
|
+
});
|
|
304
|
+
} catch (e) {
|
|
305
|
+
Logger.debug(e.message, AuthService.name);
|
|
306
|
+
}
|
|
307
|
+
return null;
|
|
308
|
+
}
|
|
309
|
+
};
|
|
310
|
+
AuthService = __decorateClass([
|
|
311
|
+
Injectable3()
|
|
312
|
+
], AuthService);
|
|
313
|
+
export {
|
|
314
|
+
AuthService
|
|
315
|
+
};
|
package/package.json
CHANGED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { ModuleRef } from '@nestjs/core';
|
|
2
|
+
import { Request } from 'express';
|
|
3
|
+
import { IAuthToken, IAuthTokenRequest, TokenFactory } from '@smartsoft001/auth-domain';
|
|
4
|
+
export declare class AuthService {
|
|
5
|
+
private factory;
|
|
6
|
+
private moduleRef;
|
|
7
|
+
constructor(factory: TokenFactory, moduleRef: ModuleRef);
|
|
8
|
+
create(req: IAuthTokenRequest, httpReq?: Request): Promise<IAuthToken>;
|
|
9
|
+
private getPayloadProvider;
|
|
10
|
+
private getValidationProvider;
|
|
11
|
+
private getUserProvider;
|
|
12
|
+
}
|
package/.eslintrc.json
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"extends": "../../../../.eslintrc.json",
|
|
3
|
-
"ignorePatterns": ["!**/*"],
|
|
4
|
-
"rules": {
|
|
5
|
-
"import/order": "off"
|
|
6
|
-
},
|
|
7
|
-
"overrides": [
|
|
8
|
-
{
|
|
9
|
-
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
|
|
10
|
-
"rules": {}
|
|
11
|
-
},
|
|
12
|
-
{
|
|
13
|
-
"files": ["*.ts", "*.tsx"],
|
|
14
|
-
"rules": {}
|
|
15
|
-
},
|
|
16
|
-
{
|
|
17
|
-
"files": ["*.js", "*.jsx"],
|
|
18
|
-
"rules": {}
|
|
19
|
-
},
|
|
20
|
-
{
|
|
21
|
-
"files": "package.json",
|
|
22
|
-
"parser": "jsonc-eslint-parser",
|
|
23
|
-
"rules": {}
|
|
24
|
-
}
|
|
25
|
-
]
|
|
26
|
-
}
|
package/jest.config.ts
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
/* eslint-disable */
|
|
2
|
-
export default {
|
|
3
|
-
displayName: 'auth-shell-app-services',
|
|
4
|
-
preset: '../../../../jest.preset.js',
|
|
5
|
-
testEnvironment: 'node',
|
|
6
|
-
transform: {
|
|
7
|
-
'^.+\\.[tj]sx?$': [
|
|
8
|
-
'ts-jest',
|
|
9
|
-
{
|
|
10
|
-
tsConfig: '<rootDir>/tsconfig.spec.json',
|
|
11
|
-
},
|
|
12
|
-
],
|
|
13
|
-
},
|
|
14
|
-
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'],
|
|
15
|
-
coverageDirectory: '../../../../coverage/packages/auth/shell/app-services',
|
|
16
|
-
/* TODO: Update to latest Jest snapshotFormat
|
|
17
|
-
* By default Nx has kept the older style of Jest Snapshot formats
|
|
18
|
-
* to prevent breaking of any existing tests with snapshots.
|
|
19
|
-
* It's recommend you update to the latest format.
|
|
20
|
-
* You can do this by removing snapshotFormat property
|
|
21
|
-
* and running tests with --update-snapshot flag.
|
|
22
|
-
* Example: From within the project directory, run "nx test --update-snapshot"
|
|
23
|
-
* More info: https://jestjs.io/docs/upgrading-to-jest29#snapshot-format
|
|
24
|
-
*/
|
|
25
|
-
snapshotFormat: { escapeString: true, printBasicPrototype: true },
|
|
26
|
-
};
|
package/project.json
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "auth-shell-app-services",
|
|
3
|
-
"$schema": "../../../../node_modules/nx/schemas/project-schema.json",
|
|
4
|
-
"sourceRoot": "packages/auth/shell/app-services/src",
|
|
5
|
-
"projectType": "library",
|
|
6
|
-
"targets": {
|
|
7
|
-
"lint": {
|
|
8
|
-
"executor": "@nx/eslint:lint",
|
|
9
|
-
"outputs": ["{options.outputFile}"],
|
|
10
|
-
"options": {
|
|
11
|
-
"lintFilePatterns": [
|
|
12
|
-
"packages/auth/shell/app-services/**/*.{ts,tsx,js,jsx}",
|
|
13
|
-
"packages/auth/shell/app-services/package.json"
|
|
14
|
-
]
|
|
15
|
-
}
|
|
16
|
-
},
|
|
17
|
-
"test": {
|
|
18
|
-
"executor": "@nx/jest:jest",
|
|
19
|
-
"outputs": ["{workspaceRoot}/coverage/packages/auth/shell/app-services"],
|
|
20
|
-
"options": {
|
|
21
|
-
"jestConfig": "packages/auth/shell/app-services/jest.config.ts"
|
|
22
|
-
}
|
|
23
|
-
},
|
|
24
|
-
"build": {
|
|
25
|
-
"executor": "@nx/esbuild:esbuild",
|
|
26
|
-
"outputs": ["{options.outputPath}"],
|
|
27
|
-
"options": {
|
|
28
|
-
"outputPath": "dist/packages/auth/shell/app-services",
|
|
29
|
-
"tsConfig": "packages/auth/shell/app-services/tsconfig.lib.json",
|
|
30
|
-
"packageJson": "packages/auth/shell/app-services/package.json",
|
|
31
|
-
"main": "packages/auth/shell/app-services/src/index.ts",
|
|
32
|
-
"assets": ["packages/auth/shell/app-services/*.md"]
|
|
33
|
-
}
|
|
34
|
-
},
|
|
35
|
-
"deploy": {
|
|
36
|
-
"executor": "ngx-deploy-npm:deploy",
|
|
37
|
-
"options": {
|
|
38
|
-
"access": "public",
|
|
39
|
-
"distFolderPath": "dist/packages/auth/shell/app-services"
|
|
40
|
-
},
|
|
41
|
-
"dependsOn": ["build"]
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
}
|
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
import { ModuleRef } from '@nestjs/core';
|
|
2
|
-
import { Test, TestingModule } from '@nestjs/testing';
|
|
3
|
-
import { Request } from 'express';
|
|
4
|
-
|
|
5
|
-
import {
|
|
6
|
-
AUTH_TOKEN_PAYLOAD_PROVIDER,
|
|
7
|
-
AUTH_TOKEN_USER_PROVIDER,
|
|
8
|
-
AUTH_TOKEN_VALIDATION_PROVIDER,
|
|
9
|
-
IAuthToken,
|
|
10
|
-
TokenFactory,
|
|
11
|
-
} from '@smartsoft001/auth-domain';
|
|
12
|
-
|
|
13
|
-
import { AuthService } from './auth.service';
|
|
14
|
-
|
|
15
|
-
describe('auth-shell-app-services: AuthService', () => {
|
|
16
|
-
let service: AuthService;
|
|
17
|
-
let moduleRef: ModuleRef;
|
|
18
|
-
let tokenFactory: TokenFactory;
|
|
19
|
-
|
|
20
|
-
beforeEach(async () => {
|
|
21
|
-
const module: TestingModule = await Test.createTestingModule({
|
|
22
|
-
providers: [
|
|
23
|
-
AuthService,
|
|
24
|
-
{
|
|
25
|
-
provide: TokenFactory,
|
|
26
|
-
useValue: {
|
|
27
|
-
create: jest.fn(),
|
|
28
|
-
},
|
|
29
|
-
},
|
|
30
|
-
{
|
|
31
|
-
provide: ModuleRef,
|
|
32
|
-
useValue: {
|
|
33
|
-
get: jest.fn(),
|
|
34
|
-
},
|
|
35
|
-
},
|
|
36
|
-
],
|
|
37
|
-
}).compile();
|
|
38
|
-
|
|
39
|
-
service = module.get<AuthService>(AuthService);
|
|
40
|
-
moduleRef = module.get<ModuleRef>(ModuleRef);
|
|
41
|
-
tokenFactory = module.get<TokenFactory>(TokenFactory);
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
describe('create', () => {
|
|
45
|
-
it('should call TokenFactory.create with correct parameters when no providers are available', async () => {
|
|
46
|
-
const request = { grant_type: 'password' };
|
|
47
|
-
const httpReq = {} as Request;
|
|
48
|
-
const expectedToken = { token_type: 'bearer' } as IAuthToken;
|
|
49
|
-
|
|
50
|
-
(moduleRef.get as jest.Mock).mockImplementation(() => {
|
|
51
|
-
throw new Error('Not found');
|
|
52
|
-
});
|
|
53
|
-
(tokenFactory.create as jest.Mock).mockResolvedValue(expectedToken);
|
|
54
|
-
|
|
55
|
-
const result = await service.create(request, httpReq);
|
|
56
|
-
|
|
57
|
-
expect(result).toEqual(expectedToken);
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
it('should include payload provider when available', async () => {
|
|
61
|
-
const request = { grant_type: 'password' };
|
|
62
|
-
const payloadProvider = { change: jest.fn() };
|
|
63
|
-
|
|
64
|
-
(moduleRef.get as jest.Mock).mockImplementation((token) => {
|
|
65
|
-
if (token === AUTH_TOKEN_PAYLOAD_PROVIDER) {
|
|
66
|
-
return payloadProvider;
|
|
67
|
-
}
|
|
68
|
-
throw new Error('Not found');
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
await service.create(request);
|
|
72
|
-
|
|
73
|
-
expect(
|
|
74
|
-
(tokenFactory.create as jest.Mock).mock.calls[0][0].payloadProvider,
|
|
75
|
-
).toBe(payloadProvider);
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
it('should include validation provider when available', async () => {
|
|
79
|
-
const request = { grant_type: 'password' };
|
|
80
|
-
const validationProvider = { check: jest.fn() };
|
|
81
|
-
|
|
82
|
-
(moduleRef.get as jest.Mock).mockImplementation((token) => {
|
|
83
|
-
if (token === AUTH_TOKEN_VALIDATION_PROVIDER) {
|
|
84
|
-
return validationProvider;
|
|
85
|
-
}
|
|
86
|
-
throw new Error('Not found');
|
|
87
|
-
});
|
|
88
|
-
|
|
89
|
-
await service.create(request);
|
|
90
|
-
|
|
91
|
-
expect(
|
|
92
|
-
(tokenFactory.create as jest.Mock).mock.calls[0][0].validationProvider,
|
|
93
|
-
).toBe(validationProvider);
|
|
94
|
-
});
|
|
95
|
-
|
|
96
|
-
it('should include user provider when available', async () => {
|
|
97
|
-
const request = { grant_type: 'password' };
|
|
98
|
-
const userProvider = { get: jest.fn() };
|
|
99
|
-
|
|
100
|
-
(moduleRef.get as jest.Mock).mockImplementation((token) => {
|
|
101
|
-
if (token === AUTH_TOKEN_USER_PROVIDER) {
|
|
102
|
-
return userProvider;
|
|
103
|
-
}
|
|
104
|
-
throw new Error('Not found');
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
await service.create(request);
|
|
108
|
-
|
|
109
|
-
expect(
|
|
110
|
-
(tokenFactory.create as jest.Mock).mock.calls[0][0].userProvider,
|
|
111
|
-
).toBe(userProvider);
|
|
112
|
-
});
|
|
113
|
-
});
|
|
114
|
-
});
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
import { Injectable, Logger } from '@nestjs/common';
|
|
2
|
-
import { ModuleRef } from '@nestjs/core';
|
|
3
|
-
import { Request } from 'express';
|
|
4
|
-
|
|
5
|
-
import {
|
|
6
|
-
AUTH_TOKEN_PAYLOAD_PROVIDER,
|
|
7
|
-
AUTH_TOKEN_USER_PROVIDER,
|
|
8
|
-
AUTH_TOKEN_VALIDATION_PROVIDER,
|
|
9
|
-
IAuthToken,
|
|
10
|
-
IAuthTokenRequest,
|
|
11
|
-
ITokenPayloadProvider,
|
|
12
|
-
ITokenUserProvider,
|
|
13
|
-
ITokenValidationProvider,
|
|
14
|
-
TokenFactory,
|
|
15
|
-
} from '@smartsoft001/auth-domain';
|
|
16
|
-
|
|
17
|
-
@Injectable()
|
|
18
|
-
export class AuthService {
|
|
19
|
-
constructor(
|
|
20
|
-
private factory: TokenFactory,
|
|
21
|
-
private moduleRef: ModuleRef,
|
|
22
|
-
) {}
|
|
23
|
-
|
|
24
|
-
create(req: IAuthTokenRequest, httpReq?: Request): Promise<IAuthToken> {
|
|
25
|
-
return this.factory.create({
|
|
26
|
-
httpReq: httpReq,
|
|
27
|
-
request: req,
|
|
28
|
-
payloadProvider: this.getPayloadProvider(),
|
|
29
|
-
validationProvider: this.getValidationProvider(),
|
|
30
|
-
userProvider: this.getUserProvider(),
|
|
31
|
-
}) as Promise<IAuthToken>;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
private getPayloadProvider(): ITokenPayloadProvider {
|
|
35
|
-
try {
|
|
36
|
-
return this.moduleRef.get(AUTH_TOKEN_PAYLOAD_PROVIDER, {
|
|
37
|
-
strict: false,
|
|
38
|
-
});
|
|
39
|
-
} catch (e) {
|
|
40
|
-
Logger.debug(e.message, AuthService.name);
|
|
41
|
-
}
|
|
42
|
-
return null;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
private getValidationProvider(): ITokenValidationProvider {
|
|
46
|
-
try {
|
|
47
|
-
return this.moduleRef.get(AUTH_TOKEN_VALIDATION_PROVIDER, {
|
|
48
|
-
strict: false,
|
|
49
|
-
});
|
|
50
|
-
} catch (e) {
|
|
51
|
-
Logger.debug(e.message, AuthService.name);
|
|
52
|
-
}
|
|
53
|
-
return null;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
private getUserProvider(): ITokenUserProvider {
|
|
57
|
-
try {
|
|
58
|
-
return this.moduleRef.get(AUTH_TOKEN_USER_PROVIDER, {
|
|
59
|
-
strict: false,
|
|
60
|
-
});
|
|
61
|
-
} catch (e) {
|
|
62
|
-
Logger.debug(e.message, AuthService.name);
|
|
63
|
-
}
|
|
64
|
-
return null;
|
|
65
|
-
}
|
|
66
|
-
}
|
package/tsconfig.json
DELETED
package/tsconfig.lib.json
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"extends": "./tsconfig.json",
|
|
3
|
-
"compilerOptions": {
|
|
4
|
-
"module": "commonjs",
|
|
5
|
-
"outDir": "../../../../dist/out-tsc",
|
|
6
|
-
"declaration": true,
|
|
7
|
-
"types": ["node"]
|
|
8
|
-
},
|
|
9
|
-
"exclude": ["**/*.spec.ts", "**/*.test.ts", "jest.config.ts"],
|
|
10
|
-
"include": ["**/*.ts"]
|
|
11
|
-
}
|
package/tsconfig.spec.json
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"extends": "./tsconfig.json",
|
|
3
|
-
"compilerOptions": {
|
|
4
|
-
"outDir": "../../../../dist/out-tsc",
|
|
5
|
-
"module": "commonjs",
|
|
6
|
-
"types": ["jest", "node"]
|
|
7
|
-
},
|
|
8
|
-
"include": [
|
|
9
|
-
"**/*.spec.ts",
|
|
10
|
-
"**/*.test.ts",
|
|
11
|
-
"**/*.spec.tsx",
|
|
12
|
-
"**/*.test.tsx",
|
|
13
|
-
"**/*.spec.js",
|
|
14
|
-
"**/*.test.js",
|
|
15
|
-
"**/*.spec.jsx",
|
|
16
|
-
"**/*.test.jsx",
|
|
17
|
-
"**/*.d.ts",
|
|
18
|
-
"jest.config.ts"
|
|
19
|
-
]
|
|
20
|
-
}
|
|
File without changes
|
|
File without changes
|