@flowerforce/flowerbase 1.2.1-beta.11 → 1.2.1-beta.13
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/dist/auth/providers/local-userpass/controller.d.ts.map +1 -1
- package/dist/auth/providers/local-userpass/controller.js +34 -11
- package/dist/auth/providers/local-userpass/dtos.d.ts +6 -0
- package/dist/auth/providers/local-userpass/dtos.d.ts.map +1 -1
- package/dist/auth/utils.d.ts +18 -1
- package/dist/auth/utils.d.ts.map +1 -1
- package/dist/auth/utils.js +13 -1
- package/dist/features/triggers/index.d.ts.map +1 -1
- package/dist/features/triggers/index.js +1 -0
- package/dist/features/triggers/interface.d.ts +1 -0
- package/dist/features/triggers/interface.d.ts.map +1 -1
- package/dist/features/triggers/utils.js +6 -7
- package/dist/shared/handleUserRegistration.d.ts.map +1 -1
- package/dist/shared/handleUserRegistration.js +64 -1
- package/dist/utils/context/helpers.d.ts +5 -5
- package/dist/utils/context/helpers.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/auth/providers/local-userpass/controller.ts +49 -14
- package/src/auth/providers/local-userpass/dtos.ts +7 -0
- package/src/auth/utils.ts +15 -1
- package/src/features/triggers/index.ts +2 -1
- package/src/features/triggers/interface.ts +1 -0
- package/src/features/triggers/utils.ts +11 -11
- package/src/shared/handleUserRegistration.ts +82 -2
|
@@ -1 +1 @@
|
|
|
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;
|
|
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;AAqCzC;;;;GAIG;AACH,wBAAsB,uBAAuB,CAAC,GAAG,EAAE,eAAe,iBAgUjE"}
|
|
@@ -109,6 +109,38 @@ function localUserPassController(app) {
|
|
|
109
109
|
res === null || res === void 0 ? void 0 : res.status(201);
|
|
110
110
|
return { userId: result.insertedId.toString() };
|
|
111
111
|
}));
|
|
112
|
+
/**
|
|
113
|
+
* Endpoint for confirming a user registration.
|
|
114
|
+
*
|
|
115
|
+
* @route {POST} /confirm
|
|
116
|
+
* @param {ConfirmUserDto} req - The request object with confirmation data.
|
|
117
|
+
* @returns {Promise<Object>} A promise resolving with confirmation status.
|
|
118
|
+
*/
|
|
119
|
+
app.post(utils_1.AUTH_ENDPOINTS.CONFIRM, {
|
|
120
|
+
schema: utils_1.CONFIRM_USER_SCHEMA
|
|
121
|
+
}, (req, res) => __awaiter(this, void 0, void 0, function* () {
|
|
122
|
+
const key = `confirm:${req.ip}`;
|
|
123
|
+
if (isRateLimited(key, resetMaxAttempts, rateLimitWindowMs)) {
|
|
124
|
+
res.status(429).send({ message: 'Too many requests' });
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
const existing = yield db.collection(authCollection).findOne({
|
|
128
|
+
confirmationToken: req.body.token,
|
|
129
|
+
confirmationTokenId: req.body.tokenId
|
|
130
|
+
});
|
|
131
|
+
if (!existing) {
|
|
132
|
+
res.status(500);
|
|
133
|
+
throw new Error(utils_1.AUTH_ERRORS.INVALID_TOKEN);
|
|
134
|
+
}
|
|
135
|
+
if (existing.status !== 'confirmed') {
|
|
136
|
+
yield db.collection(authCollection).updateOne({ _id: existing._id }, {
|
|
137
|
+
$set: { status: 'confirmed' },
|
|
138
|
+
$unset: { confirmationToken: '', confirmationTokenId: '' }
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
res.status(200);
|
|
142
|
+
return { status: 'confirmed' };
|
|
143
|
+
}));
|
|
112
144
|
/**
|
|
113
145
|
* Endpoint for user login.
|
|
114
146
|
*
|
|
@@ -142,17 +174,8 @@ function localUserPassController(app) {
|
|
|
142
174
|
: {};
|
|
143
175
|
authUser === null || authUser === void 0 ? true : delete authUser.password;
|
|
144
176
|
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() });
|
|
145
|
-
if (authUser && authUser.status
|
|
146
|
-
|
|
147
|
-
yield (db === null || db === void 0 ? void 0 : db.collection(authCollection).updateOne({ _id: authUser._id }, {
|
|
148
|
-
$set: {
|
|
149
|
-
status: 'confirmed'
|
|
150
|
-
}
|
|
151
|
-
}));
|
|
152
|
-
}
|
|
153
|
-
catch (error) {
|
|
154
|
-
console.log('>>> 🚀 ~ localUserPassController ~ error:', error);
|
|
155
|
-
}
|
|
177
|
+
if (authUser && authUser.status !== 'confirmed') {
|
|
178
|
+
throw new Error(utils_1.AUTH_ERRORS.USER_NOT_CONFIRMED);
|
|
156
179
|
}
|
|
157
180
|
const refreshToken = this.createRefreshToken(userWithCustomData);
|
|
158
181
|
const refreshTokenHash = (0, crypto_1.hashToken)(refreshToken);
|
|
@@ -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,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"}
|
|
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;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE;QACJ,KAAK,EAAE,MAAM,CAAA;QACb,OAAO,EAAE,MAAM,CAAA;KAChB,CAAA;CACF"}
|
package/dist/auth/utils.d.ts
CHANGED
|
@@ -72,6 +72,20 @@ export declare const CONFIRM_RESET_SCHEMA: {
|
|
|
72
72
|
required: string[];
|
|
73
73
|
};
|
|
74
74
|
};
|
|
75
|
+
export declare const CONFIRM_USER_SCHEMA: {
|
|
76
|
+
body: {
|
|
77
|
+
type: string;
|
|
78
|
+
properties: {
|
|
79
|
+
token: {
|
|
80
|
+
type: string;
|
|
81
|
+
};
|
|
82
|
+
tokenId: {
|
|
83
|
+
type: string;
|
|
84
|
+
};
|
|
85
|
+
};
|
|
86
|
+
required: string[];
|
|
87
|
+
};
|
|
88
|
+
};
|
|
75
89
|
export declare const RESET_SCHEMA: {
|
|
76
90
|
body: {
|
|
77
91
|
type: string;
|
|
@@ -108,6 +122,7 @@ export declare const REGISTRATION_SCHEMA: {
|
|
|
108
122
|
export declare enum AUTH_ENDPOINTS {
|
|
109
123
|
LOGIN = "/login",
|
|
110
124
|
REGISTRATION = "/register",
|
|
125
|
+
CONFIRM = "/confirm",
|
|
111
126
|
PROFILE = "/profile",
|
|
112
127
|
SESSION = "/session",
|
|
113
128
|
RESET = "/reset/send",
|
|
@@ -119,7 +134,8 @@ export declare enum AUTH_ERRORS {
|
|
|
119
134
|
INVALID_CREDENTIALS = "Invalid credentials",
|
|
120
135
|
INVALID_TOKEN = "Invalid refresh token provided",
|
|
121
136
|
INVALID_RESET_PARAMS = "Invalid token or tokenId provided",
|
|
122
|
-
MISSING_RESET_FUNCTION = "Missing reset function"
|
|
137
|
+
MISSING_RESET_FUNCTION = "Missing reset function",
|
|
138
|
+
USER_NOT_CONFIRMED = "User not confirmed"
|
|
123
139
|
}
|
|
124
140
|
export interface AuthConfig {
|
|
125
141
|
auth_collection?: string;
|
|
@@ -148,6 +164,7 @@ interface CustomFunction {
|
|
|
148
164
|
}
|
|
149
165
|
export interface Config {
|
|
150
166
|
autoConfirm: boolean;
|
|
167
|
+
confirmationFunctionName?: string;
|
|
151
168
|
resetFunctionName: string;
|
|
152
169
|
resetPasswordUrl: string;
|
|
153
170
|
runConfirmationFunction: boolean;
|
package/dist/auth/utils.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/auth/utils.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;CAcxB,CAAA;AAED,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;CAa7B,CAAA;AAED,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;CAe7B,CAAA;AAED,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;CAUhC,CAAA;AAED,eAAO,MAAM,YAAY;;;;;;;;;;;;;CAAoB,CAAA;AAE7C,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;CAc/B,CAAA;AAED,oBAAY,cAAc;IACxB,KAAK,WAAW;IAChB,YAAY,cAAc;IAC1B,OAAO,aAAa;IACpB,OAAO,aAAa;IACpB,KAAK,gBAAgB;IACrB,UAAU,gBAAgB;IAC1B,aAAa,WAAW;IACxB,UAAU,sBAAsB;CACjC;AAED,oBAAY,WAAW;IACrB,mBAAmB,wBAAwB;IAC3C,aAAa,mCAAmC;IAChD,oBAAoB,sCAAsC;IAC1D,sBAAsB,2BAA2B;
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/auth/utils.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;CAcxB,CAAA;AAED,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;CAa7B,CAAA;AAED,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;CAe7B,CAAA;AAED,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;CAUhC,CAAA;AAED,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;CAS/B,CAAA;AAED,eAAO,MAAM,YAAY;;;;;;;;;;;;;CAAoB,CAAA;AAE7C,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;CAc/B,CAAA;AAED,oBAAY,cAAc;IACxB,KAAK,WAAW;IAChB,YAAY,cAAc;IAC1B,OAAO,aAAa;IACpB,OAAO,aAAa;IACpB,OAAO,aAAa;IACpB,KAAK,gBAAgB;IACrB,UAAU,gBAAgB;IAC1B,aAAa,WAAW;IACxB,UAAU,sBAAsB;CACjC;AAED,oBAAY,WAAW;IACrB,mBAAmB,wBAAwB;IAC3C,aAAa,mCAAmC;IAChD,oBAAoB,sCAAsC;IAC1D,sBAAsB,2BAA2B;IACjD,kBAAkB,uBAAuB;CAC1C;AAED,MAAM,WAAW,UAAU;IACzB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,SAAS,EAAE,MAAM,CAAA;IACjB,gBAAgB,EAAE,aAAa,CAAA;IAC/B,iBAAiB,EAAE,cAAc,CAAA;CAClC;AAED,UAAU,MAAM;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,OAAO,CAAA;CAClB;AACD,UAAU,aAAa;IACrB,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,OAAO,CAAA;IACjB,MAAM,EAAE,MAAM,CAAA;CACf;AAED,UAAU,cAAc;IACtB,IAAI,EAAE,iBAAiB,CAAC;IACxB,IAAI,EAAE,iBAAiB,CAAC;IACxB,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE;QACN,kBAAkB,EAAE,MAAM,CAAA;KAC3B,CAAA;CACF;AAED,MAAM,WAAW,MAAM;IACrB,WAAW,EAAE,OAAO,CAAA;IACpB,wBAAwB,CAAC,EAAE,MAAM,CAAA;IACjC,iBAAiB,EAAE,MAAM,CAAA;IACzB,gBAAgB,EAAE,MAAM,CAAA;IACxB,uBAAuB,EAAE,OAAO,CAAA;IAChC,gBAAgB,EAAE,OAAO,CAAA;CAC1B;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,OAAO,CAAA;IAChB,kBAAkB,EAAE,MAAM,CAAA;IAC1B,aAAa,EAAE,MAAM,CAAA;IACrB,eAAe,EAAE,MAAM,CAAA;IACvB,aAAa,EAAE,MAAM,CAAA;IACrB,8BAA8B,EAAE,MAAM,CAAA;CACvC;AAMD;;;GAGG;AACH,eAAO,MAAM,cAAc,QAAO,UAGjC,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,kBAAkB,QAAO,oBAGrC,CAAA;AAED,eAAO,MAAM,gBAAgB,GAAI,eAAW,WAG3C,CAAA"}
|
package/dist/auth/utils.js
CHANGED
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.generatePassword = exports.loadCustomUserData = exports.loadAuthConfig = exports.AUTH_ERRORS = exports.AUTH_ENDPOINTS = exports.REGISTRATION_SCHEMA = exports.RESET_SCHEMA = exports.CONFIRM_RESET_SCHEMA = exports.RESET_CALL_SCHEMA = exports.RESET_SEND_SCHEMA = exports.LOGIN_SCHEMA = void 0;
|
|
6
|
+
exports.generatePassword = exports.loadCustomUserData = exports.loadAuthConfig = exports.AUTH_ERRORS = exports.AUTH_ENDPOINTS = exports.REGISTRATION_SCHEMA = exports.RESET_SCHEMA = exports.CONFIRM_USER_SCHEMA = exports.CONFIRM_RESET_SCHEMA = exports.RESET_CALL_SCHEMA = exports.RESET_SEND_SCHEMA = exports.LOGIN_SCHEMA = void 0;
|
|
7
7
|
const crypto_1 = __importDefault(require("crypto"));
|
|
8
8
|
const fs_1 = __importDefault(require("fs"));
|
|
9
9
|
const path_1 = __importDefault(require("path"));
|
|
@@ -64,6 +64,16 @@ exports.CONFIRM_RESET_SCHEMA = {
|
|
|
64
64
|
required: ['password', 'token', 'tokenId']
|
|
65
65
|
}
|
|
66
66
|
};
|
|
67
|
+
exports.CONFIRM_USER_SCHEMA = {
|
|
68
|
+
body: {
|
|
69
|
+
type: 'object',
|
|
70
|
+
properties: {
|
|
71
|
+
token: { type: 'string' },
|
|
72
|
+
tokenId: { type: 'string' }
|
|
73
|
+
},
|
|
74
|
+
required: ['token', 'tokenId']
|
|
75
|
+
}
|
|
76
|
+
};
|
|
67
77
|
exports.RESET_SCHEMA = exports.RESET_SEND_SCHEMA;
|
|
68
78
|
exports.REGISTRATION_SCHEMA = {
|
|
69
79
|
body: {
|
|
@@ -84,6 +94,7 @@ var AUTH_ENDPOINTS;
|
|
|
84
94
|
(function (AUTH_ENDPOINTS) {
|
|
85
95
|
AUTH_ENDPOINTS["LOGIN"] = "/login";
|
|
86
96
|
AUTH_ENDPOINTS["REGISTRATION"] = "/register";
|
|
97
|
+
AUTH_ENDPOINTS["CONFIRM"] = "/confirm";
|
|
87
98
|
AUTH_ENDPOINTS["PROFILE"] = "/profile";
|
|
88
99
|
AUTH_ENDPOINTS["SESSION"] = "/session";
|
|
89
100
|
AUTH_ENDPOINTS["RESET"] = "/reset/send";
|
|
@@ -97,6 +108,7 @@ var AUTH_ERRORS;
|
|
|
97
108
|
AUTH_ERRORS["INVALID_TOKEN"] = "Invalid refresh token provided";
|
|
98
109
|
AUTH_ERRORS["INVALID_RESET_PARAMS"] = "Invalid token or tokenId provided";
|
|
99
110
|
AUTH_ERRORS["MISSING_RESET_FUNCTION"] = "Missing reset function";
|
|
111
|
+
AUTH_ERRORS["USER_NOT_CONFIRMED"] = "User not confirmed";
|
|
100
112
|
})(AUTH_ERRORS || (exports.AUTH_ERRORS = AUTH_ERRORS = {}));
|
|
101
113
|
const resolveAppPath = () => { var _a, _b, _c; return (_c = (_a = process.env.FLOWERBASE_APP_PATH) !== null && _a !== void 0 ? _a : (_b = require.main) === null || _b === void 0 ? void 0 : _b.path) !== null && _c !== void 0 ? _c : process.cwd(); };
|
|
102
114
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/features/triggers/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,sBAAsB,EAAE,MAAM,QAAQ,CAAA;AAG/C;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,GAAU,0CAIpC,sBAAsB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/features/triggers/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,sBAAsB,EAAE,MAAM,QAAQ,CAAA;AAG/C;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,GAAU,0CAIpC,sBAAsB,kBAgExB,CAAA"}
|
|
@@ -48,6 +48,7 @@ const activateTriggers = (_a) => __awaiter(void 0, [_a], void 0, function* ({ fa
|
|
|
48
48
|
type: 'AUTHENTICATION',
|
|
49
49
|
disabled: false,
|
|
50
50
|
config: {
|
|
51
|
+
isAutoTrigger: true,
|
|
51
52
|
collection: (_e = constants_1.AUTH_CONFIG.authCollection) !== null && _e !== void 0 ? _e : 'auth_users',
|
|
52
53
|
database: constants_1.DB_NAME,
|
|
53
54
|
full_document: true,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../../src/features/triggers/interface.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AACzC,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAA;AACnD,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAA;AAE5D,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,WAAW,CAAA;IACjB,QAAQ,EAAE,OAAO,CAAA;IACjB,MAAM,EAAE,MAAM,CAAA;IACd,gBAAgB,EAAE;QAChB,QAAQ,EAAE;YACR,MAAM,EAAE;gBACN,aAAa,EAAE,MAAM,CAAA;aACtB,CAAA;SACF,CAAA;KACF,CAAA;CACF;AAED,KAAK,MAAM,GAAG;IACZ,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;IAChB,aAAa,EAAE,OAAO,CAAA;IACtB,2BAA2B,EAAE,OAAO,CAAA;IACpC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC9B,eAAe,EAAE,MAAM,EAAE,CAAA;IACzB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAChC,YAAY,EAAE,MAAM,CAAA;IACpB,mBAAmB,EAAE,OAAO,CAAA;IAC5B,sBAAsB,EAAE,OAAO,CAAA;IAC/B,SAAS,EAAE,OAAO,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;CACjB,CAAA;AAED,MAAM,MAAM,WAAW,GAAG,WAAW,GAAG,UAAU,GAAG,gBAAgB,CAAA;AACrE,MAAM,MAAM,QAAQ,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,EAAE,CAAA;AAE/D,MAAM,MAAM,aAAa,GAAG;IAC1B,MAAM,EAAE,MAAM,CAAA;IACd,cAAc,EAAE,QAAQ,CAAA;IACxB,GAAG,EAAE,eAAe,CAAA;IACpB,QAAQ,EAAE,QAAQ,CAAA;IAClB,aAAa,EAAE,SAAS,CAAA;CACzB,CAAA"}
|
|
1
|
+
{"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../../src/features/triggers/interface.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AACzC,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAA;AACnD,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAA;AAE5D,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,WAAW,CAAA;IACjB,QAAQ,EAAE,OAAO,CAAA;IACjB,MAAM,EAAE,MAAM,CAAA;IACd,gBAAgB,EAAE;QAChB,QAAQ,EAAE;YACR,MAAM,EAAE;gBACN,aAAa,EAAE,MAAM,CAAA;aACtB,CAAA;SACF,CAAA;KACF,CAAA;CACF;AAED,KAAK,MAAM,GAAG;IACZ,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;IAChB,aAAa,EAAE,OAAO,CAAA;IACtB,2BAA2B,EAAE,OAAO,CAAA;IACpC,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC9B,eAAe,EAAE,MAAM,EAAE,CAAA;IACzB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAChC,YAAY,EAAE,MAAM,CAAA;IACpB,mBAAmB,EAAE,OAAO,CAAA;IAC5B,sBAAsB,EAAE,OAAO,CAAA;IAC/B,SAAS,EAAE,OAAO,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;CACjB,CAAA;AAED,MAAM,MAAM,WAAW,GAAG,WAAW,GAAG,UAAU,GAAG,gBAAgB,CAAA;AACrE,MAAM,MAAM,QAAQ,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,EAAE,CAAA;AAE/D,MAAM,MAAM,aAAa,GAAG;IAC1B,MAAM,EAAE,MAAM,CAAA;IACd,cAAc,EAAE,QAAQ,CAAA;IACxB,GAAG,EAAE,eAAe,CAAA;IACpB,QAAQ,EAAE,QAAQ,CAAA;IAClB,aAAa,EAAE,SAAS,CAAA;CACzB,CAAA"}
|
|
@@ -119,7 +119,7 @@ const handleCronTrigger = (_a) => __awaiter(void 0, [_a], void 0, function* ({ c
|
|
|
119
119
|
});
|
|
120
120
|
const handleAuthenticationTrigger = (_a) => __awaiter(void 0, [_a], void 0, function* ({ config, triggerHandler, functionsList, services, app }) {
|
|
121
121
|
var _b;
|
|
122
|
-
const { database } = config;
|
|
122
|
+
const { database, isAutoTrigger } = config;
|
|
123
123
|
const authCollection = (_b = constants_1.AUTH_CONFIG.authCollection) !== null && _b !== void 0 ? _b : 'auth_users';
|
|
124
124
|
const collection = app.mongo.client.db(database || constants_1.DB_NAME).collection(authCollection);
|
|
125
125
|
const pipeline = [
|
|
@@ -186,13 +186,12 @@ const handleAuthenticationTrigger = (_a) => __awaiter(void 0, [_a], void 0, func
|
|
|
186
186
|
delete document.password;
|
|
187
187
|
const currentUser = Object.assign({}, document);
|
|
188
188
|
delete currentUser.password;
|
|
189
|
+
const userData = Object.assign(Object.assign({}, currentUser), { id: currentUser._id.toString(), data: {
|
|
190
|
+
_id: currentUser._id.toString(),
|
|
191
|
+
email: currentUser.email
|
|
192
|
+
} });
|
|
189
193
|
yield (0, context_1.GenerateContext)({
|
|
190
|
-
args: [{
|
|
191
|
-
user: Object.assign(Object.assign({}, currentUser), { id: currentUser._id.toString(), data: {
|
|
192
|
-
_id: currentUser._id.toString(),
|
|
193
|
-
email: currentUser.email
|
|
194
|
-
} })
|
|
195
|
-
}],
|
|
194
|
+
args: isAutoTrigger ? [userData] : [Object.assign({ user: userData }, change)],
|
|
196
195
|
app,
|
|
197
196
|
rules: state_1.StateManager.select("rules"),
|
|
198
197
|
user: {}, // TODO from currentUser ??
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handleUserRegistration.d.ts","sourceRoot":"","sources":["../../src/shared/handleUserRegistration.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"handleUserRegistration.d.ts","sourceRoot":"","sources":["../../src/shared/handleUserRegistration.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,sBAAsB,EAAE,MAAM,uCAAuC,CAAA;AAE9E;;;;;;GAMG;AACH,QAAA,MAAM,sBAAsB,EAAE,sBAkI7B,CAAA;AAED,eAAe,sBAAsB,CAAA"}
|
|
@@ -10,6 +10,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
const constants_1 = require("../constants");
|
|
13
|
+
const state_1 = require("../state");
|
|
14
|
+
const context_1 = require("../utils/context");
|
|
13
15
|
const crypto_1 = require("../utils/crypto");
|
|
14
16
|
/**
|
|
15
17
|
* Register user
|
|
@@ -25,7 +27,10 @@ const handleUserRegistration = (app, opt) => (_a) => __awaiter(void 0, [_a], voi
|
|
|
25
27
|
throw new Error('only run_as_system');
|
|
26
28
|
}
|
|
27
29
|
const { authCollection } = constants_1.AUTH_CONFIG;
|
|
28
|
-
const
|
|
30
|
+
const localUserpassConfig = constants_1.AUTH_CONFIG.localUserpassConfig;
|
|
31
|
+
const autoConfirm = (localUserpassConfig === null || localUserpassConfig === void 0 ? void 0 : localUserpassConfig.autoConfirm) === true;
|
|
32
|
+
const runConfirmationFunction = (localUserpassConfig === null || localUserpassConfig === void 0 ? void 0 : localUserpassConfig.runConfirmationFunction) === true;
|
|
33
|
+
const confirmationFunctionName = localUserpassConfig === null || localUserpassConfig === void 0 ? void 0 : localUserpassConfig.confirmationFunctionName;
|
|
29
34
|
const mongo = app === null || app === void 0 ? void 0 : app.mongo;
|
|
30
35
|
const db = mongo.client.db(constants_1.DB_NAME);
|
|
31
36
|
const hashedPassword = yield (0, crypto_1.hashPassword)(password);
|
|
@@ -60,6 +65,64 @@ const handleUserRegistration = (app, opt) => (_a) => __awaiter(void 0, [_a], voi
|
|
|
60
65
|
]
|
|
61
66
|
}
|
|
62
67
|
}));
|
|
68
|
+
if (!(result === null || result === void 0 ? void 0 : result.insertedId) || skipUserCheck || autoConfirm) {
|
|
69
|
+
return result;
|
|
70
|
+
}
|
|
71
|
+
if (!runConfirmationFunction) {
|
|
72
|
+
throw new Error('Missing confirmation function');
|
|
73
|
+
}
|
|
74
|
+
if (!confirmationFunctionName) {
|
|
75
|
+
throw new Error('Missing confirmation function name');
|
|
76
|
+
}
|
|
77
|
+
const functionsList = state_1.StateManager.select('functions');
|
|
78
|
+
const services = state_1.StateManager.select('services');
|
|
79
|
+
const confirmationFunction = functionsList[confirmationFunctionName];
|
|
80
|
+
if (!confirmationFunction) {
|
|
81
|
+
throw new Error(`Confirmation function not found: ${confirmationFunctionName}`);
|
|
82
|
+
}
|
|
83
|
+
const token = (0, crypto_1.generateToken)();
|
|
84
|
+
const tokenId = (0, crypto_1.generateToken)();
|
|
85
|
+
yield (db === null || db === void 0 ? void 0 : db.collection(authCollection).updateOne({ _id: result.insertedId }, {
|
|
86
|
+
$set: {
|
|
87
|
+
confirmationToken: token,
|
|
88
|
+
confirmationTokenId: tokenId
|
|
89
|
+
}
|
|
90
|
+
}));
|
|
91
|
+
let confirmationStatus = 'fail';
|
|
92
|
+
try {
|
|
93
|
+
const response = yield (0, context_1.GenerateContext)({
|
|
94
|
+
args: [{
|
|
95
|
+
token,
|
|
96
|
+
tokenId,
|
|
97
|
+
username: email
|
|
98
|
+
}],
|
|
99
|
+
app,
|
|
100
|
+
rules: {},
|
|
101
|
+
user: {},
|
|
102
|
+
currentFunction: confirmationFunction,
|
|
103
|
+
functionsList,
|
|
104
|
+
services,
|
|
105
|
+
runAsSystem: true
|
|
106
|
+
});
|
|
107
|
+
confirmationStatus = (_b = response === null || response === void 0 ? void 0 : response.status) !== null && _b !== void 0 ? _b : 'fail';
|
|
108
|
+
}
|
|
109
|
+
catch (_c) {
|
|
110
|
+
confirmationStatus = 'fail';
|
|
111
|
+
}
|
|
112
|
+
if (confirmationStatus === 'success') {
|
|
113
|
+
yield (db === null || db === void 0 ? void 0 : db.collection(authCollection).updateOne({ _id: result.insertedId }, {
|
|
114
|
+
$set: { status: 'confirmed' },
|
|
115
|
+
$unset: { confirmationToken: '', confirmationTokenId: '' }
|
|
116
|
+
}));
|
|
117
|
+
return result;
|
|
118
|
+
}
|
|
119
|
+
if (confirmationStatus === 'pending') {
|
|
120
|
+
return result;
|
|
121
|
+
}
|
|
122
|
+
yield (db === null || db === void 0 ? void 0 : db.collection(authCollection).updateOne({ _id: result.insertedId }, {
|
|
123
|
+
$set: { status: 'failed' },
|
|
124
|
+
$unset: { confirmationToken: '', confirmationTokenId: '' }
|
|
125
|
+
}));
|
|
63
126
|
return result;
|
|
64
127
|
});
|
|
65
128
|
exports.default = handleUserRegistration;
|
|
@@ -23,10 +23,10 @@ export declare const generateContextData: ({ user, services, app, rules, current
|
|
|
23
23
|
method?: string | undefined;
|
|
24
24
|
url?: string | undefined;
|
|
25
25
|
host?: string | undefined;
|
|
26
|
-
id?: string | undefined;
|
|
27
26
|
ips?: string[];
|
|
28
27
|
hostname?: string | undefined;
|
|
29
28
|
ip?: string | undefined;
|
|
29
|
+
id?: string | undefined;
|
|
30
30
|
};
|
|
31
31
|
user: unknown;
|
|
32
32
|
environment: {
|
|
@@ -69,16 +69,16 @@ export declare const generateContextData: ({ user, services, app, rules, current
|
|
|
69
69
|
message: string;
|
|
70
70
|
};
|
|
71
71
|
} | import("undici").Dispatcher.ResponseData<T>>;
|
|
72
|
-
} | {
|
|
73
|
-
emailPasswordAuth: {
|
|
74
|
-
registerUser: ReturnType<import("../../shared/models/handleUserRegistration.model").HandleUserRegistration>;
|
|
75
|
-
};
|
|
76
72
|
} | {
|
|
77
73
|
lambda: (region: string) => import("aws-sdk").Lambda & {
|
|
78
74
|
Invoke: (...args: Parameters<import("aws-sdk").Lambda["invoke"]>) => Promise<import("aws-sdk/lib/request").PromiseResult<import("aws-sdk/clients/lambda").InvocationResponse, import("aws-sdk").AWSError>>;
|
|
79
75
|
InvokeAsync: import("aws-sdk").Lambda["invokeAsync"];
|
|
80
76
|
};
|
|
81
77
|
s3: (region: string) => import("aws-sdk").S3;
|
|
78
|
+
} | {
|
|
79
|
+
emailPasswordAuth: {
|
|
80
|
+
registerUser: ReturnType<import("../../shared/models/handleUserRegistration.model").HandleUserRegistration>;
|
|
81
|
+
};
|
|
82
82
|
} | undefined;
|
|
83
83
|
};
|
|
84
84
|
functions: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../../src/utils/context/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAA;AAC1C,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAE3C,OAAO,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAA;AAEvD;;;;;;;;;GASG;AACH,eAAO,MAAM,mBAAmB,GAAI,0FASjC,yBAAyB;;;uBAGT,SAAS;yBAGP,SAAS;;;;;;;;;;;;;;;;;;uBAcb,MAAM;;;+BAGE,MAAM,OAAO,QAAQ
|
|
1
|
+
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../../src/utils/context/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAA;AAC1C,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAE3C,OAAO,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAA;AAEvD;;;;;;;;;GASG;AACH,eAAO,MAAM,mBAAmB,GAAI,0FASjC,yBAAyB;;;uBAGT,SAAS;yBAGP,SAAS;;;;;;;;;;;;;;;;;;uBAcb,MAAM;;;+BAGE,MAAM,OAAO,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6BAlCG,GAE3C;;;;;;;;;;;4BAiDgB,MAAM,OAAO,aAAa,WAAW,SAAS;;;CAclE,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { FastifyInstance } from 'fastify'
|
|
2
|
+
import { ObjectId } from 'mongodb'
|
|
2
3
|
import { AUTH_CONFIG, DB_NAME, DEFAULT_CONFIG } from '../../../constants'
|
|
3
|
-
import { services } from '../../../services'
|
|
4
4
|
import handleUserRegistration from '../../../shared/handleUserRegistration'
|
|
5
5
|
import { PROVIDER } from '../../../shared/models/handleUserRegistration.model'
|
|
6
6
|
import { StateManager } from '../../../state'
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
AUTH_ENDPOINTS,
|
|
11
11
|
AUTH_ERRORS,
|
|
12
12
|
CONFIRM_RESET_SCHEMA,
|
|
13
|
+
CONFIRM_USER_SCHEMA,
|
|
13
14
|
LOGIN_SCHEMA,
|
|
14
15
|
REGISTRATION_SCHEMA,
|
|
15
16
|
RESET_CALL_SCHEMA,
|
|
@@ -17,6 +18,7 @@ import {
|
|
|
17
18
|
} from '../../utils'
|
|
18
19
|
import {
|
|
19
20
|
ConfirmResetPasswordDto,
|
|
21
|
+
ConfirmUserDto,
|
|
20
22
|
LoginDto,
|
|
21
23
|
RegistrationDto,
|
|
22
24
|
ResetPasswordCallDto,
|
|
@@ -142,6 +144,50 @@ export async function localUserPassController(app: FastifyInstance) {
|
|
|
142
144
|
}
|
|
143
145
|
)
|
|
144
146
|
|
|
147
|
+
/**
|
|
148
|
+
* Endpoint for confirming a user registration.
|
|
149
|
+
*
|
|
150
|
+
* @route {POST} /confirm
|
|
151
|
+
* @param {ConfirmUserDto} req - The request object with confirmation data.
|
|
152
|
+
* @returns {Promise<Object>} A promise resolving with confirmation status.
|
|
153
|
+
*/
|
|
154
|
+
app.post<ConfirmUserDto>(
|
|
155
|
+
AUTH_ENDPOINTS.CONFIRM,
|
|
156
|
+
{
|
|
157
|
+
schema: CONFIRM_USER_SCHEMA
|
|
158
|
+
},
|
|
159
|
+
async (req, res) => {
|
|
160
|
+
const key = `confirm:${req.ip}`
|
|
161
|
+
if (isRateLimited(key, resetMaxAttempts, rateLimitWindowMs)) {
|
|
162
|
+
res.status(429).send({ message: 'Too many requests' })
|
|
163
|
+
return
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
const existing = await db.collection(authCollection!).findOne({
|
|
167
|
+
confirmationToken: req.body.token,
|
|
168
|
+
confirmationTokenId: req.body.tokenId
|
|
169
|
+
}) as { _id: ObjectId; status?: string } | null
|
|
170
|
+
|
|
171
|
+
if (!existing) {
|
|
172
|
+
res.status(500)
|
|
173
|
+
throw new Error(AUTH_ERRORS.INVALID_TOKEN)
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
if (existing.status !== 'confirmed') {
|
|
177
|
+
await db.collection(authCollection!).updateOne(
|
|
178
|
+
{ _id: existing._id },
|
|
179
|
+
{
|
|
180
|
+
$set: { status: 'confirmed' },
|
|
181
|
+
$unset: { confirmationToken: '', confirmationTokenId: '' }
|
|
182
|
+
}
|
|
183
|
+
)
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
res.status(200)
|
|
187
|
+
return { status: 'confirmed' }
|
|
188
|
+
}
|
|
189
|
+
)
|
|
190
|
+
|
|
145
191
|
/**
|
|
146
192
|
* Endpoint for user login.
|
|
147
193
|
*
|
|
@@ -192,19 +238,8 @@ export async function localUserPassController(app: FastifyInstance) {
|
|
|
192
238
|
id: authUser._id.toString()
|
|
193
239
|
}
|
|
194
240
|
|
|
195
|
-
if (authUser && authUser.status
|
|
196
|
-
|
|
197
|
-
await db?.collection(authCollection!).updateOne(
|
|
198
|
-
{ _id: authUser._id },
|
|
199
|
-
{
|
|
200
|
-
$set: {
|
|
201
|
-
status: 'confirmed'
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
)
|
|
205
|
-
} catch (error) {
|
|
206
|
-
console.log('>>> 🚀 ~ localUserPassController ~ error:', error)
|
|
207
|
-
}
|
|
241
|
+
if (authUser && authUser.status !== 'confirmed') {
|
|
242
|
+
throw new Error(AUTH_ERRORS.USER_NOT_CONFIRMED)
|
|
208
243
|
}
|
|
209
244
|
|
|
210
245
|
const refreshToken = this.createRefreshToken(userWithCustomData)
|
package/src/auth/utils.ts
CHANGED
|
@@ -64,6 +64,17 @@ export const CONFIRM_RESET_SCHEMA = {
|
|
|
64
64
|
}
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
+
export const CONFIRM_USER_SCHEMA = {
|
|
68
|
+
body: {
|
|
69
|
+
type: 'object',
|
|
70
|
+
properties: {
|
|
71
|
+
token: { type: 'string' },
|
|
72
|
+
tokenId: { type: 'string' }
|
|
73
|
+
},
|
|
74
|
+
required: ['token', 'tokenId']
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
67
78
|
export const RESET_SCHEMA = RESET_SEND_SCHEMA
|
|
68
79
|
|
|
69
80
|
export const REGISTRATION_SCHEMA = {
|
|
@@ -85,6 +96,7 @@ export const REGISTRATION_SCHEMA = {
|
|
|
85
96
|
export enum AUTH_ENDPOINTS {
|
|
86
97
|
LOGIN = '/login',
|
|
87
98
|
REGISTRATION = '/register',
|
|
99
|
+
CONFIRM = '/confirm',
|
|
88
100
|
PROFILE = '/profile',
|
|
89
101
|
SESSION = '/session',
|
|
90
102
|
RESET = '/reset/send',
|
|
@@ -97,7 +109,8 @@ export enum AUTH_ERRORS {
|
|
|
97
109
|
INVALID_CREDENTIALS = 'Invalid credentials',
|
|
98
110
|
INVALID_TOKEN = 'Invalid refresh token provided',
|
|
99
111
|
INVALID_RESET_PARAMS = 'Invalid token or tokenId provided',
|
|
100
|
-
MISSING_RESET_FUNCTION = 'Missing reset function'
|
|
112
|
+
MISSING_RESET_FUNCTION = 'Missing reset function',
|
|
113
|
+
USER_NOT_CONFIRMED = 'User not confirmed'
|
|
101
114
|
}
|
|
102
115
|
|
|
103
116
|
export interface AuthConfig {
|
|
@@ -130,6 +143,7 @@ interface CustomFunction {
|
|
|
130
143
|
|
|
131
144
|
export interface Config {
|
|
132
145
|
autoConfirm: boolean
|
|
146
|
+
confirmationFunctionName?: string
|
|
133
147
|
resetFunctionName: string
|
|
134
148
|
resetPasswordUrl: string
|
|
135
149
|
runConfirmationFunction: boolean
|
|
@@ -24,7 +24,7 @@ export const activateTriggers = async ({
|
|
|
24
24
|
(trigger) =>
|
|
25
25
|
trigger.content.type === 'AUTHENTICATION' &&
|
|
26
26
|
trigger.content.event_processors?.FUNCTION?.config?.function_name ===
|
|
27
|
-
|
|
27
|
+
AUTH_CONFIG.on_user_creation_function_name
|
|
28
28
|
)
|
|
29
29
|
if (!alreadyDeclared) {
|
|
30
30
|
triggersToActivate.push({
|
|
@@ -34,6 +34,7 @@ export const activateTriggers = async ({
|
|
|
34
34
|
type: 'AUTHENTICATION',
|
|
35
35
|
disabled: false,
|
|
36
36
|
config: {
|
|
37
|
+
isAutoTrigger: true,
|
|
37
38
|
collection: AUTH_CONFIG.authCollection ?? 'auth_users',
|
|
38
39
|
database: DB_NAME,
|
|
39
40
|
full_document: true,
|
|
@@ -110,7 +110,7 @@ const handleAuthenticationTrigger = async ({
|
|
|
110
110
|
services,
|
|
111
111
|
app
|
|
112
112
|
}: HandlerParams) => {
|
|
113
|
-
const { database } = config
|
|
113
|
+
const { database, isAutoTrigger } = config
|
|
114
114
|
const authCollection = AUTH_CONFIG.authCollection ?? 'auth_users'
|
|
115
115
|
const collection = app.mongo.client.db(database || DB_NAME).collection(authCollection)
|
|
116
116
|
const pipeline = [
|
|
@@ -191,17 +191,17 @@ const handleAuthenticationTrigger = async ({
|
|
|
191
191
|
|
|
192
192
|
const currentUser = { ...document }
|
|
193
193
|
delete (currentUser as { password?: unknown }).password
|
|
194
|
+
|
|
195
|
+
const userData = {
|
|
196
|
+
...currentUser,
|
|
197
|
+
id: (currentUser as { _id: { toString: () => string } })._id.toString(),
|
|
198
|
+
data: {
|
|
199
|
+
_id: (currentUser as { _id: { toString: () => string } })._id.toString(),
|
|
200
|
+
email: (currentUser as { email?: string }).email
|
|
201
|
+
}
|
|
202
|
+
}
|
|
194
203
|
await GenerateContext({
|
|
195
|
-
args: [{
|
|
196
|
-
user: {
|
|
197
|
-
...currentUser,
|
|
198
|
-
id: (currentUser as { _id: { toString: () => string } })._id.toString(),
|
|
199
|
-
data: {
|
|
200
|
-
_id: (currentUser as { _id: { toString: () => string } })._id.toString(),
|
|
201
|
-
email: (currentUser as { email?: string }).email
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
}],
|
|
204
|
+
args: isAutoTrigger ? [userData] : [{ user: userData, ...change }],
|
|
205
205
|
app,
|
|
206
206
|
rules: StateManager.select("rules"),
|
|
207
207
|
user: {}, // TODO from currentUser ??
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { AUTH_CONFIG, DB_NAME } from "../constants"
|
|
2
|
-
import {
|
|
2
|
+
import { StateManager } from "../state"
|
|
3
|
+
import { GenerateContext } from "../utils/context"
|
|
4
|
+
import { generateToken, hashPassword } from "../utils/crypto"
|
|
3
5
|
import { HandleUserRegistration } from "./models/handleUserRegistration.model"
|
|
4
6
|
|
|
5
7
|
/**
|
|
@@ -17,7 +19,10 @@ const handleUserRegistration: HandleUserRegistration = (app, opt) => async ({ em
|
|
|
17
19
|
}
|
|
18
20
|
|
|
19
21
|
const { authCollection } = AUTH_CONFIG
|
|
20
|
-
const
|
|
22
|
+
const localUserpassConfig = AUTH_CONFIG.localUserpassConfig
|
|
23
|
+
const autoConfirm = localUserpassConfig?.autoConfirm === true
|
|
24
|
+
const runConfirmationFunction = localUserpassConfig?.runConfirmationFunction === true
|
|
25
|
+
const confirmationFunctionName = localUserpassConfig?.confirmationFunctionName
|
|
21
26
|
const mongo = app?.mongo
|
|
22
27
|
const db = mongo.client.db(DB_NAME)
|
|
23
28
|
const hashedPassword = await hashPassword(password)
|
|
@@ -59,6 +64,81 @@ const handleUserRegistration: HandleUserRegistration = (app, opt) => async ({ em
|
|
|
59
64
|
}
|
|
60
65
|
)
|
|
61
66
|
|
|
67
|
+
if (!result?.insertedId || skipUserCheck || autoConfirm) {
|
|
68
|
+
return result
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (!runConfirmationFunction) {
|
|
72
|
+
throw new Error('Missing confirmation function')
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
if (!confirmationFunctionName) {
|
|
76
|
+
throw new Error('Missing confirmation function name')
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const functionsList = StateManager.select('functions')
|
|
80
|
+
const services = StateManager.select('services')
|
|
81
|
+
const confirmationFunction = functionsList[confirmationFunctionName]
|
|
82
|
+
if (!confirmationFunction) {
|
|
83
|
+
throw new Error(`Confirmation function not found: ${confirmationFunctionName}`)
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const token = generateToken()
|
|
87
|
+
const tokenId = generateToken()
|
|
88
|
+
await db?.collection(authCollection!).updateOne(
|
|
89
|
+
{ _id: result.insertedId },
|
|
90
|
+
{
|
|
91
|
+
$set: {
|
|
92
|
+
confirmationToken: token,
|
|
93
|
+
confirmationTokenId: tokenId
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
type ConfirmationResult = { status?: 'success' | 'pending' | 'fail' }
|
|
99
|
+
let confirmationStatus: ConfirmationResult['status'] = 'fail'
|
|
100
|
+
try {
|
|
101
|
+
const response = await GenerateContext({
|
|
102
|
+
args: [{
|
|
103
|
+
token,
|
|
104
|
+
tokenId,
|
|
105
|
+
username: email
|
|
106
|
+
}],
|
|
107
|
+
app,
|
|
108
|
+
rules: {},
|
|
109
|
+
user: {},
|
|
110
|
+
currentFunction: confirmationFunction,
|
|
111
|
+
functionsList,
|
|
112
|
+
services,
|
|
113
|
+
runAsSystem: true
|
|
114
|
+
}) as ConfirmationResult
|
|
115
|
+
confirmationStatus = response?.status ?? 'fail'
|
|
116
|
+
} catch {
|
|
117
|
+
confirmationStatus = 'fail'
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
if (confirmationStatus === 'success') {
|
|
121
|
+
await db?.collection(authCollection!).updateOne(
|
|
122
|
+
{ _id: result.insertedId },
|
|
123
|
+
{
|
|
124
|
+
$set: { status: 'confirmed' },
|
|
125
|
+
$unset: { confirmationToken: '', confirmationTokenId: '' }
|
|
126
|
+
}
|
|
127
|
+
)
|
|
128
|
+
return result
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
if (confirmationStatus === 'pending') {
|
|
132
|
+
return result
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
await db?.collection(authCollection!).updateOne(
|
|
136
|
+
{ _id: result.insertedId },
|
|
137
|
+
{
|
|
138
|
+
$set: { status: 'failed' },
|
|
139
|
+
$unset: { confirmationToken: '', confirmationTokenId: '' }
|
|
140
|
+
}
|
|
141
|
+
)
|
|
62
142
|
return result
|
|
63
143
|
|
|
64
144
|
}
|