@flowerforce/flowerbase 1.2.0 → 1.2.1-beta.10
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 +28 -3
- package/dist/auth/controller.d.ts.map +1 -1
- package/dist/auth/controller.js +57 -3
- package/dist/auth/plugins/jwt.d.ts.map +1 -1
- package/dist/auth/plugins/jwt.js +49 -3
- package/dist/auth/providers/custom-function/controller.d.ts.map +1 -1
- package/dist/auth/providers/custom-function/controller.js +19 -3
- package/dist/auth/providers/local-userpass/controller.d.ts.map +1 -1
- package/dist/auth/providers/local-userpass/controller.js +125 -71
- package/dist/auth/providers/local-userpass/dtos.d.ts +11 -2
- package/dist/auth/providers/local-userpass/dtos.d.ts.map +1 -1
- package/dist/auth/utils.d.ts +53 -14
- package/dist/auth/utils.d.ts.map +1 -1
- package/dist/auth/utils.js +46 -63
- package/dist/constants.d.ts +13 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +14 -2
- package/dist/features/functions/controller.d.ts.map +1 -1
- package/dist/features/functions/controller.js +32 -3
- package/dist/features/functions/dtos.d.ts +3 -0
- package/dist/features/functions/dtos.d.ts.map +1 -1
- package/dist/features/functions/interface.d.ts +3 -0
- package/dist/features/functions/interface.d.ts.map +1 -1
- package/dist/features/functions/utils.d.ts +2 -1
- package/dist/features/functions/utils.d.ts.map +1 -1
- package/dist/features/functions/utils.js +19 -7
- package/dist/features/rules/utils.d.ts.map +1 -1
- package/dist/features/rules/utils.js +11 -2
- package/dist/features/triggers/index.d.ts.map +1 -1
- package/dist/features/triggers/index.js +48 -7
- package/dist/features/triggers/utils.d.ts.map +1 -1
- package/dist/features/triggers/utils.js +118 -27
- package/dist/index.d.ts +8 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +57 -21
- package/dist/services/mongodb-atlas/index.d.ts.map +1 -1
- package/dist/services/mongodb-atlas/index.js +605 -478
- package/dist/services/mongodb-atlas/model.d.ts +2 -1
- package/dist/services/mongodb-atlas/model.d.ts.map +1 -1
- package/dist/services/mongodb-atlas/utils.d.ts +9 -2
- package/dist/services/mongodb-atlas/utils.d.ts.map +1 -1
- package/dist/services/mongodb-atlas/utils.js +113 -23
- package/dist/shared/handleUserRegistration.d.ts.map +1 -1
- package/dist/shared/handleUserRegistration.js +1 -0
- package/dist/shared/models/handleUserRegistration.model.d.ts +6 -2
- package/dist/shared/models/handleUserRegistration.model.d.ts.map +1 -1
- package/dist/utils/context/helpers.d.ts +7 -6
- package/dist/utils/context/helpers.d.ts.map +1 -1
- package/dist/utils/context/helpers.js +3 -0
- package/dist/utils/context/index.d.ts +1 -1
- package/dist/utils/context/index.d.ts.map +1 -1
- package/dist/utils/context/index.js +176 -5
- package/dist/utils/context/interface.d.ts +1 -1
- package/dist/utils/context/interface.d.ts.map +1 -1
- package/dist/utils/crypto/index.d.ts +1 -0
- package/dist/utils/crypto/index.d.ts.map +1 -1
- package/dist/utils/crypto/index.js +6 -2
- package/dist/utils/initializer/exposeRoutes.d.ts.map +1 -1
- package/dist/utils/initializer/exposeRoutes.js +11 -4
- package/dist/utils/initializer/registerPlugins.d.ts +3 -1
- package/dist/utils/initializer/registerPlugins.d.ts.map +1 -1
- package/dist/utils/initializer/registerPlugins.js +9 -6
- package/dist/utils/roles/helpers.js +11 -3
- package/dist/utils/roles/machines/commonValidators.d.ts.map +1 -1
- package/dist/utils/roles/machines/commonValidators.js +10 -6
- package/dist/utils/roles/machines/read/B/validators.d.ts +4 -0
- package/dist/utils/roles/machines/read/B/validators.d.ts.map +1 -0
- package/dist/utils/roles/machines/read/B/validators.js +8 -0
- package/dist/utils/roles/machines/read/C/index.d.ts.map +1 -1
- package/dist/utils/roles/machines/read/C/index.js +10 -7
- package/dist/utils/roles/machines/read/C/validators.d.ts +5 -0
- package/dist/utils/roles/machines/read/C/validators.d.ts.map +1 -0
- package/dist/utils/roles/machines/read/C/validators.js +29 -0
- package/dist/utils/roles/machines/read/D/index.d.ts.map +1 -1
- package/dist/utils/roles/machines/read/D/index.js +13 -11
- package/dist/utils/rules.d.ts +1 -1
- package/dist/utils/rules.d.ts.map +1 -1
- package/dist/utils/rules.js +26 -17
- package/jest.config.ts +2 -12
- package/jest.setup.ts +28 -0
- package/package.json +1 -2
- package/src/auth/controller.ts +70 -4
- package/src/auth/plugins/jwt.test.ts +93 -0
- package/src/auth/plugins/jwt.ts +62 -3
- package/src/auth/providers/custom-function/controller.ts +22 -5
- package/src/auth/providers/local-userpass/controller.ts +168 -96
- package/src/auth/providers/local-userpass/dtos.ts +13 -2
- package/src/auth/utils.ts +51 -86
- package/src/constants.ts +16 -3
- package/src/fastify.d.ts +32 -15
- package/src/features/functions/controller.ts +51 -3
- package/src/features/functions/dtos.ts +3 -0
- package/src/features/functions/interface.ts +3 -0
- package/src/features/functions/utils.ts +29 -8
- package/src/features/rules/utils.ts +11 -2
- package/src/features/triggers/index.ts +43 -1
- package/src/features/triggers/utils.ts +146 -38
- package/src/index.ts +69 -20
- package/src/services/mongodb-atlas/__tests__/findOneAndUpdate.test.ts +95 -0
- package/src/services/mongodb-atlas/__tests__/utils.test.ts +141 -0
- package/src/services/mongodb-atlas/index.ts +241 -90
- package/src/services/mongodb-atlas/model.ts +15 -2
- package/src/services/mongodb-atlas/utils.ts +158 -22
- package/src/shared/handleUserRegistration.ts +3 -3
- package/src/shared/models/handleUserRegistration.model.ts +8 -3
- package/src/types/fastify-raw-body.d.ts +22 -0
- package/src/utils/__tests__/STEP_B_STATES.test.ts +1 -1
- package/src/utils/__tests__/STEP_C_STATES.test.ts +1 -1
- package/src/utils/__tests__/STEP_D_STATES.test.ts +2 -2
- package/src/utils/__tests__/checkIsValidFieldNameFn.test.ts +9 -4
- package/src/utils/__tests__/registerPlugins.test.ts +16 -1
- package/src/utils/context/helpers.ts +3 -0
- package/src/utils/context/index.ts +238 -13
- package/src/utils/context/interface.ts +1 -1
- package/src/utils/crypto/index.ts +5 -1
- package/src/utils/initializer/exposeRoutes.ts +15 -8
- package/src/utils/initializer/registerPlugins.ts +15 -7
- package/src/utils/roles/helpers.ts +23 -5
- package/src/utils/roles/machines/commonValidators.ts +10 -5
- package/src/utils/roles/machines/read/B/validators.ts +8 -0
- package/src/utils/roles/machines/read/C/index.ts +11 -7
- package/src/utils/roles/machines/read/C/validators.ts +21 -0
- package/src/utils/roles/machines/read/D/index.ts +22 -12
- package/src/utils/rules.ts +31 -22
- package/tsconfig.spec.json +7 -0
package/README.md
CHANGED
|
@@ -96,6 +96,13 @@ Ensure the following environment variables are set in your .env file or deployme
|
|
|
96
96
|
| `APP_SECRET` | Secret used to sign and verify JWT tokens (choose a strong secret). | `supersecretkey123!` |
|
|
97
97
|
| `HOST` | The host address the server binds to (usually `0.0.0.0` for public access). | `0.0.0.0` |
|
|
98
98
|
| `HTTPS_SCHEMA` | The schema for your server requests (usually `https` or `http`). | `http` |
|
|
99
|
+
| `RESET_PASSWORD_TTL_SECONDS` | Time-to-live for password reset tokens (in seconds). | `3600` |
|
|
100
|
+
| `AUTH_RATE_LIMIT_WINDOW_MS` | Rate limit window for auth endpoints (in ms). | `900000` |
|
|
101
|
+
| `AUTH_LOGIN_MAX_ATTEMPTS` | Max login attempts per window. | `10` |
|
|
102
|
+
| `AUTH_RESET_MAX_ATTEMPTS` | Max reset requests per window. | `5` |
|
|
103
|
+
| `REFRESH_TOKEN_TTL_DAYS` | Refresh token time-to-live (in days). | `60` |
|
|
104
|
+
| `SWAGGER_UI_USER` | Basic Auth username for Swagger UI (optional). | `admin` |
|
|
105
|
+
| `SWAGGER_UI_PASSWORD` | Basic Auth password for Swagger UI (optional). | `change-me` |
|
|
99
106
|
|
|
100
107
|
|
|
101
108
|
Example:
|
|
@@ -106,6 +113,13 @@ DB_CONNECTION_STRING=mongodb+srv://username:password@cluster.mongodb.net/dbname
|
|
|
106
113
|
APP_SECRET=your-jwt-secret
|
|
107
114
|
HOST=0.0.0.0
|
|
108
115
|
HTTPS_SCHEMA=http
|
|
116
|
+
RESET_PASSWORD_TTL_SECONDS=3600
|
|
117
|
+
AUTH_RATE_LIMIT_WINDOW_MS=900000
|
|
118
|
+
AUTH_LOGIN_MAX_ATTEMPTS=10
|
|
119
|
+
AUTH_RESET_MAX_ATTEMPTS=5
|
|
120
|
+
REFRESH_TOKEN_TTL_DAYS=60
|
|
121
|
+
SWAGGER_UI_USER=admin
|
|
122
|
+
SWAGGER_UI_PASSWORD=change-me
|
|
109
123
|
```
|
|
110
124
|
|
|
111
125
|
🛡️ Note: Never commit .env files to source control. Use a .gitignore file to exclude it.
|
|
@@ -406,6 +420,13 @@ Ensure the following environment variables are set in your .env file or deployme
|
|
|
406
420
|
| `APP_SECRET` | Secret used to sign and verify JWT tokens (choose a strong secret). | `supersecretkey123!` |
|
|
407
421
|
| `HOST` | The host address the server binds to (usually `0.0.0.0` for public access). | `0.0.0.0` |
|
|
408
422
|
| `HTTPS_SCHEMA` | The schema for your server requests (usually `https` or `http`). | `http` |
|
|
423
|
+
| `RESET_PASSWORD_TTL_SECONDS` | Time-to-live for password reset tokens (in seconds). | `3600` |
|
|
424
|
+
| `AUTH_RATE_LIMIT_WINDOW_MS` | Rate limit window for auth endpoints (in ms). | `900000` |
|
|
425
|
+
| `AUTH_LOGIN_MAX_ATTEMPTS` | Max login attempts per window. | `10` |
|
|
426
|
+
| `AUTH_RESET_MAX_ATTEMPTS` | Max reset requests per window. | `5` |
|
|
427
|
+
| `REFRESH_TOKEN_TTL_DAYS` | Refresh token time-to-live (in days). | `60` |
|
|
428
|
+
| `SWAGGER_UI_USER` | Basic Auth username for Swagger UI (optional). | `admin` |
|
|
429
|
+
| `SWAGGER_UI_PASSWORD` | Basic Auth password for Swagger UI (optional). | `change-me` |
|
|
409
430
|
|
|
410
431
|
|
|
411
432
|
Example:
|
|
@@ -416,6 +437,13 @@ DB_CONNECTION_STRING=mongodb+srv://username:password@cluster.mongodb.net/dbname
|
|
|
416
437
|
APP_SECRET=your-jwt-secret
|
|
417
438
|
HOST=0.0.0.0
|
|
418
439
|
HTTPS_SCHEMA=http
|
|
440
|
+
RESET_PASSWORD_TTL_SECONDS=3600
|
|
441
|
+
AUTH_RATE_LIMIT_WINDOW_MS=900000
|
|
442
|
+
AUTH_LOGIN_MAX_ATTEMPTS=10
|
|
443
|
+
AUTH_RESET_MAX_ATTEMPTS=5
|
|
444
|
+
REFRESH_TOKEN_TTL_DAYS=60
|
|
445
|
+
SWAGGER_UI_USER=admin
|
|
446
|
+
SWAGGER_UI_PASSWORD=change-me
|
|
419
447
|
```
|
|
420
448
|
|
|
421
449
|
🛡️ Note: Never commit .env files to source control. Use a .gitignore file to exclude it.
|
|
@@ -472,6 +500,3 @@ export default app;
|
|
|
472
500
|
|
|
473
501
|
>🔗 The baseUrl should point to the backend URL you deployed earlier using Flowerbase.
|
|
474
502
|
This tells the frontend SDK where to send authentication and data requests.
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"controller.d.ts","sourceRoot":"","sources":["../../src/auth/controller.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"controller.d.ts","sourceRoot":"","sources":["../../src/auth/controller.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAQzC;;;;GAIG;AACH,wBAAsB,cAAc,CAAC,GAAG,EAAE,eAAe,iBA4IxD"}
|
package/dist/auth/controller.js
CHANGED
|
@@ -13,6 +13,7 @@ exports.authController = authController;
|
|
|
13
13
|
const bson_1 = require("bson");
|
|
14
14
|
const constants_1 = require("../constants");
|
|
15
15
|
const utils_1 = require("./utils");
|
|
16
|
+
const crypto_1 = require("../utils/crypto");
|
|
16
17
|
const HANDLER_TYPE = 'preHandler';
|
|
17
18
|
/**
|
|
18
19
|
* Controller for handling user authentication, profile retrieval, and session management.
|
|
@@ -21,8 +22,15 @@ const HANDLER_TYPE = 'preHandler';
|
|
|
21
22
|
*/
|
|
22
23
|
function authController(app) {
|
|
23
24
|
return __awaiter(this, void 0, void 0, function* () {
|
|
24
|
-
const { authCollection, userCollection } = constants_1.AUTH_CONFIG;
|
|
25
|
+
const { authCollection, userCollection, refreshTokensCollection } = constants_1.AUTH_CONFIG;
|
|
25
26
|
const db = app.mongo.client.db(constants_1.DB_NAME);
|
|
27
|
+
const refreshTokenTtlMs = constants_1.DEFAULT_CONFIG.REFRESH_TOKEN_TTL_DAYS * 24 * 60 * 60 * 1000;
|
|
28
|
+
try {
|
|
29
|
+
yield db.collection(refreshTokensCollection).createIndex({ expiresAt: 1 }, { expireAfterSeconds: 0 });
|
|
30
|
+
}
|
|
31
|
+
catch (error) {
|
|
32
|
+
console.error('Failed to ensure refresh token TTL index', error);
|
|
33
|
+
}
|
|
26
34
|
app.addHook(HANDLER_TYPE, app.jwtAuthentication);
|
|
27
35
|
/**
|
|
28
36
|
* Endpoint to retrieve the authenticated user's profile.
|
|
@@ -33,6 +41,9 @@ function authController(app) {
|
|
|
33
41
|
*/
|
|
34
42
|
app.get(utils_1.AUTH_ENDPOINTS.PROFILE, function (req) {
|
|
35
43
|
return __awaiter(this, void 0, void 0, function* () {
|
|
44
|
+
if (req.user.typ !== 'access') {
|
|
45
|
+
throw new Error('Access token required');
|
|
46
|
+
}
|
|
36
47
|
const user = yield db
|
|
37
48
|
.collection(authCollection)
|
|
38
49
|
.findOne({ _id: bson_1.ObjectId.createFromHexString(req.user.id) });
|
|
@@ -61,6 +72,20 @@ function authController(app) {
|
|
|
61
72
|
if (req.user.typ !== 'refresh') {
|
|
62
73
|
throw new Error(utils_1.AUTH_ERRORS.INVALID_TOKEN);
|
|
63
74
|
}
|
|
75
|
+
const authHeader = req.headers.authorization;
|
|
76
|
+
if (!(authHeader === null || authHeader === void 0 ? void 0 : authHeader.startsWith('Bearer '))) {
|
|
77
|
+
throw new Error(utils_1.AUTH_ERRORS.INVALID_TOKEN);
|
|
78
|
+
}
|
|
79
|
+
const refreshToken = authHeader.slice('Bearer '.length).trim();
|
|
80
|
+
const refreshTokenHash = (0, crypto_1.hashToken)(refreshToken);
|
|
81
|
+
const storedToken = yield db.collection(refreshTokensCollection).findOne({
|
|
82
|
+
tokenHash: refreshTokenHash,
|
|
83
|
+
revokedAt: null,
|
|
84
|
+
expiresAt: { $gt: new Date() }
|
|
85
|
+
});
|
|
86
|
+
if (!storedToken) {
|
|
87
|
+
throw new Error(utils_1.AUTH_ERRORS.INVALID_TOKEN);
|
|
88
|
+
}
|
|
64
89
|
const auth_user = yield (db === null || db === void 0 ? void 0 : db.collection(authCollection).findOne({ _id: new this.mongo.ObjectId(req.user.sub) }));
|
|
65
90
|
if (!auth_user) {
|
|
66
91
|
throw new Error(`User with ID ${req.user.sub} not found`);
|
|
@@ -77,9 +102,38 @@ function authController(app) {
|
|
|
77
102
|
/**
|
|
78
103
|
* Endpoint to destroy the existing session.
|
|
79
104
|
*/
|
|
80
|
-
app.delete(utils_1.AUTH_ENDPOINTS.SESSION, function () {
|
|
105
|
+
app.delete(utils_1.AUTH_ENDPOINTS.SESSION, function (req, res) {
|
|
81
106
|
return __awaiter(this, void 0, void 0, function* () {
|
|
82
|
-
|
|
107
|
+
var _a, _b;
|
|
108
|
+
const authHeader = req.headers.authorization;
|
|
109
|
+
if (!(authHeader === null || authHeader === void 0 ? void 0 : authHeader.startsWith('Bearer '))) {
|
|
110
|
+
res.status(204);
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
const refreshToken = authHeader.slice('Bearer '.length).trim();
|
|
114
|
+
const refreshTokenHash = (0, crypto_1.hashToken)(refreshToken);
|
|
115
|
+
const now = new Date();
|
|
116
|
+
const expiresAt = new Date(Date.now() + refreshTokenTtlMs);
|
|
117
|
+
const updateResult = yield db.collection(refreshTokensCollection).findOneAndUpdate({ tokenHash: refreshTokenHash }, {
|
|
118
|
+
$set: {
|
|
119
|
+
revokedAt: now,
|
|
120
|
+
expiresAt
|
|
121
|
+
}
|
|
122
|
+
}, { returnDocument: 'after' });
|
|
123
|
+
const fromToken = (_a = req.user) === null || _a === void 0 ? void 0 : _a.sub;
|
|
124
|
+
let userId = (_b = updateResult === null || updateResult === void 0 ? void 0 : updateResult.value) === null || _b === void 0 ? void 0 : _b.userId;
|
|
125
|
+
if (!userId && fromToken) {
|
|
126
|
+
try {
|
|
127
|
+
userId = new bson_1.ObjectId(fromToken);
|
|
128
|
+
}
|
|
129
|
+
catch (_c) {
|
|
130
|
+
userId = fromToken;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
if (userId && authCollection) {
|
|
134
|
+
yield db.collection(authCollection).updateOne({ _id: userId }, { $set: { lastLogoutAt: now } });
|
|
135
|
+
}
|
|
136
|
+
return { status: 'ok' };
|
|
83
137
|
});
|
|
84
138
|
});
|
|
85
139
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"jwt.d.ts","sourceRoot":"","sources":["../../../src/auth/plugins/jwt.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"jwt.d.ts","sourceRoot":"","sources":["../../../src/auth/plugins/jwt.ts"],"names":[],"mappings":"AAKA,KAAK,OAAO,GAAG;IACb,MAAM,EAAE,MAAM,CAAA;CACf,CAAA;AAQD;;;;;;;GAOG;iUAC8C,OAAO;AAAxD,wBA4GE"}
|
package/dist/auth/plugins/jwt.js
CHANGED
|
@@ -15,6 +15,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
15
15
|
const jwt_1 = __importDefault(require("@fastify/jwt"));
|
|
16
16
|
const fastify_plugin_1 = __importDefault(require("fastify-plugin"));
|
|
17
17
|
const mongodb_1 = require("mongodb");
|
|
18
|
+
const constants_1 = require("../../constants");
|
|
18
19
|
/**
|
|
19
20
|
* This module is a Fastify plugin that sets up JWT-based authentication and token creation.
|
|
20
21
|
* It registers JWT authentication, and provides methods to create access and refresh tokens.
|
|
@@ -31,12 +32,57 @@ exports.default = (0, fastify_plugin_1.default)(function (fastify, opts) {
|
|
|
31
32
|
});
|
|
32
33
|
fastify.decorate('jwtAuthentication', function (request, reply) {
|
|
33
34
|
return __awaiter(this, void 0, void 0, function* () {
|
|
35
|
+
var _a, _b, _c;
|
|
34
36
|
try {
|
|
35
37
|
yield request.jwtVerify();
|
|
36
38
|
}
|
|
37
39
|
catch (err) {
|
|
38
|
-
|
|
39
|
-
reply.send(
|
|
40
|
+
fastify.log.warn({ err }, 'JWT authentication failed');
|
|
41
|
+
reply.code(401).send({ message: 'Unauthorized' });
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
if (((_a = request.user) === null || _a === void 0 ? void 0 : _a.typ) !== 'access') {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
const db = (_c = (_b = fastify.mongo) === null || _b === void 0 ? void 0 : _b.client) === null || _c === void 0 ? void 0 : _c.db(constants_1.DB_NAME);
|
|
48
|
+
if (!db) {
|
|
49
|
+
fastify.log.warn('Mongo client unavailable while checking logout state');
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
if (!request.user.sub) {
|
|
53
|
+
reply.code(401).send({ message: 'Unauthorized' });
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
let authUser;
|
|
57
|
+
try {
|
|
58
|
+
authUser = yield db
|
|
59
|
+
.collection(constants_1.AUTH_CONFIG.authCollection)
|
|
60
|
+
.findOne({ _id: new mongodb_1.ObjectId(request.user.sub) });
|
|
61
|
+
}
|
|
62
|
+
catch (err) {
|
|
63
|
+
fastify.log.warn({ err }, 'Failed to lookup user during JWT authentication');
|
|
64
|
+
reply.code(401).send({ message: 'Unauthorized' });
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
if (!authUser) {
|
|
68
|
+
reply.code(401).send({ message: 'Unauthorized' });
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
const lastLogoutAt = authUser.lastLogoutAt ? new Date(authUser.lastLogoutAt) : null;
|
|
72
|
+
const accessUser = request.user;
|
|
73
|
+
const rawIssuedAt = accessUser.iat;
|
|
74
|
+
const issuedAt = typeof rawIssuedAt === 'number'
|
|
75
|
+
? rawIssuedAt
|
|
76
|
+
: typeof rawIssuedAt === 'string'
|
|
77
|
+
? Number(rawIssuedAt)
|
|
78
|
+
: undefined;
|
|
79
|
+
if (lastLogoutAt &&
|
|
80
|
+
!Number.isNaN(lastLogoutAt.getTime()) &&
|
|
81
|
+
typeof issuedAt === 'number' &&
|
|
82
|
+
!Number.isNaN(issuedAt) &&
|
|
83
|
+
lastLogoutAt.getTime() >= issuedAt * 1000) {
|
|
84
|
+
reply.code(401).send({ message: 'Unauthorized' });
|
|
85
|
+
return;
|
|
40
86
|
}
|
|
41
87
|
});
|
|
42
88
|
});
|
|
@@ -63,7 +109,7 @@ exports.default = (0, fastify_plugin_1.default)(function (fastify, opts) {
|
|
|
63
109
|
baas_id: BAAS_ID
|
|
64
110
|
}, {
|
|
65
111
|
sub: user._id.toJSON(),
|
|
66
|
-
expiresIn:
|
|
112
|
+
expiresIn: `${constants_1.DEFAULT_CONFIG.REFRESH_TOKEN_TTL_DAYS}d`
|
|
67
113
|
});
|
|
68
114
|
});
|
|
69
115
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"controller.d.ts","sourceRoot":"","sources":["../../../../src/auth/providers/custom-function/controller.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"controller.d.ts","sourceRoot":"","sources":["../../../../src/auth/providers/custom-function/controller.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAgBzC;;;;GAIG;AACH,wBAAsB,wBAAwB,CAAC,GAAG,EAAE,eAAe,iBA8FlE"}
|
|
@@ -18,6 +18,7 @@ const handleUserRegistration_1 = __importDefault(require("../../../shared/handle
|
|
|
18
18
|
const handleUserRegistration_model_1 = require("../../../shared/models/handleUserRegistration.model");
|
|
19
19
|
const state_1 = require("../../../state");
|
|
20
20
|
const context_1 = require("../../../utils/context");
|
|
21
|
+
const crypto_1 = require("../../../utils/crypto");
|
|
21
22
|
const utils_1 = require("../../utils");
|
|
22
23
|
const schema_1 = require("./schema");
|
|
23
24
|
/**
|
|
@@ -29,6 +30,9 @@ function customFunctionController(app) {
|
|
|
29
30
|
return __awaiter(this, void 0, void 0, function* () {
|
|
30
31
|
const functionsList = state_1.StateManager.select('functions');
|
|
31
32
|
const services = state_1.StateManager.select('services');
|
|
33
|
+
const db = app.mongo.client.db(constants_1.DB_NAME);
|
|
34
|
+
const { refreshTokensCollection } = constants_1.AUTH_CONFIG;
|
|
35
|
+
const refreshTokenTtlMs = constants_1.DEFAULT_CONFIG.REFRESH_TOKEN_TTL_DAYS * 24 * 60 * 60 * 1000;
|
|
32
36
|
/**
|
|
33
37
|
* Endpoint for user login.
|
|
34
38
|
*
|
|
@@ -68,17 +72,29 @@ function customFunctionController(app) {
|
|
|
68
72
|
});
|
|
69
73
|
if (res.id) {
|
|
70
74
|
const user = yield (0, handleUserRegistration_1.default)(app, { run_as_system: true, skipUserCheck: true, provider: handleUserRegistration_model_1.PROVIDER.CUSTOM_FUNCTION })({ email: res.id, password: (0, utils_1.generatePassword)() });
|
|
75
|
+
if (!(user === null || user === void 0 ? void 0 : user.insertedId)) {
|
|
76
|
+
throw new Error('Failed to register custom user');
|
|
77
|
+
}
|
|
71
78
|
const currentUserData = {
|
|
72
79
|
_id: user.insertedId,
|
|
73
80
|
user_data: {
|
|
74
|
-
_id: user.insertedId
|
|
81
|
+
_id: user.insertedId
|
|
75
82
|
}
|
|
76
83
|
};
|
|
84
|
+
const refreshToken = this.createRefreshToken(currentUserData);
|
|
85
|
+
const refreshTokenHash = (0, crypto_1.hashToken)(refreshToken);
|
|
86
|
+
yield db.collection(refreshTokensCollection).insertOne({
|
|
87
|
+
userId: user.insertedId,
|
|
88
|
+
tokenHash: refreshTokenHash,
|
|
89
|
+
createdAt: new Date(),
|
|
90
|
+
expiresAt: new Date(Date.now() + refreshTokenTtlMs),
|
|
91
|
+
revokedAt: null
|
|
92
|
+
});
|
|
77
93
|
return {
|
|
78
94
|
access_token: this.createAccessToken(currentUserData),
|
|
79
|
-
refresh_token:
|
|
95
|
+
refresh_token: refreshToken,
|
|
80
96
|
device_id: '',
|
|
81
|
-
user_id: user.insertedId.toString()
|
|
97
|
+
user_id: user.insertedId.toString()
|
|
82
98
|
};
|
|
83
99
|
}
|
|
84
100
|
throw new Error("Authentication Failed");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"controller.d.ts","sourceRoot":"","sources":["../../../../src/auth/providers/local-userpass/controller.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"controller.d.ts","sourceRoot":"","sources":["../../../../src/auth/providers/local-userpass/controller.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAmCzC;;;;GAIG;AACH,wBAAsB,uBAAuB,CAAC,GAAG,EAAE,eAAe,iBA+RjE"}
|
|
@@ -13,15 +13,23 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
13
13
|
};
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
15
|
exports.localUserPassController = localUserPassController;
|
|
16
|
-
const mail_1 = __importDefault(require("@sendgrid/mail"));
|
|
17
16
|
const constants_1 = require("../../../constants");
|
|
18
|
-
const services_1 = require("../../../services");
|
|
19
17
|
const handleUserRegistration_1 = __importDefault(require("../../../shared/handleUserRegistration"));
|
|
20
18
|
const handleUserRegistration_model_1 = require("../../../shared/models/handleUserRegistration.model");
|
|
21
19
|
const state_1 = require("../../../state");
|
|
22
20
|
const context_1 = require("../../../utils/context");
|
|
23
21
|
const crypto_1 = require("../../../utils/crypto");
|
|
24
22
|
const utils_1 = require("../../utils");
|
|
23
|
+
const rateLimitStore = new Map();
|
|
24
|
+
const isRateLimited = (key, maxAttempts, windowMs) => {
|
|
25
|
+
var _a;
|
|
26
|
+
const now = Date.now();
|
|
27
|
+
const existing = (_a = rateLimitStore.get(key)) !== null && _a !== void 0 ? _a : [];
|
|
28
|
+
const recent = existing.filter((timestamp) => now - timestamp < windowMs);
|
|
29
|
+
recent.push(now);
|
|
30
|
+
rateLimitStore.set(key, recent);
|
|
31
|
+
return recent.length > maxAttempts;
|
|
32
|
+
};
|
|
25
33
|
/**
|
|
26
34
|
* Controller for handling local user registration and login.
|
|
27
35
|
* @testable
|
|
@@ -29,9 +37,59 @@ const utils_1 = require("../../utils");
|
|
|
29
37
|
*/
|
|
30
38
|
function localUserPassController(app) {
|
|
31
39
|
return __awaiter(this, void 0, void 0, function* () {
|
|
32
|
-
const
|
|
33
|
-
const {
|
|
40
|
+
const { authCollection, userCollection, user_id_field } = constants_1.AUTH_CONFIG;
|
|
41
|
+
const { resetPasswordCollection } = constants_1.AUTH_CONFIG;
|
|
42
|
+
const { refreshTokensCollection } = constants_1.AUTH_CONFIG;
|
|
34
43
|
const db = app.mongo.client.db(constants_1.DB_NAME);
|
|
44
|
+
const resetPasswordTtlSeconds = constants_1.DEFAULT_CONFIG.RESET_PASSWORD_TTL_SECONDS;
|
|
45
|
+
const rateLimitWindowMs = constants_1.DEFAULT_CONFIG.AUTH_RATE_LIMIT_WINDOW_MS;
|
|
46
|
+
const loginMaxAttempts = constants_1.DEFAULT_CONFIG.AUTH_LOGIN_MAX_ATTEMPTS;
|
|
47
|
+
const resetMaxAttempts = constants_1.DEFAULT_CONFIG.AUTH_RESET_MAX_ATTEMPTS;
|
|
48
|
+
const refreshTokenTtlMs = constants_1.DEFAULT_CONFIG.REFRESH_TOKEN_TTL_DAYS * 24 * 60 * 60 * 1000;
|
|
49
|
+
try {
|
|
50
|
+
yield db.collection(resetPasswordCollection).createIndex({ createdAt: 1 }, { expireAfterSeconds: resetPasswordTtlSeconds });
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
console.error('Failed to ensure reset password TTL index', error);
|
|
54
|
+
}
|
|
55
|
+
try {
|
|
56
|
+
yield db.collection(refreshTokensCollection).createIndex({ expiresAt: 1 }, { expireAfterSeconds: 0 });
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
console.error('Failed to ensure refresh token TTL index', error);
|
|
60
|
+
}
|
|
61
|
+
const handleResetPasswordRequest = (email, password, extraArguments) => __awaiter(this, void 0, void 0, function* () {
|
|
62
|
+
const { resetPasswordConfig } = constants_1.AUTH_CONFIG;
|
|
63
|
+
const authUser = yield db.collection(authCollection).findOne({
|
|
64
|
+
email
|
|
65
|
+
});
|
|
66
|
+
if (!authUser) {
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
const token = (0, crypto_1.generateToken)();
|
|
70
|
+
const tokenId = (0, crypto_1.generateToken)();
|
|
71
|
+
yield (db === null || db === void 0 ? void 0 : db.collection(resetPasswordCollection).updateOne({ email }, { $set: { token, tokenId, email, createdAt: new Date() } }, { upsert: true }));
|
|
72
|
+
if (!resetPasswordConfig.runResetFunction && !resetPasswordConfig.resetFunctionName) {
|
|
73
|
+
throw new Error(utils_1.AUTH_ERRORS.MISSING_RESET_FUNCTION);
|
|
74
|
+
}
|
|
75
|
+
if (resetPasswordConfig.runResetFunction && resetPasswordConfig.resetFunctionName) {
|
|
76
|
+
const functionsList = state_1.StateManager.select('functions');
|
|
77
|
+
const services = state_1.StateManager.select('services');
|
|
78
|
+
const currentFunction = functionsList[resetPasswordConfig.resetFunctionName];
|
|
79
|
+
const baseArgs = { token, tokenId, email, password, username: email };
|
|
80
|
+
const args = Array.isArray(extraArguments) ? [baseArgs, ...extraArguments] : [baseArgs];
|
|
81
|
+
yield (0, context_1.GenerateContext)({
|
|
82
|
+
args,
|
|
83
|
+
app,
|
|
84
|
+
rules: {},
|
|
85
|
+
user: {},
|
|
86
|
+
currentFunction,
|
|
87
|
+
functionsList,
|
|
88
|
+
services
|
|
89
|
+
});
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
});
|
|
35
93
|
/**
|
|
36
94
|
* Endpoint for user registration.
|
|
37
95
|
*
|
|
@@ -44,8 +102,12 @@ function localUserPassController(app) {
|
|
|
44
102
|
schema: utils_1.REGISTRATION_SCHEMA
|
|
45
103
|
}, (req, res) => __awaiter(this, void 0, void 0, function* () {
|
|
46
104
|
const result = yield (0, handleUserRegistration_1.default)(app, { run_as_system: true, provider: handleUserRegistration_model_1.PROVIDER.LOCAL_USERPASS })({ email: req.body.email.toLowerCase(), password: req.body.password });
|
|
105
|
+
if (!(result === null || result === void 0 ? void 0 : result.insertedId)) {
|
|
106
|
+
res === null || res === void 0 ? void 0 : res.status(500);
|
|
107
|
+
throw new Error('Failed to register user');
|
|
108
|
+
}
|
|
47
109
|
res === null || res === void 0 ? void 0 : res.status(201);
|
|
48
|
-
return { userId: result
|
|
110
|
+
return { userId: result.insertedId.toString() };
|
|
49
111
|
}));
|
|
50
112
|
/**
|
|
51
113
|
* Endpoint for user login.
|
|
@@ -56,8 +118,13 @@ function localUserPassController(app) {
|
|
|
56
118
|
*/
|
|
57
119
|
app.post(utils_1.AUTH_ENDPOINTS.LOGIN, {
|
|
58
120
|
schema: utils_1.LOGIN_SCHEMA
|
|
59
|
-
}, function (req) {
|
|
121
|
+
}, function (req, res) {
|
|
60
122
|
return __awaiter(this, void 0, void 0, function* () {
|
|
123
|
+
const key = `login:${req.ip}`;
|
|
124
|
+
if (isRateLimited(key, loginMaxAttempts, rateLimitWindowMs)) {
|
|
125
|
+
res.status(429).send({ message: 'Too many requests' });
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
61
128
|
const authUser = yield db.collection(authCollection).findOne({
|
|
62
129
|
email: req.body.username
|
|
63
130
|
});
|
|
@@ -74,7 +141,7 @@ function localUserPassController(app) {
|
|
|
74
141
|
.findOne({ [user_id_field]: authUser._id.toString() })
|
|
75
142
|
: {};
|
|
76
143
|
authUser === null || authUser === void 0 ? true : delete authUser.password;
|
|
77
|
-
const userWithCustomData = Object.assign(Object.assign({}, authUser), { user_data: user, id: authUser._id.toString() });
|
|
144
|
+
const userWithCustomData = Object.assign(Object.assign({}, authUser), { user_data: Object.assign(Object.assign({}, (user || {})), { _id: authUser._id }), data: { email: authUser.email }, id: authUser._id.toString() });
|
|
78
145
|
if (authUser && authUser.status === 'pending') {
|
|
79
146
|
try {
|
|
80
147
|
yield (db === null || db === void 0 ? void 0 : db.collection(authCollection).updateOne({ _id: authUser._id }, {
|
|
@@ -87,35 +154,18 @@ function localUserPassController(app) {
|
|
|
87
154
|
console.log('>>> 🚀 ~ localUserPassController ~ error:', error);
|
|
88
155
|
}
|
|
89
156
|
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
providers: 'local-userpass',
|
|
100
|
-
user: userWithCustomData,
|
|
101
|
-
time: new Date().getTime()
|
|
102
|
-
}
|
|
103
|
-
],
|
|
104
|
-
app,
|
|
105
|
-
rules: {},
|
|
106
|
-
user: userWithCustomData,
|
|
107
|
-
currentFunction: functionsList[on_user_creation_function_name],
|
|
108
|
-
functionsList,
|
|
109
|
-
services: services_1.services
|
|
110
|
-
});
|
|
111
|
-
}
|
|
112
|
-
catch (error) {
|
|
113
|
-
console.log('localUserPassController - /login - GenerateContext - CATCH:', error);
|
|
114
|
-
}
|
|
115
|
-
}
|
|
157
|
+
const refreshToken = this.createRefreshToken(userWithCustomData);
|
|
158
|
+
const refreshTokenHash = (0, crypto_1.hashToken)(refreshToken);
|
|
159
|
+
yield db.collection(refreshTokensCollection).insertOne({
|
|
160
|
+
userId: authUser._id,
|
|
161
|
+
tokenHash: refreshTokenHash,
|
|
162
|
+
createdAt: new Date(),
|
|
163
|
+
expiresAt: new Date(Date.now() + refreshTokenTtlMs),
|
|
164
|
+
revokedAt: null
|
|
165
|
+
});
|
|
116
166
|
return {
|
|
117
167
|
access_token: this.createAccessToken(userWithCustomData),
|
|
118
|
-
refresh_token:
|
|
168
|
+
refresh_token: refreshToken,
|
|
119
169
|
device_id: '',
|
|
120
170
|
user_id: authUser._id.toString()
|
|
121
171
|
};
|
|
@@ -124,48 +174,40 @@ function localUserPassController(app) {
|
|
|
124
174
|
/**
|
|
125
175
|
* Endpoint for reset password.
|
|
126
176
|
*
|
|
127
|
-
* @route {POST} /reset/
|
|
177
|
+
* @route {POST} /reset/send
|
|
128
178
|
* @param {ResetPasswordDto} req - The request object with th reset request.
|
|
129
179
|
* @returns {Promise<void>}
|
|
130
180
|
*/
|
|
131
181
|
app.post(utils_1.AUTH_ENDPOINTS.RESET, {
|
|
132
|
-
schema: utils_1.
|
|
133
|
-
}, function (req) {
|
|
182
|
+
schema: utils_1.RESET_SEND_SCHEMA
|
|
183
|
+
}, function (req, res) {
|
|
134
184
|
return __awaiter(this, void 0, void 0, function* () {
|
|
135
|
-
const
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
});
|
|
140
|
-
if (!authUser) {
|
|
141
|
-
throw new Error(utils_1.AUTH_ERRORS.INVALID_CREDENTIALS);
|
|
185
|
+
const key = `reset:${req.ip}`;
|
|
186
|
+
if (isRateLimited(key, resetMaxAttempts, rateLimitWindowMs)) {
|
|
187
|
+
res.status(429);
|
|
188
|
+
return { message: 'Too many requests' };
|
|
142
189
|
}
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
});
|
|
159
|
-
return;
|
|
190
|
+
yield handleResetPasswordRequest(req.body.email);
|
|
191
|
+
res.status(202);
|
|
192
|
+
return {
|
|
193
|
+
status: 'ok'
|
|
194
|
+
};
|
|
195
|
+
});
|
|
196
|
+
});
|
|
197
|
+
app.post(utils_1.AUTH_ENDPOINTS.RESET_CALL, {
|
|
198
|
+
schema: utils_1.RESET_CALL_SCHEMA
|
|
199
|
+
}, function (req, res) {
|
|
200
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
201
|
+
const key = `reset:${req.ip}`;
|
|
202
|
+
if (isRateLimited(key, resetMaxAttempts, rateLimitWindowMs)) {
|
|
203
|
+
res.status(429);
|
|
204
|
+
return { message: 'Too many requests' };
|
|
160
205
|
}
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
subject,
|
|
167
|
-
html: body
|
|
168
|
-
});
|
|
206
|
+
yield handleResetPasswordRequest(req.body.email, req.body.password, req.body.arguments);
|
|
207
|
+
res.status(202);
|
|
208
|
+
return {
|
|
209
|
+
status: 'ok'
|
|
210
|
+
};
|
|
169
211
|
});
|
|
170
212
|
});
|
|
171
213
|
/**
|
|
@@ -177,14 +219,26 @@ function localUserPassController(app) {
|
|
|
177
219
|
*/
|
|
178
220
|
app.post(utils_1.AUTH_ENDPOINTS.CONFIRM_RESET, {
|
|
179
221
|
schema: utils_1.CONFIRM_RESET_SCHEMA
|
|
180
|
-
}, function (req) {
|
|
222
|
+
}, function (req, res) {
|
|
181
223
|
return __awaiter(this, void 0, void 0, function* () {
|
|
182
|
-
const
|
|
224
|
+
const key = `reset-confirm:${req.ip}`;
|
|
225
|
+
if (isRateLimited(key, resetMaxAttempts, rateLimitWindowMs)) {
|
|
226
|
+
res.status(429);
|
|
227
|
+
return { message: 'Too many requests' };
|
|
228
|
+
}
|
|
183
229
|
const { token, tokenId, password } = req.body;
|
|
184
230
|
const resetRequest = yield (db === null || db === void 0 ? void 0 : db.collection(resetPasswordCollection).findOne({ token, tokenId }));
|
|
185
231
|
if (!resetRequest) {
|
|
186
232
|
throw new Error(utils_1.AUTH_ERRORS.INVALID_RESET_PARAMS);
|
|
187
233
|
}
|
|
234
|
+
const createdAt = resetRequest.createdAt ? new Date(resetRequest.createdAt) : null;
|
|
235
|
+
const isExpired = !createdAt ||
|
|
236
|
+
Number.isNaN(createdAt.getTime()) ||
|
|
237
|
+
Date.now() - createdAt.getTime() > resetPasswordTtlSeconds * 1000;
|
|
238
|
+
if (isExpired) {
|
|
239
|
+
yield (db === null || db === void 0 ? void 0 : db.collection(resetPasswordCollection).deleteOne({ _id: resetRequest._id }));
|
|
240
|
+
throw new Error(utils_1.AUTH_ERRORS.INVALID_RESET_PARAMS);
|
|
241
|
+
}
|
|
188
242
|
const hashedPassword = yield (0, crypto_1.hashPassword)(password);
|
|
189
243
|
yield db.collection(authCollection).updateOne({ email: resetRequest.email }, {
|
|
190
244
|
$set: {
|
|
@@ -12,17 +12,26 @@ export type LoginSuccessDto = {
|
|
|
12
12
|
refresh_token: string;
|
|
13
13
|
user_id: string;
|
|
14
14
|
};
|
|
15
|
+
export type ErrorResponseDto = {
|
|
16
|
+
message: string;
|
|
17
|
+
};
|
|
15
18
|
export interface RegistrationDto {
|
|
16
19
|
Body: RegisterUserDto;
|
|
17
20
|
}
|
|
18
21
|
export interface LoginDto {
|
|
19
22
|
Body: LoginUserDto;
|
|
20
|
-
Reply: LoginSuccessDto;
|
|
23
|
+
Reply: LoginSuccessDto | ErrorResponseDto;
|
|
24
|
+
}
|
|
25
|
+
export interface ResetPasswordSendDto {
|
|
26
|
+
Body: {
|
|
27
|
+
email: string;
|
|
28
|
+
};
|
|
21
29
|
}
|
|
22
|
-
export interface
|
|
30
|
+
export interface ResetPasswordCallDto {
|
|
23
31
|
Body: {
|
|
24
32
|
email: string;
|
|
25
33
|
password: string;
|
|
34
|
+
arguments?: unknown[];
|
|
26
35
|
};
|
|
27
36
|
}
|
|
28
37
|
export interface ConfirmResetPasswordDto {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dtos.d.ts","sourceRoot":"","sources":["../../../../src/auth/providers/local-userpass/dtos.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,eAAe,GAAG;IAC5B,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,MAAM,CAAA;CACjB,CAAA;AAED,MAAM,MAAM,YAAY,GAAG;IACzB,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;CACjB,CAAA;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,YAAY,EAAE,MAAM,CAAA;IACpB,SAAS,EAAE,MAAM,CAAA;IACjB,aAAa,EAAE,MAAM,CAAA;IACrB,OAAO,EAAE,MAAM,CAAA;CAChB,CAAA;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,eAAe,CAAA;CACtB;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,YAAY,CAAA;IAClB,KAAK,EAAE,eAAe,CAAA;
|
|
1
|
+
{"version":3,"file":"dtos.d.ts","sourceRoot":"","sources":["../../../../src/auth/providers/local-userpass/dtos.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,eAAe,GAAG;IAC5B,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,MAAM,CAAA;CACjB,CAAA;AAED,MAAM,MAAM,YAAY,GAAG;IACzB,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;CACjB,CAAA;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,YAAY,EAAE,MAAM,CAAA;IACpB,SAAS,EAAE,MAAM,CAAA;IACjB,aAAa,EAAE,MAAM,CAAA;IACrB,OAAO,EAAE,MAAM,CAAA;CAChB,CAAA;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B,OAAO,EAAE,MAAM,CAAA;CAChB,CAAA;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,eAAe,CAAA;CACtB;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,YAAY,CAAA;IAClB,KAAK,EAAE,eAAe,GAAG,gBAAgB,CAAA;CAC1C;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE;QACJ,KAAK,EAAE,MAAM,CAAA;KACd,CAAA;CACF;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE;QACJ,KAAK,EAAE,MAAM,CAAA;QACb,QAAQ,EAAE,MAAM,CAAA;QAChB,SAAS,CAAC,EAAE,OAAO,EAAE,CAAA;KACtB,CAAA;CACF;AAED,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE;QACJ,KAAK,EAAE,MAAM,CAAA;QACb,OAAO,EAAE,MAAM,CAAA;QACf,QAAQ,EAAE,MAAM,CAAA;KACjB,CAAA;CACF"}
|