@adminforth/two-factors-auth 1.0.12 → 1.0.14
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/index.js +7 -19
- package/index.ts +39 -48
- package/package.json +2 -3
package/dist/index.js
CHANGED
|
@@ -40,11 +40,7 @@ export default class TwoFactorsAuthPlugin extends AdminForthPlugin {
|
|
|
40
40
|
if (!this.authResource.columns.some((col) => col.name === this.options.twoFaSecretFieldName)) {
|
|
41
41
|
throw new Error(`Column ${this.options.twoFaSecretFieldName} not found in ${this.authResource.label}`);
|
|
42
42
|
}
|
|
43
|
-
|
|
44
|
-
if (!beforeLoginConfirmation.beforeLoginConfirmation) {
|
|
45
|
-
beforeLoginConfirmation.beforeLoginConfirmation = [];
|
|
46
|
-
}
|
|
47
|
-
beforeLoginConfirmation.beforeLoginConfirmation.push((_a) => __awaiter(this, [_a], void 0, function* ({ adminUser }) {
|
|
43
|
+
this.adminforth.config.auth.beforeLoginConfirmation.push((_a) => __awaiter(this, [_a], void 0, function* ({ adminUser, response }) {
|
|
48
44
|
if (adminUser.isRoot) {
|
|
49
45
|
return { body: { loginAllowed: true }, ok: true };
|
|
50
46
|
}
|
|
@@ -60,31 +56,22 @@ export default class TwoFactorsAuthPlugin extends AdminForthPlugin {
|
|
|
60
56
|
newSecret = tempSecret.secret;
|
|
61
57
|
}
|
|
62
58
|
else {
|
|
59
|
+
const value = this.adminforth.auth.issueJWT({ userName, issuer: brandName, pk: userPk }, 'tempTotp');
|
|
60
|
+
response.setHeader('Set-Cookie', `adminforth_totpTemporaryJWT=${value}; Path=${this.adminforth.config.baseUrl || '/'}; HttpOnly; SameSite=Strict; max-age=3600; `);
|
|
63
61
|
return {
|
|
64
62
|
body: {
|
|
65
63
|
loginAllowed: false,
|
|
66
64
|
redirectTo: '/confirm2fa',
|
|
67
|
-
setCookie: [{
|
|
68
|
-
name: 'totpTemporaryJWT',
|
|
69
|
-
value: this.adminforth.auth.issueJWT({ userName, issuer: brandName, pk: userPk }, 'tempTotp'),
|
|
70
|
-
expiry: '1h',
|
|
71
|
-
httpOnly: true
|
|
72
|
-
},]
|
|
73
65
|
},
|
|
74
66
|
ok: true
|
|
75
67
|
};
|
|
76
68
|
}
|
|
77
69
|
const totpTemporaryJWT = this.adminforth.auth.issueJWT({ userName, newSecret, issuer: brandName, pk: userPk }, 'tempTotp');
|
|
70
|
+
response.setHeader('Set-Cookie', `adminforth_totpTemporaryJWT=${totpTemporaryJWT}; Path=${this.adminforth.config.baseUrl || '/'}; HttpOnly; SameSite=Strict; Expires=${new Date(Date.now() + '1h').toUTCString()} `);
|
|
78
71
|
return {
|
|
79
72
|
body: {
|
|
80
73
|
loginAllowed: false,
|
|
81
74
|
redirectTo: secret ? '/confirm2fa' : '/setup2fa',
|
|
82
|
-
setCookie: [{
|
|
83
|
-
name: 'totpTemporaryJWT',
|
|
84
|
-
value: totpTemporaryJWT,
|
|
85
|
-
expiry: '1h',
|
|
86
|
-
httpOnly: true
|
|
87
|
-
},]
|
|
88
75
|
},
|
|
89
76
|
ok: true
|
|
90
77
|
};
|
|
@@ -96,8 +83,9 @@ export default class TwoFactorsAuthPlugin extends AdminForthPlugin {
|
|
|
96
83
|
path: `/plugin/twofa/initSetup`,
|
|
97
84
|
noAuth: true,
|
|
98
85
|
handler: (server) => __awaiter(this, void 0, void 0, function* () {
|
|
86
|
+
var _a;
|
|
99
87
|
const toReturn = { totpJWT: null, status: 'ok', };
|
|
100
|
-
const totpTemporaryJWT = server.cookies
|
|
88
|
+
const totpTemporaryJWT = (_a = server.cookies.find((cookie) => cookie.key === 'adminforth_totpTemporaryJWT')) === null || _a === void 0 ? void 0 : _a.value;
|
|
101
89
|
if (totpTemporaryJWT) {
|
|
102
90
|
toReturn.totpJWT = totpTemporaryJWT;
|
|
103
91
|
}
|
|
@@ -108,7 +96,7 @@ export default class TwoFactorsAuthPlugin extends AdminForthPlugin {
|
|
|
108
96
|
method: 'POST',
|
|
109
97
|
path: `/plugin/twofa/confirmSetup`,
|
|
110
98
|
noAuth: true,
|
|
111
|
-
handler: (
|
|
99
|
+
handler: (_b) => __awaiter(this, [_b], void 0, function* ({ body, adminUser, response, cookies }) {
|
|
112
100
|
const totpTemporaryJWT = cookies['adminforth_totpTemporaryJWT'];
|
|
113
101
|
const decoded = yield this.adminforth.auth.verify(totpTemporaryJWT, 'tempTotp');
|
|
114
102
|
if (!decoded) {
|
package/index.ts
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import type { IAdminForth, IHttpServer, IAdminForthAuth } from "adminforth
|
|
3
|
-
import { AdminForthPlugin } from "adminforth";
|
|
1
|
+
import { AdminForthPlugin } from "adminforth";
|
|
2
|
+
import type { AdminForthResource, AdminUser, IAdminForth, IHttpServer, IAdminForthAuth, BeforeLoginConfirmationFunction, IAdminForthHttpResponse } from "adminforth";
|
|
4
3
|
import twofactor from 'node-2fa';
|
|
5
4
|
import { PluginOptions } from "./types.js"
|
|
6
5
|
|
|
7
|
-
|
|
8
6
|
export default class TwoFactorsAuthPlugin extends AdminForthPlugin {
|
|
9
7
|
options: PluginOptions;
|
|
10
8
|
adminforth: IAdminForth;
|
|
@@ -44,54 +42,46 @@ export default class TwoFactorsAuthPlugin extends AdminForthPlugin {
|
|
|
44
42
|
if(!this.authResource.columns.some((col)=>col.name === this.options.twoFaSecretFieldName)){
|
|
45
43
|
throw new Error(`Column ${this.options.twoFaSecretFieldName} not found in ${this.authResource.label}`)
|
|
46
44
|
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
45
|
+
(this.adminforth.config.auth.beforeLoginConfirmation as BeforeLoginConfirmationFunction[]).push(
|
|
46
|
+
async({ adminUser, response }: { adminUser: AdminUser, response: IAdminForthHttpResponse} )=> {
|
|
47
|
+
if(adminUser.isRoot){
|
|
48
|
+
return { body: {loginAllowed: true}, ok: true}
|
|
49
|
+
}
|
|
50
|
+
const secret = adminUser.dbUser[this.options.twoFaSecretFieldName]
|
|
51
|
+
const userName = adminUser.dbUser[adminforth.config.auth.usernameField]
|
|
52
|
+
const brandName = adminforth.config.customization.brandName
|
|
53
|
+
const authResource = adminforth.config.resources.find((res)=>res.resourceId === adminforth.config.auth.resourceId )
|
|
54
|
+
const authPk = authResource.columns.find((col)=>col.primaryKey).name
|
|
55
|
+
const userPk = adminUser.dbUser[authPk]
|
|
56
|
+
let newSecret = null
|
|
57
|
+
if (!secret){
|
|
58
|
+
const tempSecret = twofactor.generateSecret({name: brandName,account: userName})
|
|
59
|
+
newSecret = tempSecret.secret
|
|
60
|
+
} else {
|
|
61
|
+
const value = this.adminforth.auth.issueJWT({userName, issuer:brandName, pk:userPk },'tempTotp');
|
|
62
|
+
response.setHeader('Set-Cookie', `adminforth_totpTemporaryJWT=${value}; Path=${this.adminforth.config.baseUrl || '/'}; HttpOnly; SameSite=Strict; max-age=3600; `);
|
|
63
|
+
|
|
64
|
+
return {
|
|
65
|
+
body:{
|
|
66
|
+
loginAllowed: false,
|
|
67
|
+
redirectTo: '/confirm2fa',
|
|
68
|
+
|
|
69
|
+
},
|
|
70
|
+
ok: true
|
|
71
|
+
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
const totpTemporaryJWT = this.adminforth.auth.issueJWT({userName, newSecret, issuer:brandName, pk:userPk },'tempTotp', )
|
|
75
|
+
response.setHeader('Set-Cookie', `adminforth_totpTemporaryJWT=${totpTemporaryJWT}; Path=${this.adminforth.config.baseUrl || '/'}; HttpOnly; SameSite=Strict; Expires=${new Date(Date.now() + '1h').toUTCString() } `);
|
|
76
|
+
|
|
77
|
+
return {
|
|
67
78
|
body:{
|
|
68
79
|
loginAllowed: false,
|
|
69
|
-
redirectTo: '/confirm2fa',
|
|
70
|
-
setCookie: [{
|
|
71
|
-
name: 'totpTemporaryJWT',
|
|
72
|
-
value: this.adminforth.auth.issueJWT({userName, issuer:brandName, pk:userPk },'tempTotp', ),
|
|
73
|
-
expiry: '1h',
|
|
74
|
-
httpOnly: true
|
|
75
|
-
},]
|
|
80
|
+
redirectTo: secret ? '/confirm2fa' : '/setup2fa',
|
|
76
81
|
},
|
|
77
82
|
ok: true
|
|
78
|
-
|
|
79
83
|
}
|
|
80
|
-
}
|
|
81
|
-
const totpTemporaryJWT = this.adminforth.auth.issueJWT({userName, newSecret, issuer:brandName, pk:userPk },'tempTotp', )
|
|
82
|
-
return {
|
|
83
|
-
body:{
|
|
84
|
-
loginAllowed: false,
|
|
85
|
-
redirectTo: secret ? '/confirm2fa' : '/setup2fa',
|
|
86
|
-
setCookie: [{
|
|
87
|
-
name: 'totpTemporaryJWT',
|
|
88
|
-
value: totpTemporaryJWT,
|
|
89
|
-
expiry: '1h',
|
|
90
|
-
httpOnly: true
|
|
91
|
-
},]},
|
|
92
|
-
ok: true
|
|
93
|
-
}
|
|
94
|
-
})
|
|
84
|
+
})
|
|
95
85
|
}
|
|
96
86
|
|
|
97
87
|
setupEndpoints(server: IHttpServer): void {
|
|
@@ -101,7 +91,8 @@ export default class TwoFactorsAuthPlugin extends AdminForthPlugin {
|
|
|
101
91
|
noAuth: true,
|
|
102
92
|
handler: async (server) => {
|
|
103
93
|
const toReturn = {totpJWT:null,status:'ok',}
|
|
104
|
-
|
|
94
|
+
|
|
95
|
+
const totpTemporaryJWT = server.cookies.find((cookie)=>cookie.key === 'adminforth_totpTemporaryJWT')?.value;
|
|
105
96
|
if (totpTemporaryJWT){
|
|
106
97
|
toReturn.totpJWT = totpTemporaryJWT
|
|
107
98
|
}
|
package/package.json
CHANGED
|
@@ -1,17 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adminforth/two-factors-auth",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.14",
|
|
4
4
|
"description": "AdminForth plugin for two factors authentication",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"scripts": {
|
|
9
|
-
"rollout": "tsc && cp -
|
|
9
|
+
"rollout": "tsc && cp -rf custom dist/ && npm version patch && npm publish --access public"
|
|
10
10
|
},
|
|
11
11
|
"author": "devforth",
|
|
12
12
|
"license": "ISC",
|
|
13
13
|
"dependencies": {
|
|
14
|
-
"adminforth": "^1.1.95",
|
|
15
14
|
"node-2fa": "^2.0.3"
|
|
16
15
|
}
|
|
17
16
|
}
|