@proteinjs/user-ui 1.0.35 → 1.0.36
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/CHANGELOG.md +8 -0
- package/LICENSE +21 -0
- package/dist/generated/index.d.ts +2 -0
- package/dist/generated/index.d.ts.map +1 -1
- package/dist/generated/index.js +7 -1
- package/dist/generated/index.js.map +1 -1
- package/dist/src/pages/ForgotPassword.d.ts +4 -0
- package/dist/src/pages/ForgotPassword.d.ts.map +1 -0
- package/dist/src/pages/ForgotPassword.js +126 -0
- package/dist/src/pages/ForgotPassword.js.map +1 -0
- package/dist/src/pages/Login.d.ts.map +1 -1
- package/dist/src/pages/Login.js +13 -1
- package/dist/src/pages/Login.js.map +1 -1
- package/dist/src/pages/PasswordReset.d.ts +4 -0
- package/dist/src/pages/PasswordReset.d.ts.map +1 -0
- package/dist/src/pages/PasswordReset.js +226 -0
- package/dist/src/pages/PasswordReset.js.map +1 -0
- package/generated/index.ts +11 -8
- package/package.json +7 -4
- package/src/pages/ForgotPassword.tsx +67 -0
- package/src/pages/Login.tsx +11 -0
- package/src/pages/PasswordReset.tsx +159 -0
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,14 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## [1.0.36](https://github.com/proteinjs/user/compare/@proteinjs/user-ui@1.0.35...@proteinjs/user-ui@1.0.36) (2024-07-12)
|
|
7
|
+
|
|
8
|
+
**Note:** Version bump only for package @proteinjs/user-ui
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
6
14
|
## [1.0.27](https://github.com/proteinjs/user/compare/@proteinjs/user-ui@1.0.26...@proteinjs/user-ui@1.0.27) (2024-06-27)
|
|
7
15
|
|
|
8
16
|
**Note:** Version bump only for package @proteinjs/user-ui
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023 Brent Bahry
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../generated/index.ts"],"names":[],"mappings":"AAAA,oCAAoC;AAEpC,OAAO,uBAAuB,CAAC;AAC/B,OAAO,uBAAuB,CAAC;AAC/B,OAAO,eAAe,CAAC;AACvB,OAAO,iBAAiB,CAAC;AACzB,OAAO,QAAQ,CAAC;AAChB,OAAO,OAAO,CAAC;AACf,OAAO,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../generated/index.ts"],"names":[],"mappings":"AAAA,oCAAoC;AAEpC,OAAO,qBAAqB,CAAC;AAC7B,OAAO,eAAe,CAAC;AACvB,OAAO,uBAAuB,CAAC;AAC/B,OAAO,uBAAuB,CAAC;AAC/B,OAAO,eAAe,CAAC;AACvB,OAAO,iBAAiB,CAAC;AACzB,OAAO,QAAQ,CAAC;AAChB,OAAO,OAAO,CAAC;AACf,OAAO,WAAW,CAAC;AA6BnB,cAAc,UAAU,CAAC"}
|
package/dist/generated/index.js
CHANGED
|
@@ -15,6 +15,8 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
15
15
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
16
16
|
};
|
|
17
17
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
require("@mui/icons-material");
|
|
19
|
+
require("@mui/material");
|
|
18
20
|
require("@proteinjs/reflection");
|
|
19
21
|
require("@proteinjs/server-api");
|
|
20
22
|
require("@proteinjs/ui");
|
|
@@ -23,12 +25,16 @@ require("moment");
|
|
|
23
25
|
require("react");
|
|
24
26
|
require("react-dom");
|
|
25
27
|
/** Generate Source Graph */
|
|
26
|
-
var sourceGraph = "{\"options\":{\"directed\":true,\"multigraph\":false,\"compound\":false},\"nodes\":[{\"v\":\"/Omit\"},{\"v\":\"@proteinjs/user-ui/
|
|
28
|
+
var sourceGraph = "{\"options\":{\"directed\":true,\"multigraph\":false,\"compound\":false},\"nodes\":[{\"v\":\"/Omit\"},{\"v\":\"@proteinjs/user-ui/forgotPasswordPage\",\"value\":{\"packageName\":\"@proteinjs/user-ui\",\"name\":\"forgotPasswordPage\",\"filePath\":\"/home/runner/work/user/user/packages/ui/src/pages/ForgotPassword.tsx\",\"qualifiedName\":\"@proteinjs/user-ui/forgotPasswordPage\",\"type\":{\"packageName\":\"@proteinjs/ui\",\"name\":\"Page\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/ui/Page\",\"typeParameters\":[],\"directParents\":[{\"packageName\":\"@proteinjs/ui\",\"name\":\"Page\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/ui/Page\",\"typeParameters\":[],\"directParents\":null}]},\"isExported\":true,\"isConst\":true,\"sourceType\":0}},{\"v\":\"@proteinjs/ui/Page\"},{\"v\":\"@proteinjs/user-ui/loginPage\",\"value\":{\"packageName\":\"@proteinjs/user-ui\",\"name\":\"loginPage\",\"filePath\":\"/home/runner/work/user/user/packages/ui/src/pages/Login.tsx\",\"qualifiedName\":\"@proteinjs/user-ui/loginPage\",\"type\":{\"packageName\":\"@proteinjs/ui\",\"name\":\"Page\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/ui/Page\",\"typeParameters\":[],\"directParents\":[{\"packageName\":\"@proteinjs/ui\",\"name\":\"Page\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/ui/Page\",\"typeParameters\":[],\"directParents\":null}]},\"isExported\":true,\"isConst\":true,\"sourceType\":0}},{\"v\":\"@proteinjs/user-ui/passwordResetPage\",\"value\":{\"packageName\":\"@proteinjs/user-ui\",\"name\":\"passwordResetPage\",\"filePath\":\"/home/runner/work/user/user/packages/ui/src/pages/PasswordReset.tsx\",\"qualifiedName\":\"@proteinjs/user-ui/passwordResetPage\",\"type\":{\"packageName\":\"@proteinjs/ui\",\"name\":\"Page\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/ui/Page\",\"typeParameters\":[],\"directParents\":[{\"packageName\":\"@proteinjs/ui\",\"name\":\"Page\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/ui/Page\",\"typeParameters\":[],\"directParents\":null}]},\"isExported\":true,\"isConst\":true,\"sourceType\":0}},{\"v\":\"@proteinjs/user-ui/signupPage\",\"value\":{\"packageName\":\"@proteinjs/user-ui\",\"name\":\"signupPage\",\"filePath\":\"/home/runner/work/user/user/packages/ui/src/pages/Signup.tsx\",\"qualifiedName\":\"@proteinjs/user-ui/signupPage\",\"type\":{\"packageName\":\"@proteinjs/ui\",\"name\":\"Page\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/ui/Page\",\"typeParameters\":[],\"directParents\":[{\"packageName\":\"@proteinjs/ui\",\"name\":\"Page\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/ui/Page\",\"typeParameters\":[],\"directParents\":null}]},\"isExported\":true,\"isConst\":true,\"sourceType\":0}}],\"edges\":[{\"v\":\"@proteinjs/user-ui/forgotPasswordPage\",\"w\":\"@proteinjs/ui/Page\",\"value\":\"has type\"},{\"v\":\"@proteinjs/user-ui/loginPage\",\"w\":\"@proteinjs/ui/Page\",\"value\":\"has type\"},{\"v\":\"@proteinjs/user-ui/passwordResetPage\",\"w\":\"@proteinjs/ui/Page\",\"value\":\"has type\"},{\"v\":\"@proteinjs/user-ui/signupPage\",\"w\":\"@proteinjs/ui/Page\",\"value\":\"has type\"}]}";
|
|
27
29
|
/** Generate Source Links */
|
|
30
|
+
var ForgotPassword_1 = require("../src/pages/ForgotPassword");
|
|
28
31
|
var Login_1 = require("../src/pages/Login");
|
|
32
|
+
var PasswordReset_1 = require("../src/pages/PasswordReset");
|
|
29
33
|
var Signup_1 = require("../src/pages/Signup");
|
|
30
34
|
var sourceLinks = {
|
|
35
|
+
'@proteinjs/user-ui/forgotPasswordPage': ForgotPassword_1.forgotPasswordPage,
|
|
31
36
|
'@proteinjs/user-ui/loginPage': Login_1.loginPage,
|
|
37
|
+
'@proteinjs/user-ui/passwordResetPage': PasswordReset_1.passwordResetPage,
|
|
32
38
|
'@proteinjs/user-ui/signupPage': Signup_1.signupPage,
|
|
33
39
|
};
|
|
34
40
|
/** Load Source Graph and Links */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../generated/index.ts"],"names":[],"mappings":";AAAA,oCAAoC;;;;;;;;;;;;;;;;AAEpC,iCAA+B;AAC/B,iCAA+B;AAC/B,yBAAuB;AACvB,2BAAyB;AACzB,kBAAgB;AAChB,iBAAe;AACf,qBAAmB;AAGnB,4BAA4B;AAE5B,IAAM,WAAW,GAAG,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../generated/index.ts"],"names":[],"mappings":";AAAA,oCAAoC;;;;;;;;;;;;;;;;AAEpC,+BAA6B;AAC7B,yBAAuB;AACvB,iCAA+B;AAC/B,iCAA+B;AAC/B,yBAAuB;AACvB,2BAAyB;AACzB,kBAAgB;AAChB,iBAAe;AACf,qBAAmB;AAGnB,4BAA4B;AAE5B,IAAM,WAAW,GAAG,8gGAA8gG,CAAC;AAGniG,4BAA4B;AAE5B,8DAAiE;AACjE,4CAA+C;AAC/C,4DAA+D;AAC/D,8CAAiD;AAEjD,IAAM,WAAW,GAAG;IACnB,uCAAuC,EAAE,mCAAkB;IAC3D,8BAA8B,EAAE,iBAAS;IACzC,sCAAsC,EAAE,iCAAiB;IACzD,+BAA+B,EAAE,mBAAU;CAC3C,CAAC;AAGF,kCAAkC;AAElC,oDAAyD;AACzD,6BAAgB,CAAC,KAAK,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;AAGjD,2CAAyB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ForgotPassword.d.ts","sourceRoot":"","sources":["../../../src/pages/ForgotPassword.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAkD,MAAM,eAAe,CAAC;AAIrF,eAAO,MAAM,kBAAkB,0BAA0B,CAAC;AAC1D,eAAO,MAAM,kBAAkB,EAAE,IAgBhC,CAAC"}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __extends = (this && this.__extends) || (function () {
|
|
3
|
+
var extendStatics = function (d, b) {
|
|
4
|
+
extendStatics = Object.setPrototypeOf ||
|
|
5
|
+
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
|
6
|
+
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
|
7
|
+
return extendStatics(d, b);
|
|
8
|
+
};
|
|
9
|
+
return function (d, b) {
|
|
10
|
+
if (typeof b !== "function" && b !== null)
|
|
11
|
+
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
|
12
|
+
extendStatics(d, b);
|
|
13
|
+
function __() { this.constructor = d; }
|
|
14
|
+
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
15
|
+
};
|
|
16
|
+
})();
|
|
17
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
18
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
19
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
20
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
21
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
22
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
23
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
24
|
+
});
|
|
25
|
+
};
|
|
26
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
27
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
28
|
+
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
29
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
30
|
+
function step(op) {
|
|
31
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
32
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
33
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
34
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
35
|
+
switch (op[0]) {
|
|
36
|
+
case 0: case 1: t = op; break;
|
|
37
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
38
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
39
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
40
|
+
default:
|
|
41
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
42
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
43
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
44
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
45
|
+
if (t[2]) _.ops.pop();
|
|
46
|
+
_.trys.pop(); continue;
|
|
47
|
+
}
|
|
48
|
+
op = body.call(thisArg, _);
|
|
49
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
50
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
54
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
55
|
+
};
|
|
56
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
57
|
+
exports.forgotPasswordPage = exports.forgotPasswordPath = void 0;
|
|
58
|
+
var react_1 = __importDefault(require("react"));
|
|
59
|
+
var ui_1 = require("@proteinjs/ui");
|
|
60
|
+
var user_1 = require("@proteinjs/user");
|
|
61
|
+
var PasswordReset_1 = require("./PasswordReset");
|
|
62
|
+
exports.forgotPasswordPath = 'login/forgot-password';
|
|
63
|
+
exports.forgotPasswordPage = {
|
|
64
|
+
name: 'Forgot Password',
|
|
65
|
+
path: exports.forgotPasswordPath,
|
|
66
|
+
auth: {
|
|
67
|
+
public: true,
|
|
68
|
+
},
|
|
69
|
+
component: function () { return (react_1.default.createElement(ui_1.FormPage, null,
|
|
70
|
+
react_1.default.createElement(ui_1.Form, { name: 'Forgot Password', createFields: function () { return new ForgotPasswordFields(); }, fieldLayout: ['email'], buttons: buttons }))); },
|
|
71
|
+
};
|
|
72
|
+
var ForgotPasswordFields = /** @class */ (function (_super) {
|
|
73
|
+
__extends(ForgotPasswordFields, _super);
|
|
74
|
+
function ForgotPasswordFields() {
|
|
75
|
+
var _this = _super !== null && _super.apply(this, arguments) || this;
|
|
76
|
+
_this.email = (0, ui_1.textField)({
|
|
77
|
+
name: 'email',
|
|
78
|
+
});
|
|
79
|
+
return _this;
|
|
80
|
+
}
|
|
81
|
+
ForgotPasswordFields.create = function () {
|
|
82
|
+
return new ForgotPasswordFields();
|
|
83
|
+
};
|
|
84
|
+
return ForgotPasswordFields;
|
|
85
|
+
}(ui_1.Fields));
|
|
86
|
+
var buttons = {
|
|
87
|
+
submit: {
|
|
88
|
+
name: 'Submit',
|
|
89
|
+
style: {
|
|
90
|
+
color: 'primary',
|
|
91
|
+
variant: 'contained',
|
|
92
|
+
},
|
|
93
|
+
onClick: function (fields, buttons) { return __awaiter(void 0, void 0, void 0, function () {
|
|
94
|
+
var response, body;
|
|
95
|
+
return __generator(this, function (_a) {
|
|
96
|
+
switch (_a.label) {
|
|
97
|
+
case 0: return [4 /*yield*/, fetch(user_1.routes.initiatePasswordReset.path, {
|
|
98
|
+
method: user_1.routes.initiatePasswordReset.method,
|
|
99
|
+
body: JSON.stringify({
|
|
100
|
+
email: fields.email.field.value,
|
|
101
|
+
resetPath: PasswordReset_1.passwordResetPath,
|
|
102
|
+
}),
|
|
103
|
+
redirect: 'follow',
|
|
104
|
+
credentials: 'same-origin',
|
|
105
|
+
headers: {
|
|
106
|
+
'Content-Type': 'application/json',
|
|
107
|
+
},
|
|
108
|
+
})];
|
|
109
|
+
case 1:
|
|
110
|
+
response = _a.sent();
|
|
111
|
+
if (response.status != 200) {
|
|
112
|
+
throw new Error("Failed to initiate forgot password.");
|
|
113
|
+
}
|
|
114
|
+
return [4 /*yield*/, response.json()];
|
|
115
|
+
case 2:
|
|
116
|
+
body = _a.sent();
|
|
117
|
+
if (body.error) {
|
|
118
|
+
throw new Error("Failed to initiate forgot password.");
|
|
119
|
+
}
|
|
120
|
+
return [2 /*return*/, "Successfully sent an email with a link to reset your password."];
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
}); },
|
|
124
|
+
},
|
|
125
|
+
};
|
|
126
|
+
//# sourceMappingURL=ForgotPassword.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ForgotPassword.js","sourceRoot":"","sources":["../../../src/pages/ForgotPassword.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,gDAA0B;AAC1B,oCAAqF;AACrF,wCAAyC;AACzC,iDAAoD;AAEvC,QAAA,kBAAkB,GAAG,uBAAuB,CAAC;AAC7C,QAAA,kBAAkB,GAAS;IACtC,IAAI,EAAE,iBAAiB;IACvB,IAAI,EAAE,0BAAkB;IACxB,IAAI,EAAE;QACJ,MAAM,EAAE,IAAI;KACb;IACD,SAAS,EAAE,cAAM,OAAA,CACf,8BAAC,aAAQ;QACP,8BAAC,SAAI,IACH,IAAI,EAAC,iBAAiB,EACtB,YAAY,EAAE,cAAM,OAAA,IAAI,oBAAoB,EAAE,EAA1B,CAA0B,EAC9C,WAAW,EAAE,CAAC,OAAO,CAAC,EACtB,OAAO,EAAE,OAAO,GAChB,CACO,CACZ,EATgB,CAShB;CACF,CAAC;AAEF;IAAmC,wCAAM;IAAzC;QAAA,qEAQC;QAHC,WAAK,GAAG,IAAA,cAAS,EAAuB;YACtC,IAAI,EAAE,OAAO;SACd,CAAC,CAAC;;IACL,CAAC;IAPQ,2BAAM,GAAb;QACE,OAAO,IAAI,oBAAoB,EAAE,CAAC;IACpC,CAAC;IAKH,2BAAC;AAAD,CAAC,AARD,CAAmC,WAAM,GAQxC;AAED,IAAM,OAAO,GAAsC;IACjD,MAAM,EAAE;QACN,IAAI,EAAE,QAAQ;QACd,KAAK,EAAE;YACL,KAAK,EAAE,SAAS;YAChB,OAAO,EAAE,WAAW;SACrB;QACD,OAAO,EAAE,UAAO,MAA4B,EAAE,OAA0C;;;;4BACrE,qBAAM,KAAK,CAAC,aAAM,CAAC,qBAAqB,CAAC,IAAI,EAAE;4BAC9D,MAAM,EAAE,aAAM,CAAC,qBAAqB,CAAC,MAAM;4BAC3C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gCACnB,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK;gCAC/B,SAAS,EAAE,iCAAiB;6BAC7B,CAAC;4BACF,QAAQ,EAAE,QAAQ;4BAClB,WAAW,EAAE,aAAa;4BAC1B,OAAO,EAAE;gCACP,cAAc,EAAE,kBAAkB;6BACnC;yBACF,CAAC,EAAA;;wBAXI,QAAQ,GAAG,SAWf;wBACF,IAAI,QAAQ,CAAC,MAAM,IAAI,GAAG,EAAE;4BAC1B,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;yBACxD;wBAEY,qBAAM,QAAQ,CAAC,IAAI,EAAE,EAAA;;wBAA5B,IAAI,GAAG,SAAqB;wBAClC,IAAI,IAAI,CAAC,KAAK,EAAE;4BACd,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;yBACxD;wBAED,sBAAO,gEAAgE,EAAC;;;aACzE;KACF;CACF,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Login.d.ts","sourceRoot":"","sources":["../../../src/pages/Login.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAA+D,MAAM,eAAe,CAAC;AAGlG,eAAO,MAAM,SAAS,UAAU,CAAC;AACjC,eAAO,MAAM,SAAS,EAAE,
|
|
1
|
+
{"version":3,"file":"Login.d.ts","sourceRoot":"","sources":["../../../src/pages/Login.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAA+D,MAAM,eAAe,CAAC;AAGlG,eAAO,MAAM,SAAS,UAAU,CAAC;AACjC,eAAO,MAAM,SAAS,EAAE,IAiBvB,CAAC"}
|
package/dist/src/pages/Login.js
CHANGED
|
@@ -66,7 +66,7 @@ exports.loginPage = {
|
|
|
66
66
|
public: true,
|
|
67
67
|
},
|
|
68
68
|
component: function () { return (react_1.default.createElement(ui_1.FormPage, null,
|
|
69
|
-
react_1.default.createElement(ui_1.Form, { name: 'Login', createFields: function () { return new LoginFields(); }, fieldLayout: ['email', 'password'], buttons: buttons }))); },
|
|
69
|
+
react_1.default.createElement(ui_1.Form, { name: 'Login', createFields: function () { return new LoginFields(); }, fieldLayout: ['email', 'password'], buttons: buttons, maxWidth: 'xs' }))); },
|
|
70
70
|
};
|
|
71
71
|
var LoginFields = /** @class */ (function (_super) {
|
|
72
72
|
__extends(LoginFields, _super);
|
|
@@ -87,6 +87,18 @@ var LoginFields = /** @class */ (function (_super) {
|
|
|
87
87
|
return LoginFields;
|
|
88
88
|
}(ui_1.Fields));
|
|
89
89
|
var buttons = {
|
|
90
|
+
forgotPassword: {
|
|
91
|
+
name: 'Forgot password',
|
|
92
|
+
style: {
|
|
93
|
+
variant: 'text',
|
|
94
|
+
align: 'left',
|
|
95
|
+
},
|
|
96
|
+
redirect: function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
97
|
+
return __generator(this, function (_a) {
|
|
98
|
+
return [2 /*return*/, { path: '/login/forgot-password' }];
|
|
99
|
+
});
|
|
100
|
+
}); },
|
|
101
|
+
},
|
|
90
102
|
clear: ui_1.clearButton,
|
|
91
103
|
login: {
|
|
92
104
|
name: 'Login',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Login.js","sourceRoot":"","sources":["../../../src/pages/Login.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,gDAA0B;AAC1B,oCAAkG;AAClG,wCAAyC;AAE5B,QAAA,SAAS,GAAG,OAAO,CAAC;AACpB,QAAA,SAAS,GAAS;IAC7B,IAAI,EAAE,OAAO;IACb,IAAI,EAAE,iBAAS;IACf,IAAI,EAAE;QACJ,MAAM,EAAE,IAAI;KACb;IACD,SAAS,EAAE,cAAM,OAAA,CACf,8BAAC,aAAQ;QACP,8BAAC,SAAI,IACH,IAAI,EAAC,OAAO,EACZ,YAAY,EAAE,cAAM,OAAA,IAAI,WAAW,EAAE,EAAjB,CAAiB,EACrC,WAAW,EAAE,CAAC,OAAO,EAAE,UAAU,CAAC,EAClC,OAAO,EAAE,OAAO,
|
|
1
|
+
{"version":3,"file":"Login.js","sourceRoot":"","sources":["../../../src/pages/Login.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,gDAA0B;AAC1B,oCAAkG;AAClG,wCAAyC;AAE5B,QAAA,SAAS,GAAG,OAAO,CAAC;AACpB,QAAA,SAAS,GAAS;IAC7B,IAAI,EAAE,OAAO;IACb,IAAI,EAAE,iBAAS;IACf,IAAI,EAAE;QACJ,MAAM,EAAE,IAAI;KACb;IACD,SAAS,EAAE,cAAM,OAAA,CACf,8BAAC,aAAQ;QACP,8BAAC,SAAI,IACH,IAAI,EAAC,OAAO,EACZ,YAAY,EAAE,cAAM,OAAA,IAAI,WAAW,EAAE,EAAjB,CAAiB,EACrC,WAAW,EAAE,CAAC,OAAO,EAAE,UAAU,CAAC,EAClC,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,IAAI,GACd,CACO,CACZ,EAVgB,CAUhB;CACF,CAAC;AAEF;IAA0B,+BAAM;IAAhC;QAAA,qEAaC;QARC,WAAK,GAAG,IAAA,cAAS,EAAc;YAC7B,IAAI,EAAE,OAAO;SACd,CAAC,CAAC;QAEH,cAAQ,GAAG,IAAA,cAAS,EAAc;YAChC,IAAI,EAAE,UAAU;YAChB,UAAU,EAAE,IAAI;SACjB,CAAC,CAAC;;IACL,CAAC;IAZQ,kBAAM,GAAb;QACE,OAAO,IAAI,WAAW,EAAE,CAAC;IAC3B,CAAC;IAUH,kBAAC;AAAD,CAAC,AAbD,CAA0B,WAAM,GAa/B;AAED,IAAM,OAAO,GAA6B;IACxC,cAAc,EAAE;QACd,IAAI,EAAE,iBAAiB;QACvB,KAAK,EAAE;YACL,OAAO,EAAE,MAAM;YACf,KAAK,EAAE,MAAM;SACd;QACD,QAAQ,EAAE;;gBACR,sBAAO,EAAE,IAAI,EAAE,wBAAwB,EAAE,EAAC;;aAC3C;KACF;IACD,KAAK,EAAE,gBAAW;IAClB,KAAK,EAAE;QACL,IAAI,EAAE,OAAO;QACb,KAAK,EAAE;YACL,KAAK,EAAE,SAAS;YAChB,OAAO,EAAE,WAAW;SACrB;QACD,OAAO,EAAE,UAAO,MAAmB,EAAE,OAAiC;;;;4BACnD,qBAAM,KAAK,CAAC,aAAM,CAAC,KAAK,CAAC,IAAI,EAAE;4BAC9C,MAAM,EAAE,aAAM,CAAC,KAAK,CAAC,MAAM;4BAC3B,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gCACnB,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK;gCAC/B,QAAQ,EAAE,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK;6BACtC,CAAC;4BACF,QAAQ,EAAE,QAAQ;4BAClB,WAAW,EAAE,aAAa;4BAC1B,OAAO,EAAE;gCACP,cAAc,EAAE,kBAAkB;6BACnC;yBACF,CAAC,EAAA;;wBAXI,QAAQ,GAAG,SAWf;wBACF,IAAI,QAAQ,CAAC,MAAM,IAAI,GAAG,EAAE;4BAC1B,MAAM,IAAI,KAAK,CAAC,kCAA2B,QAAQ,CAAC,UAAU,CAAE,CAAC,CAAC;yBACnE;wBAEY,qBAAM,QAAQ,CAAC,IAAI,EAAE,EAAA;;wBAA5B,IAAI,GAAG,SAAqB;wBAClC,IAAI,IAAI,CAAC,KAAK,EAAE;4BACd,MAAM,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;yBAC7B;wBAED,MAAM,CAAC,QAAQ,CAAC,IAAI,GAAG,GAAG,CAAC;;;;aAC5B;KACF;CACF,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PasswordReset.d.ts","sourceRoot":"","sources":["../../../src/pages/PasswordReset.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAkD,MAAM,eAAe,CAAC;AAIrF,eAAO,MAAM,iBAAiB,yBAAyB,CAAC;AA6HxD,eAAO,MAAM,iBAAiB,EAAE,IAO/B,CAAC"}
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __extends = (this && this.__extends) || (function () {
|
|
3
|
+
var extendStatics = function (d, b) {
|
|
4
|
+
extendStatics = Object.setPrototypeOf ||
|
|
5
|
+
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
|
6
|
+
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
|
7
|
+
return extendStatics(d, b);
|
|
8
|
+
};
|
|
9
|
+
return function (d, b) {
|
|
10
|
+
if (typeof b !== "function" && b !== null)
|
|
11
|
+
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
|
12
|
+
extendStatics(d, b);
|
|
13
|
+
function __() { this.constructor = d; }
|
|
14
|
+
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
15
|
+
};
|
|
16
|
+
})();
|
|
17
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
18
|
+
if (k2 === undefined) k2 = k;
|
|
19
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
20
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
21
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
22
|
+
}
|
|
23
|
+
Object.defineProperty(o, k2, desc);
|
|
24
|
+
}) : (function(o, m, k, k2) {
|
|
25
|
+
if (k2 === undefined) k2 = k;
|
|
26
|
+
o[k2] = m[k];
|
|
27
|
+
}));
|
|
28
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
29
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
30
|
+
}) : function(o, v) {
|
|
31
|
+
o["default"] = v;
|
|
32
|
+
});
|
|
33
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
34
|
+
if (mod && mod.__esModule) return mod;
|
|
35
|
+
var result = {};
|
|
36
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
37
|
+
__setModuleDefault(result, mod);
|
|
38
|
+
return result;
|
|
39
|
+
};
|
|
40
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
41
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
42
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
43
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
44
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
45
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
46
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
47
|
+
});
|
|
48
|
+
};
|
|
49
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
50
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
51
|
+
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
52
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
53
|
+
function step(op) {
|
|
54
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
55
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
56
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
57
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
58
|
+
switch (op[0]) {
|
|
59
|
+
case 0: case 1: t = op; break;
|
|
60
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
61
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
62
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
63
|
+
default:
|
|
64
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
65
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
66
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
67
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
68
|
+
if (t[2]) _.ops.pop();
|
|
69
|
+
_.trys.pop(); continue;
|
|
70
|
+
}
|
|
71
|
+
op = body.call(thisArg, _);
|
|
72
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
73
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
77
|
+
exports.passwordResetPage = exports.passwordResetPath = void 0;
|
|
78
|
+
var react_1 = __importStar(require("react"));
|
|
79
|
+
var ui_1 = require("@proteinjs/ui");
|
|
80
|
+
var user_1 = require("@proteinjs/user");
|
|
81
|
+
var material_1 = require("@mui/material");
|
|
82
|
+
exports.passwordResetPath = 'login/password-reset';
|
|
83
|
+
var PasswordResetComponent = function () {
|
|
84
|
+
var _a = (0, react_1.useState)(''), token = _a[0], setToken = _a[1];
|
|
85
|
+
var _b = (0, react_1.useState)(false), isValidating = _b[0], setIsValidating = _b[1];
|
|
86
|
+
var _c = (0, react_1.useState)(null), validationError = _c[0], setValidationError = _c[1];
|
|
87
|
+
var _d = (0, react_1.useState)(false), resetSuccess = _d[0], setResetSuccess = _d[1];
|
|
88
|
+
var buttons = {
|
|
89
|
+
submit: {
|
|
90
|
+
name: 'Reset Password',
|
|
91
|
+
style: {
|
|
92
|
+
color: 'primary',
|
|
93
|
+
variant: 'contained',
|
|
94
|
+
},
|
|
95
|
+
onClick: function (fields) { return __awaiter(void 0, void 0, void 0, function () {
|
|
96
|
+
var response;
|
|
97
|
+
return __generator(this, function (_a) {
|
|
98
|
+
switch (_a.label) {
|
|
99
|
+
case 0:
|
|
100
|
+
if (fields.newPassword.field.value !== fields.confirmPassword.field.value) {
|
|
101
|
+
throw new Error('Passwords do not match');
|
|
102
|
+
}
|
|
103
|
+
return [4 /*yield*/, fetch(user_1.routes.executePasswordReset.path, {
|
|
104
|
+
method: user_1.routes.executePasswordReset.method,
|
|
105
|
+
body: JSON.stringify({
|
|
106
|
+
token: fields.token.field.value,
|
|
107
|
+
newPassword: fields.newPassword.field.value,
|
|
108
|
+
}),
|
|
109
|
+
credentials: 'same-origin',
|
|
110
|
+
headers: {
|
|
111
|
+
'Content-Type': 'application/json',
|
|
112
|
+
},
|
|
113
|
+
})];
|
|
114
|
+
case 1:
|
|
115
|
+
response = _a.sent();
|
|
116
|
+
if (response.status !== 200) {
|
|
117
|
+
throw new Error('Failed to reset password');
|
|
118
|
+
}
|
|
119
|
+
setResetSuccess(true);
|
|
120
|
+
return [2 /*return*/, 'Your password has been successfully reset. You can now log in with your new password.'];
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
}); },
|
|
124
|
+
},
|
|
125
|
+
};
|
|
126
|
+
(0, react_1.useEffect)(function () {
|
|
127
|
+
var searchParams = new URLSearchParams(window.location.search);
|
|
128
|
+
var resetToken = searchParams.get('token');
|
|
129
|
+
if (resetToken) {
|
|
130
|
+
setToken(resetToken);
|
|
131
|
+
validateToken(resetToken);
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
setValidationError('No reset token provided');
|
|
135
|
+
}
|
|
136
|
+
}, []);
|
|
137
|
+
var validateToken = function (token) { return __awaiter(void 0, void 0, void 0, function () {
|
|
138
|
+
var response, data, error_1;
|
|
139
|
+
return __generator(this, function (_a) {
|
|
140
|
+
switch (_a.label) {
|
|
141
|
+
case 0:
|
|
142
|
+
setIsValidating(true);
|
|
143
|
+
_a.label = 1;
|
|
144
|
+
case 1:
|
|
145
|
+
_a.trys.push([1, 4, 5, 6]);
|
|
146
|
+
return [4 /*yield*/, fetch("".concat(user_1.routes.validateResetToken.path, "?token=").concat(token), {
|
|
147
|
+
method: user_1.routes.validateResetToken.method,
|
|
148
|
+
credentials: 'same-origin',
|
|
149
|
+
})];
|
|
150
|
+
case 2:
|
|
151
|
+
response = _a.sent();
|
|
152
|
+
return [4 /*yield*/, response.json()];
|
|
153
|
+
case 3:
|
|
154
|
+
data = _a.sent();
|
|
155
|
+
if (!data.isValid) {
|
|
156
|
+
setValidationError(data.message || 'Invalid or expired token');
|
|
157
|
+
}
|
|
158
|
+
return [3 /*break*/, 6];
|
|
159
|
+
case 4:
|
|
160
|
+
error_1 = _a.sent();
|
|
161
|
+
setValidationError('An error occurred while validating the token');
|
|
162
|
+
return [3 /*break*/, 6];
|
|
163
|
+
case 5:
|
|
164
|
+
setIsValidating(false);
|
|
165
|
+
return [7 /*endfinally*/];
|
|
166
|
+
case 6: return [2 /*return*/];
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
}); };
|
|
170
|
+
if (isValidating) {
|
|
171
|
+
return react_1.default.createElement(ui_1.FormPage, null, "Validating reset token...");
|
|
172
|
+
}
|
|
173
|
+
if (validationError) {
|
|
174
|
+
return (react_1.default.createElement(ui_1.FormPage, null,
|
|
175
|
+
react_1.default.createElement(material_1.Stack, { alignItems: 'center', spacing: 3 },
|
|
176
|
+
react_1.default.createElement(material_1.Typography, { variant: 'h1', gutterBottom: true }, "Invalid password reset link"),
|
|
177
|
+
react_1.default.createElement(material_1.Typography, { variant: 'body1', gutterBottom: true }, "The password reset link is invalid or has expired. Please request a new password reset."),
|
|
178
|
+
react_1.default.createElement(material_1.Button, { variant: 'contained', color: 'primary', href: '/login' }, "Go to login page"))));
|
|
179
|
+
}
|
|
180
|
+
if (resetSuccess) {
|
|
181
|
+
return (react_1.default.createElement(ui_1.FormPage, null,
|
|
182
|
+
react_1.default.createElement(material_1.Stack, { alignItems: 'center', spacing: 3 },
|
|
183
|
+
react_1.default.createElement(material_1.Typography, { variant: 'h6', gutterBottom: true }, "Password reset successful"),
|
|
184
|
+
react_1.default.createElement(material_1.Typography, { variant: 'body1', gutterBottom: true }, "Your password has been successfully reset. You can now log in with your new password."),
|
|
185
|
+
react_1.default.createElement(material_1.Button, { variant: 'contained', color: 'primary', href: '/login' }, "Go to login page"))));
|
|
186
|
+
}
|
|
187
|
+
return (react_1.default.createElement(ui_1.FormPage, null,
|
|
188
|
+
react_1.default.createElement(ui_1.Form, { name: 'Reset Password', createFields: function () { return new ResetPasswordFields(); }, fieldLayout: ['newPassword', 'confirmPassword'], buttons: buttons, onLoad: function (fields) { return __awaiter(void 0, void 0, void 0, function () {
|
|
189
|
+
return __generator(this, function (_a) {
|
|
190
|
+
fields.token.field.value = token;
|
|
191
|
+
return [2 /*return*/];
|
|
192
|
+
});
|
|
193
|
+
}); } })));
|
|
194
|
+
};
|
|
195
|
+
exports.passwordResetPage = {
|
|
196
|
+
name: 'Reset Password',
|
|
197
|
+
path: exports.passwordResetPath,
|
|
198
|
+
auth: {
|
|
199
|
+
public: true,
|
|
200
|
+
},
|
|
201
|
+
component: PasswordResetComponent,
|
|
202
|
+
};
|
|
203
|
+
var ResetPasswordFields = /** @class */ (function (_super) {
|
|
204
|
+
__extends(ResetPasswordFields, _super);
|
|
205
|
+
function ResetPasswordFields() {
|
|
206
|
+
var _this = _super !== null && _super.apply(this, arguments) || this;
|
|
207
|
+
_this.token = (0, ui_1.textField)({
|
|
208
|
+
name: 'token',
|
|
209
|
+
accessibility: { hidden: true },
|
|
210
|
+
});
|
|
211
|
+
_this.newPassword = (0, ui_1.textField)({
|
|
212
|
+
name: 'New Password',
|
|
213
|
+
isPassword: true,
|
|
214
|
+
});
|
|
215
|
+
_this.confirmPassword = (0, ui_1.textField)({
|
|
216
|
+
name: 'Confirm New Password',
|
|
217
|
+
isPassword: true,
|
|
218
|
+
});
|
|
219
|
+
return _this;
|
|
220
|
+
}
|
|
221
|
+
ResetPasswordFields.create = function () {
|
|
222
|
+
return new ResetPasswordFields();
|
|
223
|
+
};
|
|
224
|
+
return ResetPasswordFields;
|
|
225
|
+
}(ui_1.Fields));
|
|
226
|
+
//# sourceMappingURL=PasswordReset.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PasswordReset.js","sourceRoot":"","sources":["../../../src/pages/PasswordReset.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,6CAAmD;AACnD,oCAAqF;AACrF,wCAAyC;AACzC,0CAA0D;AAE7C,QAAA,iBAAiB,GAAG,sBAAsB,CAAC;AACxD,IAAM,sBAAsB,GAAa;IACjC,IAAA,KAAoB,IAAA,gBAAQ,EAAC,EAAE,CAAC,EAA/B,KAAK,QAAA,EAAE,QAAQ,QAAgB,CAAC;IACjC,IAAA,KAAkC,IAAA,gBAAQ,EAAC,KAAK,CAAC,EAAhD,YAAY,QAAA,EAAE,eAAe,QAAmB,CAAC;IAClD,IAAA,KAAwC,IAAA,gBAAQ,EAAgB,IAAI,CAAC,EAApE,eAAe,QAAA,EAAE,kBAAkB,QAAiC,CAAC;IACtE,IAAA,KAAkC,IAAA,gBAAQ,EAAC,KAAK,CAAC,EAAhD,YAAY,QAAA,EAAE,eAAe,QAAmB,CAAC;IAExD,IAAM,OAAO,GAAqC;QAChD,MAAM,EAAE;YACN,IAAI,EAAE,gBAAgB;YACtB,KAAK,EAAE;gBACL,KAAK,EAAE,SAAS;gBAChB,OAAO,EAAE,WAAW;aACrB;YACD,OAAO,EAAE,UAAO,MAA2B;;;;;4BACzC,IAAI,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,KAAK,KAAK,MAAM,CAAC,eAAe,CAAC,KAAK,CAAC,KAAK,EAAE;gCACzE,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;6BAC3C;4BAEgB,qBAAM,KAAK,CAAC,aAAM,CAAC,oBAAoB,CAAC,IAAI,EAAE;oCAC7D,MAAM,EAAE,aAAM,CAAC,oBAAoB,CAAC,MAAM;oCAC1C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;wCACnB,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK;wCAC/B,WAAW,EAAE,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,KAAK;qCAC5C,CAAC;oCACF,WAAW,EAAE,aAAa;oCAC1B,OAAO,EAAE;wCACP,cAAc,EAAE,kBAAkB;qCACnC;iCACF,CAAC,EAAA;;4BAVI,QAAQ,GAAG,SAUf;4BAEF,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE;gCAC3B,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;6BAC7C;4BAED,eAAe,CAAC,IAAI,CAAC,CAAC;4BACtB,sBAAO,uFAAuF,EAAC;;;iBAChG;SACF;KACF,CAAC;IAEF,IAAA,iBAAS,EAAC;QACR,IAAM,YAAY,GAAG,IAAI,eAAe,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QACjE,IAAM,UAAU,GAAG,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAC7C,IAAI,UAAU,EAAE;YACd,QAAQ,CAAC,UAAU,CAAC,CAAC;YACrB,aAAa,CAAC,UAAU,CAAC,CAAC;SAC3B;aAAM;YACL,kBAAkB,CAAC,yBAAyB,CAAC,CAAC;SAC/C;IACH,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,IAAM,aAAa,GAAG,UAAO,KAAa;;;;;oBACxC,eAAe,CAAC,IAAI,CAAC,CAAC;;;;oBAEH,qBAAM,KAAK,CAAC,UAAG,aAAM,CAAC,kBAAkB,CAAC,IAAI,oBAAU,KAAK,CAAE,EAAE;4BAC/E,MAAM,EAAE,aAAM,CAAC,kBAAkB,CAAC,MAAM;4BACxC,WAAW,EAAE,aAAa;yBAC3B,CAAC,EAAA;;oBAHI,QAAQ,GAAG,SAGf;oBACW,qBAAM,QAAQ,CAAC,IAAI,EAAE,EAAA;;oBAA5B,IAAI,GAAG,SAAqB;oBAClC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;wBACjB,kBAAkB,CAAC,IAAI,CAAC,OAAO,IAAI,0BAA0B,CAAC,CAAC;qBAChE;;;;oBAED,kBAAkB,CAAC,8CAA8C,CAAC,CAAC;;;oBAEnE,eAAe,CAAC,KAAK,CAAC,CAAC;;;;;SAE1B,CAAC;IAEF,IAAI,YAAY,EAAE;QAChB,OAAO,8BAAC,aAAQ,oCAAqC,CAAC;KACvD;IAED,IAAI,eAAe,EAAE;QACnB,OAAO,CACL,8BAAC,aAAQ;YACP,8BAAC,gBAAK,IAAC,UAAU,EAAC,QAAQ,EAAC,OAAO,EAAE,CAAC;gBACnC,8BAAC,qBAAU,IAAC,OAAO,EAAC,IAAI,EAAC,YAAY,wCAExB;gBACb,8BAAC,qBAAU,IAAC,OAAO,EAAC,OAAO,EAAC,YAAY,oGAE3B;gBACb,8BAAC,iBAAM,IAAC,OAAO,EAAC,WAAW,EAAC,KAAK,EAAC,SAAS,EAAC,IAAI,EAAC,QAAQ,uBAEhD,CACH,CACC,CACZ,CAAC;KACH;IAED,IAAI,YAAY,EAAE;QAChB,OAAO,CACL,8BAAC,aAAQ;YACP,8BAAC,gBAAK,IAAC,UAAU,EAAC,QAAQ,EAAC,OAAO,EAAE,CAAC;gBACnC,8BAAC,qBAAU,IAAC,OAAO,EAAC,IAAI,EAAC,YAAY,sCAExB;gBACb,8BAAC,qBAAU,IAAC,OAAO,EAAC,OAAO,EAAC,YAAY,kGAE3B;gBACb,8BAAC,iBAAM,IAAC,OAAO,EAAC,WAAW,EAAC,KAAK,EAAC,SAAS,EAAC,IAAI,EAAC,QAAQ,uBAEhD,CACH,CACC,CACZ,CAAC;KACH;IAED,OAAO,CACL,8BAAC,aAAQ;QACP,8BAAC,SAAI,IACH,IAAI,EAAC,gBAAgB,EACrB,YAAY,EAAE,cAAM,OAAA,IAAI,mBAAmB,EAAE,EAAzB,CAAyB,EAC7C,WAAW,EAAE,CAAC,aAAa,EAAE,iBAAiB,CAAC,EAC/C,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,UAAO,MAAM;;oBACnB,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC;;;iBAClC,GACD,CACO,CACZ,CAAC;AACJ,CAAC,CAAC;AAEW,QAAA,iBAAiB,GAAS;IACrC,IAAI,EAAE,gBAAgB;IACtB,IAAI,EAAE,yBAAiB;IACvB,IAAI,EAAE;QACJ,MAAM,EAAE,IAAI;KACb;IACD,SAAS,EAAE,sBAAsB;CAClC,CAAC;AAEF;IAAkC,uCAAM;IAAxC;QAAA,qEAmBC;QAdC,WAAK,GAAG,IAAA,cAAS,EAAsB;YACrC,IAAI,EAAE,OAAO;YACb,aAAa,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE;SAChC,CAAC,CAAC;QAEH,iBAAW,GAAG,IAAA,cAAS,EAAsB;YAC3C,IAAI,EAAE,cAAc;YACpB,UAAU,EAAE,IAAI;SACjB,CAAC,CAAC;QAEH,qBAAe,GAAG,IAAA,cAAS,EAAsB;YAC/C,IAAI,EAAE,sBAAsB;YAC5B,UAAU,EAAE,IAAI;SACjB,CAAC,CAAC;;IACL,CAAC;IAlBQ,0BAAM,GAAb;QACE,OAAO,IAAI,mBAAmB,EAAE,CAAC;IACnC,CAAC;IAgBH,0BAAC;AAAD,CAAC,AAnBD,CAAkC,WAAM,GAmBvC"}
|
package/generated/index.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
/** Load Dependency Source Graphs */
|
|
2
2
|
|
|
3
|
+
import '@mui/icons-material';
|
|
4
|
+
import '@mui/material';
|
|
3
5
|
import '@proteinjs/reflection';
|
|
4
6
|
import '@proteinjs/server-api';
|
|
5
7
|
import '@proteinjs/ui';
|
|
@@ -8,27 +10,28 @@ import 'moment';
|
|
|
8
10
|
import 'react';
|
|
9
11
|
import 'react-dom';
|
|
10
12
|
|
|
11
|
-
|
|
12
13
|
/** Generate Source Graph */
|
|
13
14
|
|
|
14
|
-
const sourceGraph =
|
|
15
|
-
|
|
15
|
+
const sourceGraph =
|
|
16
|
+
'{"options":{"directed":true,"multigraph":false,"compound":false},"nodes":[{"v":"/Omit"},{"v":"@proteinjs/user-ui/forgotPasswordPage","value":{"packageName":"@proteinjs/user-ui","name":"forgotPasswordPage","filePath":"/home/runner/work/user/user/packages/ui/src/pages/ForgotPassword.tsx","qualifiedName":"@proteinjs/user-ui/forgotPasswordPage","type":{"packageName":"@proteinjs/ui","name":"Page","filePath":null,"qualifiedName":"@proteinjs/ui/Page","typeParameters":[],"directParents":[{"packageName":"@proteinjs/ui","name":"Page","filePath":null,"qualifiedName":"@proteinjs/ui/Page","typeParameters":[],"directParents":null}]},"isExported":true,"isConst":true,"sourceType":0}},{"v":"@proteinjs/ui/Page"},{"v":"@proteinjs/user-ui/loginPage","value":{"packageName":"@proteinjs/user-ui","name":"loginPage","filePath":"/home/runner/work/user/user/packages/ui/src/pages/Login.tsx","qualifiedName":"@proteinjs/user-ui/loginPage","type":{"packageName":"@proteinjs/ui","name":"Page","filePath":null,"qualifiedName":"@proteinjs/ui/Page","typeParameters":[],"directParents":[{"packageName":"@proteinjs/ui","name":"Page","filePath":null,"qualifiedName":"@proteinjs/ui/Page","typeParameters":[],"directParents":null}]},"isExported":true,"isConst":true,"sourceType":0}},{"v":"@proteinjs/user-ui/passwordResetPage","value":{"packageName":"@proteinjs/user-ui","name":"passwordResetPage","filePath":"/home/runner/work/user/user/packages/ui/src/pages/PasswordReset.tsx","qualifiedName":"@proteinjs/user-ui/passwordResetPage","type":{"packageName":"@proteinjs/ui","name":"Page","filePath":null,"qualifiedName":"@proteinjs/ui/Page","typeParameters":[],"directParents":[{"packageName":"@proteinjs/ui","name":"Page","filePath":null,"qualifiedName":"@proteinjs/ui/Page","typeParameters":[],"directParents":null}]},"isExported":true,"isConst":true,"sourceType":0}},{"v":"@proteinjs/user-ui/signupPage","value":{"packageName":"@proteinjs/user-ui","name":"signupPage","filePath":"/home/runner/work/user/user/packages/ui/src/pages/Signup.tsx","qualifiedName":"@proteinjs/user-ui/signupPage","type":{"packageName":"@proteinjs/ui","name":"Page","filePath":null,"qualifiedName":"@proteinjs/ui/Page","typeParameters":[],"directParents":[{"packageName":"@proteinjs/ui","name":"Page","filePath":null,"qualifiedName":"@proteinjs/ui/Page","typeParameters":[],"directParents":null}]},"isExported":true,"isConst":true,"sourceType":0}}],"edges":[{"v":"@proteinjs/user-ui/forgotPasswordPage","w":"@proteinjs/ui/Page","value":"has type"},{"v":"@proteinjs/user-ui/loginPage","w":"@proteinjs/ui/Page","value":"has type"},{"v":"@proteinjs/user-ui/passwordResetPage","w":"@proteinjs/ui/Page","value":"has type"},{"v":"@proteinjs/user-ui/signupPage","w":"@proteinjs/ui/Page","value":"has type"}]}';
|
|
16
17
|
|
|
17
18
|
/** Generate Source Links */
|
|
18
19
|
|
|
20
|
+
import { forgotPasswordPage } from '../src/pages/ForgotPassword';
|
|
19
21
|
import { loginPage } from '../src/pages/Login';
|
|
22
|
+
import { passwordResetPage } from '../src/pages/PasswordReset';
|
|
20
23
|
import { signupPage } from '../src/pages/Signup';
|
|
21
24
|
|
|
22
25
|
const sourceLinks = {
|
|
23
|
-
|
|
24
|
-
|
|
26
|
+
'@proteinjs/user-ui/forgotPasswordPage': forgotPasswordPage,
|
|
27
|
+
'@proteinjs/user-ui/loginPage': loginPage,
|
|
28
|
+
'@proteinjs/user-ui/passwordResetPage': passwordResetPage,
|
|
29
|
+
'@proteinjs/user-ui/signupPage': signupPage,
|
|
25
30
|
};
|
|
26
31
|
|
|
27
|
-
|
|
28
32
|
/** Load Source Graph and Links */
|
|
29
33
|
|
|
30
34
|
import { SourceRepository } from '@proteinjs/reflection';
|
|
31
35
|
SourceRepository.merge(sourceGraph, sourceLinks);
|
|
32
36
|
|
|
33
|
-
|
|
34
|
-
export * from '../index';
|
|
37
|
+
export * from '../index';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@proteinjs/user-ui",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.36",
|
|
4
4
|
"description": "User ui components",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -21,10 +21,12 @@
|
|
|
21
21
|
"watch": "reflection-watch"
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
|
+
"@mui/icons-material": "5.14.11",
|
|
25
|
+
"@mui/material": "5.14.11",
|
|
24
26
|
"@proteinjs/reflection": "1.1.6",
|
|
25
27
|
"@proteinjs/server-api": "1.3.3",
|
|
26
28
|
"@proteinjs/ui": "2.2.0",
|
|
27
|
-
"@proteinjs/user": "^1.0.
|
|
29
|
+
"@proteinjs/user": "^1.0.34",
|
|
28
30
|
"moment": "2.29.4",
|
|
29
31
|
"react": "18.2.0",
|
|
30
32
|
"react-dom": "18.2.0"
|
|
@@ -42,5 +44,6 @@
|
|
|
42
44
|
"typescript": "5.2.2"
|
|
43
45
|
},
|
|
44
46
|
"main": "./dist/generated/index.js",
|
|
45
|
-
"types": "./dist/generated/index.d.ts"
|
|
46
|
-
|
|
47
|
+
"types": "./dist/generated/index.d.ts",
|
|
48
|
+
"gitHead": "392402662a3066f07526c715703f2b381c899ed3"
|
|
49
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Page, Form, Fields, textField, FormButtons, FormPage } from '@proteinjs/ui';
|
|
3
|
+
import { routes } from '@proteinjs/user';
|
|
4
|
+
import { passwordResetPath } from './PasswordReset';
|
|
5
|
+
|
|
6
|
+
export const forgotPasswordPath = 'login/forgot-password';
|
|
7
|
+
export const forgotPasswordPage: Page = {
|
|
8
|
+
name: 'Forgot Password',
|
|
9
|
+
path: forgotPasswordPath,
|
|
10
|
+
auth: {
|
|
11
|
+
public: true,
|
|
12
|
+
},
|
|
13
|
+
component: () => (
|
|
14
|
+
<FormPage>
|
|
15
|
+
<Form<ForgotPasswordFields, typeof buttons>
|
|
16
|
+
name='Forgot Password'
|
|
17
|
+
createFields={() => new ForgotPasswordFields()}
|
|
18
|
+
fieldLayout={['email']}
|
|
19
|
+
buttons={buttons}
|
|
20
|
+
/>
|
|
21
|
+
</FormPage>
|
|
22
|
+
),
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
class ForgotPasswordFields extends Fields {
|
|
26
|
+
static create() {
|
|
27
|
+
return new ForgotPasswordFields();
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
email = textField<ForgotPasswordFields>({
|
|
31
|
+
name: 'email',
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const buttons: FormButtons<ForgotPasswordFields> = {
|
|
36
|
+
submit: {
|
|
37
|
+
name: 'Submit',
|
|
38
|
+
style: {
|
|
39
|
+
color: 'primary',
|
|
40
|
+
variant: 'contained',
|
|
41
|
+
},
|
|
42
|
+
onClick: async (fields: ForgotPasswordFields, buttons: FormButtons<ForgotPasswordFields>) => {
|
|
43
|
+
const response = await fetch(routes.initiatePasswordReset.path, {
|
|
44
|
+
method: routes.initiatePasswordReset.method,
|
|
45
|
+
body: JSON.stringify({
|
|
46
|
+
email: fields.email.field.value,
|
|
47
|
+
resetPath: passwordResetPath,
|
|
48
|
+
}),
|
|
49
|
+
redirect: 'follow',
|
|
50
|
+
credentials: 'same-origin',
|
|
51
|
+
headers: {
|
|
52
|
+
'Content-Type': 'application/json',
|
|
53
|
+
},
|
|
54
|
+
});
|
|
55
|
+
if (response.status != 200) {
|
|
56
|
+
throw new Error(`Failed to initiate forgot password.`);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const body = await response.json();
|
|
60
|
+
if (body.error) {
|
|
61
|
+
throw new Error(`Failed to initiate forgot password.`);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return `Successfully sent an email with a link to reset your password.`;
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
};
|
package/src/pages/Login.tsx
CHANGED
|
@@ -16,6 +16,7 @@ export const loginPage: Page = {
|
|
|
16
16
|
createFields={() => new LoginFields()}
|
|
17
17
|
fieldLayout={['email', 'password']}
|
|
18
18
|
buttons={buttons}
|
|
19
|
+
maxWidth={'xs'}
|
|
19
20
|
/>
|
|
20
21
|
</FormPage>
|
|
21
22
|
),
|
|
@@ -37,6 +38,16 @@ class LoginFields extends Fields {
|
|
|
37
38
|
}
|
|
38
39
|
|
|
39
40
|
const buttons: FormButtons<LoginFields> = {
|
|
41
|
+
forgotPassword: {
|
|
42
|
+
name: 'Forgot password',
|
|
43
|
+
style: {
|
|
44
|
+
variant: 'text',
|
|
45
|
+
align: 'left',
|
|
46
|
+
},
|
|
47
|
+
redirect: async () => {
|
|
48
|
+
return { path: '/login/forgot-password' };
|
|
49
|
+
},
|
|
50
|
+
},
|
|
40
51
|
clear: clearButton,
|
|
41
52
|
login: {
|
|
42
53
|
name: 'Login',
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import React, { useEffect, useState } from 'react';
|
|
2
|
+
import { Page, Form, Fields, textField, FormButtons, FormPage } from '@proteinjs/ui';
|
|
3
|
+
import { routes } from '@proteinjs/user';
|
|
4
|
+
import { Button, Stack, Typography } from '@mui/material';
|
|
5
|
+
|
|
6
|
+
export const passwordResetPath = 'login/password-reset';
|
|
7
|
+
const PasswordResetComponent: React.FC = () => {
|
|
8
|
+
const [token, setToken] = useState('');
|
|
9
|
+
const [isValidating, setIsValidating] = useState(false);
|
|
10
|
+
const [validationError, setValidationError] = useState<string | null>(null);
|
|
11
|
+
const [resetSuccess, setResetSuccess] = useState(false);
|
|
12
|
+
|
|
13
|
+
const buttons: FormButtons<ResetPasswordFields> = {
|
|
14
|
+
submit: {
|
|
15
|
+
name: 'Reset Password',
|
|
16
|
+
style: {
|
|
17
|
+
color: 'primary',
|
|
18
|
+
variant: 'contained',
|
|
19
|
+
},
|
|
20
|
+
onClick: async (fields: ResetPasswordFields) => {
|
|
21
|
+
if (fields.newPassword.field.value !== fields.confirmPassword.field.value) {
|
|
22
|
+
throw new Error('Passwords do not match');
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const response = await fetch(routes.executePasswordReset.path, {
|
|
26
|
+
method: routes.executePasswordReset.method,
|
|
27
|
+
body: JSON.stringify({
|
|
28
|
+
token: fields.token.field.value,
|
|
29
|
+
newPassword: fields.newPassword.field.value,
|
|
30
|
+
}),
|
|
31
|
+
credentials: 'same-origin',
|
|
32
|
+
headers: {
|
|
33
|
+
'Content-Type': 'application/json',
|
|
34
|
+
},
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
if (response.status !== 200) {
|
|
38
|
+
throw new Error('Failed to reset password');
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
setResetSuccess(true);
|
|
42
|
+
return 'Your password has been successfully reset. You can now log in with your new password.';
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
useEffect(() => {
|
|
48
|
+
const searchParams = new URLSearchParams(window.location.search);
|
|
49
|
+
const resetToken = searchParams.get('token');
|
|
50
|
+
if (resetToken) {
|
|
51
|
+
setToken(resetToken);
|
|
52
|
+
validateToken(resetToken);
|
|
53
|
+
} else {
|
|
54
|
+
setValidationError('No reset token provided');
|
|
55
|
+
}
|
|
56
|
+
}, []);
|
|
57
|
+
|
|
58
|
+
const validateToken = async (token: string) => {
|
|
59
|
+
setIsValidating(true);
|
|
60
|
+
try {
|
|
61
|
+
const response = await fetch(`${routes.validateResetToken.path}?token=${token}`, {
|
|
62
|
+
method: routes.validateResetToken.method,
|
|
63
|
+
credentials: 'same-origin',
|
|
64
|
+
});
|
|
65
|
+
const data = await response.json();
|
|
66
|
+
if (!data.isValid) {
|
|
67
|
+
setValidationError(data.message || 'Invalid or expired token');
|
|
68
|
+
}
|
|
69
|
+
} catch (error) {
|
|
70
|
+
setValidationError('An error occurred while validating the token');
|
|
71
|
+
} finally {
|
|
72
|
+
setIsValidating(false);
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
if (isValidating) {
|
|
77
|
+
return <FormPage>Validating reset token...</FormPage>;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if (validationError) {
|
|
81
|
+
return (
|
|
82
|
+
<FormPage>
|
|
83
|
+
<Stack alignItems='center' spacing={3}>
|
|
84
|
+
<Typography variant='h1' gutterBottom>
|
|
85
|
+
Invalid password reset link
|
|
86
|
+
</Typography>
|
|
87
|
+
<Typography variant='body1' gutterBottom>
|
|
88
|
+
The password reset link is invalid or has expired. Please request a new password reset.
|
|
89
|
+
</Typography>
|
|
90
|
+
<Button variant='contained' color='primary' href='/login'>
|
|
91
|
+
Go to login page
|
|
92
|
+
</Button>
|
|
93
|
+
</Stack>
|
|
94
|
+
</FormPage>
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
if (resetSuccess) {
|
|
99
|
+
return (
|
|
100
|
+
<FormPage>
|
|
101
|
+
<Stack alignItems='center' spacing={3}>
|
|
102
|
+
<Typography variant='h6' gutterBottom>
|
|
103
|
+
Password reset successful
|
|
104
|
+
</Typography>
|
|
105
|
+
<Typography variant='body1' gutterBottom>
|
|
106
|
+
Your password has been successfully reset. You can now log in with your new password.
|
|
107
|
+
</Typography>
|
|
108
|
+
<Button variant='contained' color='primary' href='/login'>
|
|
109
|
+
Go to login page
|
|
110
|
+
</Button>
|
|
111
|
+
</Stack>
|
|
112
|
+
</FormPage>
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
return (
|
|
117
|
+
<FormPage>
|
|
118
|
+
<Form<ResetPasswordFields, typeof buttons>
|
|
119
|
+
name='Reset Password'
|
|
120
|
+
createFields={() => new ResetPasswordFields()}
|
|
121
|
+
fieldLayout={['newPassword', 'confirmPassword']}
|
|
122
|
+
buttons={buttons}
|
|
123
|
+
onLoad={async (fields) => {
|
|
124
|
+
fields.token.field.value = token;
|
|
125
|
+
}}
|
|
126
|
+
/>
|
|
127
|
+
</FormPage>
|
|
128
|
+
);
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
export const passwordResetPage: Page = {
|
|
132
|
+
name: 'Reset Password',
|
|
133
|
+
path: passwordResetPath,
|
|
134
|
+
auth: {
|
|
135
|
+
public: true,
|
|
136
|
+
},
|
|
137
|
+
component: PasswordResetComponent,
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
class ResetPasswordFields extends Fields {
|
|
141
|
+
static create() {
|
|
142
|
+
return new ResetPasswordFields();
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
token = textField<ResetPasswordFields>({
|
|
146
|
+
name: 'token',
|
|
147
|
+
accessibility: { hidden: true },
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
newPassword = textField<ResetPasswordFields>({
|
|
151
|
+
name: 'New Password',
|
|
152
|
+
isPassword: true,
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
confirmPassword = textField<ResetPasswordFields>({
|
|
156
|
+
name: 'Confirm New Password',
|
|
157
|
+
isPassword: true,
|
|
158
|
+
});
|
|
159
|
+
}
|