@nauth-toolkit/mfa-totp 0.1.3
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/LICENSE +90 -0
- package/README.md +30 -0
- package/dist/nestjs/index.d.ts +5 -0
- package/dist/nestjs/index.d.ts.map +1 -0
- package/dist/nestjs/index.js +23 -0
- package/dist/nestjs/index.js.map +1 -0
- package/dist/nestjs/totp-mfa.module.d.ts +10 -0
- package/dist/nestjs/totp-mfa.module.d.ts.map +1 -0
- package/dist/nestjs/totp-mfa.module.js +67 -0
- package/dist/nestjs/totp-mfa.module.js.map +1 -0
- package/dist/src/dto/mfa.dto.d.ts +143 -0
- package/dist/src/dto/mfa.dto.d.ts.map +1 -0
- package/dist/src/dto/mfa.dto.js +3 -0
- package/dist/src/dto/mfa.dto.js.map +1 -0
- package/dist/src/index.d.ts +4 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +23 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/totp-mfa-provider.service.d.ts +14 -0
- package/dist/src/totp-mfa-provider.service.d.ts.map +1 -0
- package/dist/src/totp-mfa-provider.service.js +71 -0
- package/dist/src/totp-mfa-provider.service.js.map +1 -0
- package/dist/src/totp.service.d.ts +22 -0
- package/dist/src/totp.service.d.ts.map +1 -0
- package/dist/src/totp.service.js +163 -0
- package/dist/src/totp.service.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +61 -0
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.TOTPService = void 0;
|
|
37
|
+
const otplib_1 = require("otplib");
|
|
38
|
+
const QRCode = __importStar(require("qrcode"));
|
|
39
|
+
const core_1 = require("@nauth-toolkit/core");
|
|
40
|
+
class TOTPService {
|
|
41
|
+
config;
|
|
42
|
+
logger;
|
|
43
|
+
defaultConfig = {
|
|
44
|
+
window: 1,
|
|
45
|
+
stepSeconds: 30,
|
|
46
|
+
digits: 6,
|
|
47
|
+
algorithm: 'sha1',
|
|
48
|
+
};
|
|
49
|
+
constructor(config, logger) {
|
|
50
|
+
this.config = config;
|
|
51
|
+
this.logger = logger;
|
|
52
|
+
this.configureAuthenticator();
|
|
53
|
+
}
|
|
54
|
+
configureAuthenticator() {
|
|
55
|
+
const totpConfig = this.getTOTPConfig();
|
|
56
|
+
otplib_1.authenticator.options = {
|
|
57
|
+
step: totpConfig.stepSeconds,
|
|
58
|
+
window: totpConfig.window,
|
|
59
|
+
digits: totpConfig.digits,
|
|
60
|
+
algorithm: totpConfig.algorithm,
|
|
61
|
+
};
|
|
62
|
+
this.logger?.debug?.(`TOTP configured: step=${totpConfig.stepSeconds}s, window=${totpConfig.window}, digits=${totpConfig.digits}`);
|
|
63
|
+
}
|
|
64
|
+
getTOTPConfig() {
|
|
65
|
+
return {
|
|
66
|
+
...this.defaultConfig,
|
|
67
|
+
...this.config.mfa?.totp,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
getIssuer() {
|
|
71
|
+
return this.config.mfa?.issuer || 'nauth-toolkit';
|
|
72
|
+
}
|
|
73
|
+
async generateSecret(accountName) {
|
|
74
|
+
this.logger?.log?.(`Generating TOTP secret for: ${accountName}`);
|
|
75
|
+
const secret = otplib_1.authenticator.generateSecret();
|
|
76
|
+
const issuer = this.getIssuer();
|
|
77
|
+
const otpauthUrl = otplib_1.authenticator.keyuri(accountName, issuer, secret);
|
|
78
|
+
let qrCode;
|
|
79
|
+
try {
|
|
80
|
+
qrCode = await QRCode.toDataURL(otpauthUrl);
|
|
81
|
+
}
|
|
82
|
+
catch (error) {
|
|
83
|
+
this.logger?.error?.('Failed to generate QR code', error);
|
|
84
|
+
throw new core_1.NAuthException(core_1.AuthErrorCode.INTERNAL_ERROR, 'Failed to generate QR code');
|
|
85
|
+
}
|
|
86
|
+
const manualEntryKey = this.formatSecretForManualEntry(secret);
|
|
87
|
+
this.logger?.log?.(`TOTP secret generated successfully for: ${accountName}`);
|
|
88
|
+
return {
|
|
89
|
+
secret,
|
|
90
|
+
qrCode,
|
|
91
|
+
manualEntryKey,
|
|
92
|
+
issuer,
|
|
93
|
+
accountName,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
formatSecretForManualEntry(secret) {
|
|
97
|
+
return secret.match(/.{1,4}/g)?.join(' ') || secret;
|
|
98
|
+
}
|
|
99
|
+
verifyCode(secret, code) {
|
|
100
|
+
try {
|
|
101
|
+
const cleanCode = code.replace(/\s/g, '');
|
|
102
|
+
if (!/^\d{6}$/.test(cleanCode)) {
|
|
103
|
+
this.logger?.warn?.('Invalid TOTP code format');
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
const isValid = otplib_1.authenticator.verify({
|
|
107
|
+
token: cleanCode,
|
|
108
|
+
secret,
|
|
109
|
+
});
|
|
110
|
+
if (isValid) {
|
|
111
|
+
this.logger?.debug?.('TOTP code verified successfully');
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
this.logger?.warn?.('TOTP code verification failed');
|
|
115
|
+
}
|
|
116
|
+
return isValid;
|
|
117
|
+
}
|
|
118
|
+
catch (error) {
|
|
119
|
+
this.logger?.error?.('TOTP verification error', error);
|
|
120
|
+
return false;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
verifyCodeWithDetails(secret, code) {
|
|
124
|
+
const cleanCode = code.replace(/\s/g, '');
|
|
125
|
+
if (!cleanCode) {
|
|
126
|
+
return { valid: false, error: 'Code is required' };
|
|
127
|
+
}
|
|
128
|
+
if (!/^\d{6}$/.test(cleanCode)) {
|
|
129
|
+
return { valid: false, error: 'Code must be 6 digits' };
|
|
130
|
+
}
|
|
131
|
+
if (!secret || secret.length < 16) {
|
|
132
|
+
return { valid: false, error: 'Invalid secret' };
|
|
133
|
+
}
|
|
134
|
+
const isValid = this.verifyCode(secret, cleanCode);
|
|
135
|
+
if (!isValid) {
|
|
136
|
+
return { valid: false, error: 'Invalid or expired code' };
|
|
137
|
+
}
|
|
138
|
+
return { valid: true };
|
|
139
|
+
}
|
|
140
|
+
generateCode(secret) {
|
|
141
|
+
return otplib_1.authenticator.generate(secret);
|
|
142
|
+
}
|
|
143
|
+
isValidSecret(secret) {
|
|
144
|
+
if (!secret || typeof secret !== 'string') {
|
|
145
|
+
return false;
|
|
146
|
+
}
|
|
147
|
+
if (secret.length < 16) {
|
|
148
|
+
return false;
|
|
149
|
+
}
|
|
150
|
+
if (!/^[A-Z2-7]+$/.test(secret)) {
|
|
151
|
+
return false;
|
|
152
|
+
}
|
|
153
|
+
return true;
|
|
154
|
+
}
|
|
155
|
+
getTimeRemaining() {
|
|
156
|
+
const totpConfig = this.getTOTPConfig();
|
|
157
|
+
const now = Math.floor(Date.now() / 1000);
|
|
158
|
+
const elapsed = now % totpConfig.stepSeconds;
|
|
159
|
+
return totpConfig.stepSeconds - elapsed;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
exports.TOTPService = TOTPService;
|
|
163
|
+
//# sourceMappingURL=totp.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"totp.service.js","sourceRoot":"","sources":["../../src/totp.service.ts"],"names":[],"mappings":"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"}
|