@bernierllc/auth-suite 1.0.0
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 +21 -0
- package/README.md +468 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +39 -0
- package/dist/index.js.map +1 -0
- package/dist/managers/audit-manager.d.ts +26 -0
- package/dist/managers/audit-manager.d.ts.map +1 -0
- package/dist/managers/audit-manager.js +160 -0
- package/dist/managers/audit-manager.js.map +1 -0
- package/dist/managers/mfa-manager.d.ts +32 -0
- package/dist/managers/mfa-manager.d.ts.map +1 -0
- package/dist/managers/mfa-manager.js +206 -0
- package/dist/managers/mfa-manager.js.map +1 -0
- package/dist/managers/rbac-manager.d.ts +25 -0
- package/dist/managers/rbac-manager.d.ts.map +1 -0
- package/dist/managers/rbac-manager.js +192 -0
- package/dist/managers/rbac-manager.js.map +1 -0
- package/dist/managers/session-manager.d.ts +20 -0
- package/dist/managers/session-manager.d.ts.map +1 -0
- package/dist/managers/session-manager.js +110 -0
- package/dist/managers/session-manager.js.map +1 -0
- package/dist/suite.d.ts +172 -0
- package/dist/suite.d.ts.map +1 -0
- package/dist/suite.js +1145 -0
- package/dist/suite.js.map +1 -0
- package/dist/types.d.ts +250 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +10 -0
- package/dist/types.js.map +1 -0
- package/package.json +68 -0
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
Copyright (c) 2025 Bernier LLC
|
|
4
|
+
|
|
5
|
+
This file is licensed to the client under a limited-use license.
|
|
6
|
+
The client may use and modify this code *only within the scope of the project it was delivered for*.
|
|
7
|
+
Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.FileAuditManager = void 0;
|
|
11
|
+
const uuid_1 = require("uuid");
|
|
12
|
+
/**
|
|
13
|
+
* File-based audit manager
|
|
14
|
+
* For production use, consider database storage or external logging service
|
|
15
|
+
*/
|
|
16
|
+
class FileAuditManager {
|
|
17
|
+
logs = [];
|
|
18
|
+
config;
|
|
19
|
+
maxLogs;
|
|
20
|
+
constructor(config) {
|
|
21
|
+
this.config = config;
|
|
22
|
+
this.maxLogs = this.parseMaxSize(config.retention?.maxSize || '100MB');
|
|
23
|
+
}
|
|
24
|
+
async log(event) {
|
|
25
|
+
const auditLog = {
|
|
26
|
+
id: (0, uuid_1.v4)(),
|
|
27
|
+
timestamp: new Date(),
|
|
28
|
+
...event
|
|
29
|
+
};
|
|
30
|
+
this.logs.push(auditLog);
|
|
31
|
+
// Trim logs if we exceed the maximum
|
|
32
|
+
if (this.logs.length > this.maxLogs) {
|
|
33
|
+
this.logs = this.logs.slice(-this.maxLogs);
|
|
34
|
+
}
|
|
35
|
+
// In a real implementation, this would write to a file or database
|
|
36
|
+
// eslint-disable-next-line no-console
|
|
37
|
+
console.log(`[AUDIT] ${auditLog.timestamp.toISOString()} [${auditLog.level.toUpperCase()}] ${auditLog.event}`, auditLog.details);
|
|
38
|
+
}
|
|
39
|
+
async query(filters) {
|
|
40
|
+
let filteredLogs = [...this.logs];
|
|
41
|
+
// Apply filters
|
|
42
|
+
if (filters.userId) {
|
|
43
|
+
filteredLogs = filteredLogs.filter(log => log.userId === filters.userId);
|
|
44
|
+
}
|
|
45
|
+
if (filters.sessionId) {
|
|
46
|
+
filteredLogs = filteredLogs.filter(log => log.sessionId === filters.sessionId);
|
|
47
|
+
}
|
|
48
|
+
if (filters.event) {
|
|
49
|
+
filteredLogs = filteredLogs.filter(log => log.event === filters.event);
|
|
50
|
+
}
|
|
51
|
+
if (filters.level) {
|
|
52
|
+
filteredLogs = filteredLogs.filter(log => log.level === filters.level);
|
|
53
|
+
}
|
|
54
|
+
if (filters.startDate) {
|
|
55
|
+
filteredLogs = filteredLogs.filter(log => log.timestamp >= filters.startDate);
|
|
56
|
+
}
|
|
57
|
+
if (filters.endDate) {
|
|
58
|
+
filteredLogs = filteredLogs.filter(log => log.timestamp <= filters.endDate);
|
|
59
|
+
}
|
|
60
|
+
// Sort by timestamp (newest first)
|
|
61
|
+
filteredLogs.sort((a, b) => b.timestamp.getTime() - a.timestamp.getTime());
|
|
62
|
+
// Apply pagination
|
|
63
|
+
const offset = filters.offset || 0;
|
|
64
|
+
const limit = filters.limit || 100;
|
|
65
|
+
return filteredLogs.slice(offset, offset + limit);
|
|
66
|
+
}
|
|
67
|
+
async cleanup(olderThanDays) {
|
|
68
|
+
const cutoffDate = new Date();
|
|
69
|
+
cutoffDate.setDate(cutoffDate.getDate() - olderThanDays);
|
|
70
|
+
const initialCount = this.logs.length;
|
|
71
|
+
this.logs = this.logs.filter(log => log.timestamp > cutoffDate);
|
|
72
|
+
return initialCount - this.logs.length;
|
|
73
|
+
}
|
|
74
|
+
// Additional utility methods
|
|
75
|
+
async getLogStats() {
|
|
76
|
+
const stats = {
|
|
77
|
+
total: this.logs.length,
|
|
78
|
+
byLevel: {},
|
|
79
|
+
byEvent: {},
|
|
80
|
+
oldestLog: undefined,
|
|
81
|
+
newestLog: undefined
|
|
82
|
+
};
|
|
83
|
+
if (this.logs.length === 0) {
|
|
84
|
+
return stats;
|
|
85
|
+
}
|
|
86
|
+
// Calculate statistics
|
|
87
|
+
for (const log of this.logs) {
|
|
88
|
+
// Count by level
|
|
89
|
+
stats.byLevel[log.level] = (stats.byLevel[log.level] || 0) + 1;
|
|
90
|
+
// Count by event
|
|
91
|
+
stats.byEvent[log.event] = (stats.byEvent[log.event] || 0) + 1;
|
|
92
|
+
}
|
|
93
|
+
// Find oldest and newest logs
|
|
94
|
+
const sortedByTime = [...this.logs].sort((a, b) => a.timestamp.getTime() - b.timestamp.getTime());
|
|
95
|
+
stats.oldestLog = sortedByTime[0]?.timestamp;
|
|
96
|
+
stats.newestLog = sortedByTime[sortedByTime.length - 1]?.timestamp;
|
|
97
|
+
return stats;
|
|
98
|
+
}
|
|
99
|
+
async exportLogs(format = 'json') {
|
|
100
|
+
if (format === 'csv') {
|
|
101
|
+
return this.exportToCsv();
|
|
102
|
+
}
|
|
103
|
+
return JSON.stringify(this.logs, null, 2);
|
|
104
|
+
}
|
|
105
|
+
async searchLogs(searchTerm) {
|
|
106
|
+
const lowerSearchTerm = searchTerm.toLowerCase();
|
|
107
|
+
return this.logs.filter(log => {
|
|
108
|
+
// Search in event name
|
|
109
|
+
if (log.event.toLowerCase().includes(lowerSearchTerm)) {
|
|
110
|
+
return true;
|
|
111
|
+
}
|
|
112
|
+
// Search in user ID
|
|
113
|
+
if (log.userId?.toLowerCase().includes(lowerSearchTerm)) {
|
|
114
|
+
return true;
|
|
115
|
+
}
|
|
116
|
+
// Search in details (JSON stringify for simple text search)
|
|
117
|
+
if (JSON.stringify(log.details).toLowerCase().includes(lowerSearchTerm)) {
|
|
118
|
+
return true;
|
|
119
|
+
}
|
|
120
|
+
return false;
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
// Private helper methods
|
|
124
|
+
parseMaxSize(maxSize) {
|
|
125
|
+
const size = parseInt(maxSize);
|
|
126
|
+
const unit = maxSize.toUpperCase().slice(-2);
|
|
127
|
+
switch (unit) {
|
|
128
|
+
case 'KB':
|
|
129
|
+
return size * 1024;
|
|
130
|
+
case 'MB':
|
|
131
|
+
return size * 1024 * 1024;
|
|
132
|
+
case 'GB':
|
|
133
|
+
return size * 1024 * 1024 * 1024;
|
|
134
|
+
default:
|
|
135
|
+
return size; // Assume bytes
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
exportToCsv() {
|
|
139
|
+
if (this.logs.length === 0) {
|
|
140
|
+
return 'id,timestamp,userId,sessionId,event,level,details,ipAddress,userAgent\n';
|
|
141
|
+
}
|
|
142
|
+
const headers = 'id,timestamp,userId,sessionId,event,level,details,ipAddress,userAgent\n';
|
|
143
|
+
const rows = this.logs.map(log => {
|
|
144
|
+
return [
|
|
145
|
+
log.id,
|
|
146
|
+
log.timestamp.toISOString(),
|
|
147
|
+
log.userId || '',
|
|
148
|
+
log.sessionId || '',
|
|
149
|
+
log.event,
|
|
150
|
+
log.level,
|
|
151
|
+
JSON.stringify(log.details).replace(/"/g, '""'), // Escape quotes for CSV
|
|
152
|
+
log.ipAddress || '',
|
|
153
|
+
log.userAgent || ''
|
|
154
|
+
].join(',');
|
|
155
|
+
}).join('\n');
|
|
156
|
+
return headers + rows;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
exports.FileAuditManager = FileAuditManager;
|
|
160
|
+
//# sourceMappingURL=audit-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit-manager.js","sourceRoot":"","sources":["../../src/managers/audit-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { MfaManager, MfaChallenge } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* TOTP-based MFA manager
|
|
4
|
+
* Supports Time-based One-Time Passwords (TOTP) like Google Authenticator
|
|
5
|
+
*/
|
|
6
|
+
export declare class TOTPMfaManager implements MfaManager {
|
|
7
|
+
private userSecrets;
|
|
8
|
+
private userBackupCodes;
|
|
9
|
+
private activeChallenges;
|
|
10
|
+
private config;
|
|
11
|
+
constructor(config: any);
|
|
12
|
+
setupMfa(userId: string, type: string, _config?: Record<string, any>): Promise<{
|
|
13
|
+
secret: string;
|
|
14
|
+
qrCode?: string;
|
|
15
|
+
}>;
|
|
16
|
+
verifySetup(userId: string, code: string): Promise<boolean>;
|
|
17
|
+
generateChallenge(userId: string): Promise<MfaChallenge>;
|
|
18
|
+
verifyChallenge(challengeId: string, response: string): Promise<boolean>;
|
|
19
|
+
getBackupCodes(userId: string): Promise<string[]>;
|
|
20
|
+
verifyBackupCode(userId: string, code: string): Promise<boolean>;
|
|
21
|
+
isMfaEnabled(userId: string): Promise<boolean>;
|
|
22
|
+
disableMfa(userId: string): Promise<boolean>;
|
|
23
|
+
regenerateBackupCodes(userId: string): Promise<string[]>;
|
|
24
|
+
private generateTotpSecret;
|
|
25
|
+
private generateBackupCodes;
|
|
26
|
+
private generateQrCodeUrl;
|
|
27
|
+
private verifyTotpCode;
|
|
28
|
+
private generateTotpCode;
|
|
29
|
+
private simpleHash;
|
|
30
|
+
cleanup(): void;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=mfa-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mfa-manager.d.ts","sourceRoot":"","sources":["../../src/managers/mfa-manager.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAEzD;;;GAGG;AACH,qBAAa,cAAe,YAAW,UAAU;IAC/C,OAAO,CAAC,WAAW,CAA6B;IAChD,OAAO,CAAC,eAAe,CAAkC;IACzD,OAAO,CAAC,gBAAgB,CAAmC;IAC3D,OAAO,CAAC,MAAM,CAAM;gBAER,MAAM,EAAE,GAAG;IAIjB,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAqBnH,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAS3D,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAsBxD,eAAe,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAoCxE,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAKjD,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAqBhE,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAI9C,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAc5C,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAY9D,OAAO,CAAC,kBAAkB;IAY1B,OAAO,CAAC,mBAAmB;IAkB3B,OAAO,CAAC,iBAAiB;IAOzB,OAAO,CAAC,cAAc;IAiBtB,OAAO,CAAC,gBAAgB;IASxB,OAAO,CAAC,UAAU;IAWlB,OAAO,IAAI,IAAI;CAShB"}
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
Copyright (c) 2025 Bernier LLC
|
|
4
|
+
|
|
5
|
+
This file is licensed to the client under a limited-use license.
|
|
6
|
+
The client may use and modify this code *only within the scope of the project it was delivered for*.
|
|
7
|
+
Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.TOTPMfaManager = void 0;
|
|
11
|
+
const uuid_1 = require("uuid");
|
|
12
|
+
/**
|
|
13
|
+
* TOTP-based MFA manager
|
|
14
|
+
* Supports Time-based One-Time Passwords (TOTP) like Google Authenticator
|
|
15
|
+
*/
|
|
16
|
+
class TOTPMfaManager {
|
|
17
|
+
userSecrets = new Map();
|
|
18
|
+
userBackupCodes = new Map();
|
|
19
|
+
activeChallenges = new Map();
|
|
20
|
+
config;
|
|
21
|
+
constructor(config) {
|
|
22
|
+
this.config = config;
|
|
23
|
+
}
|
|
24
|
+
async setupMfa(userId, type, _config) {
|
|
25
|
+
if (type !== 'totp') {
|
|
26
|
+
throw new Error(`MFA type ${type} not supported`);
|
|
27
|
+
}
|
|
28
|
+
// Generate a base32 secret for TOTP
|
|
29
|
+
const secret = this.generateTotpSecret();
|
|
30
|
+
this.userSecrets.set(userId, secret);
|
|
31
|
+
// Generate backup codes
|
|
32
|
+
if (this.config.backup?.enabled) {
|
|
33
|
+
const backupCodes = this.generateBackupCodes();
|
|
34
|
+
this.userBackupCodes.set(userId, new Set(backupCodes));
|
|
35
|
+
}
|
|
36
|
+
// Generate QR code URL (for apps like Google Authenticator)
|
|
37
|
+
const qrCode = this.generateQrCodeUrl(userId, secret);
|
|
38
|
+
return { secret, qrCode };
|
|
39
|
+
}
|
|
40
|
+
async verifySetup(userId, code) {
|
|
41
|
+
const secret = this.userSecrets.get(userId);
|
|
42
|
+
if (!secret) {
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
return this.verifyTotpCode(secret, code);
|
|
46
|
+
}
|
|
47
|
+
async generateChallenge(userId) {
|
|
48
|
+
const challengeId = (0, uuid_1.v4)();
|
|
49
|
+
const now = new Date();
|
|
50
|
+
const expiresAt = new Date(now.getTime() + 5 * 60 * 1000); // 5 minutes
|
|
51
|
+
const challenge = {
|
|
52
|
+
challengeId,
|
|
53
|
+
userId,
|
|
54
|
+
type: 'totp',
|
|
55
|
+
createdAt: now,
|
|
56
|
+
expiresAt,
|
|
57
|
+
verified: false,
|
|
58
|
+
metadata: {
|
|
59
|
+
attempts: 0,
|
|
60
|
+
maxAttempts: 3
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
this.activeChallenges.set(challengeId, challenge);
|
|
64
|
+
return challenge;
|
|
65
|
+
}
|
|
66
|
+
async verifyChallenge(challengeId, response) {
|
|
67
|
+
const challenge = this.activeChallenges.get(challengeId);
|
|
68
|
+
if (!challenge || challenge.verified || challenge.expiresAt < new Date()) {
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
// Increment attempt count
|
|
72
|
+
if (challenge.metadata) {
|
|
73
|
+
challenge.metadata.attempts = (challenge.metadata.attempts || 0) + 1;
|
|
74
|
+
// Check if max attempts exceeded
|
|
75
|
+
if (challenge.metadata.attempts > challenge.metadata.maxAttempts) {
|
|
76
|
+
this.activeChallenges.delete(challengeId);
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
const secret = this.userSecrets.get(challenge.userId);
|
|
81
|
+
if (!secret) {
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
const isValid = this.verifyTotpCode(secret, response);
|
|
85
|
+
if (isValid) {
|
|
86
|
+
challenge.verified = true;
|
|
87
|
+
this.activeChallenges.delete(challengeId);
|
|
88
|
+
return true;
|
|
89
|
+
}
|
|
90
|
+
// Update challenge with failed attempt
|
|
91
|
+
this.activeChallenges.set(challengeId, challenge);
|
|
92
|
+
return false;
|
|
93
|
+
}
|
|
94
|
+
async getBackupCodes(userId) {
|
|
95
|
+
const codes = this.userBackupCodes.get(userId);
|
|
96
|
+
return codes ? Array.from(codes) : [];
|
|
97
|
+
}
|
|
98
|
+
async verifyBackupCode(userId, code) {
|
|
99
|
+
const codes = this.userBackupCodes.get(userId);
|
|
100
|
+
if (!codes || !codes.has(code)) {
|
|
101
|
+
return false;
|
|
102
|
+
}
|
|
103
|
+
// Remove used backup code
|
|
104
|
+
codes.delete(code);
|
|
105
|
+
if (codes.size === 0) {
|
|
106
|
+
this.userBackupCodes.delete(userId);
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
this.userBackupCodes.set(userId, codes);
|
|
110
|
+
}
|
|
111
|
+
return true;
|
|
112
|
+
}
|
|
113
|
+
// Additional helper methods
|
|
114
|
+
async isMfaEnabled(userId) {
|
|
115
|
+
return this.userSecrets.has(userId);
|
|
116
|
+
}
|
|
117
|
+
async disableMfa(userId) {
|
|
118
|
+
const hadSecret = this.userSecrets.delete(userId);
|
|
119
|
+
this.userBackupCodes.delete(userId);
|
|
120
|
+
// Remove any active challenges for this user
|
|
121
|
+
for (const [challengeId, challenge] of this.activeChallenges.entries()) {
|
|
122
|
+
if (challenge.userId === userId) {
|
|
123
|
+
this.activeChallenges.delete(challengeId);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
return hadSecret;
|
|
127
|
+
}
|
|
128
|
+
async regenerateBackupCodes(userId) {
|
|
129
|
+
if (!this.userSecrets.has(userId)) {
|
|
130
|
+
throw new Error('MFA not enabled for user');
|
|
131
|
+
}
|
|
132
|
+
const backupCodes = this.generateBackupCodes();
|
|
133
|
+
this.userBackupCodes.set(userId, new Set(backupCodes));
|
|
134
|
+
return backupCodes;
|
|
135
|
+
}
|
|
136
|
+
// Private helper methods
|
|
137
|
+
generateTotpSecret() {
|
|
138
|
+
// Generate a 32-character base32 secret
|
|
139
|
+
const base32Chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567';
|
|
140
|
+
let secret = '';
|
|
141
|
+
for (let i = 0; i < 32; i++) {
|
|
142
|
+
secret += base32Chars.charAt(Math.floor(Math.random() * base32Chars.length));
|
|
143
|
+
}
|
|
144
|
+
return secret;
|
|
145
|
+
}
|
|
146
|
+
generateBackupCodes() {
|
|
147
|
+
const codes = [];
|
|
148
|
+
const codeCount = this.config.backup?.codeCount || 10;
|
|
149
|
+
const codeLength = this.config.backup?.codeLength || 8;
|
|
150
|
+
for (let i = 0; i < codeCount; i++) {
|
|
151
|
+
// Generate a simple alphanumeric code
|
|
152
|
+
const chars = 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789'; // Exclude ambiguous chars
|
|
153
|
+
let code = '';
|
|
154
|
+
for (let j = 0; j < codeLength; j++) {
|
|
155
|
+
code += chars.charAt(Math.floor(Math.random() * chars.length));
|
|
156
|
+
}
|
|
157
|
+
codes.push(code);
|
|
158
|
+
}
|
|
159
|
+
return codes;
|
|
160
|
+
}
|
|
161
|
+
generateQrCodeUrl(userId, secret) {
|
|
162
|
+
const issuer = encodeURIComponent('BernierLLC Auth Suite');
|
|
163
|
+
const accountName = encodeURIComponent(userId);
|
|
164
|
+
return `otpauth://totp/${issuer}:${accountName}?secret=${secret}&issuer=${issuer}`;
|
|
165
|
+
}
|
|
166
|
+
verifyTotpCode(secret, code) {
|
|
167
|
+
// This is a simplified TOTP verification
|
|
168
|
+
// In production, use a proper TOTP library like 'otplib'
|
|
169
|
+
const timeStep = Math.floor(Date.now() / 1000 / 30); // 30-second window
|
|
170
|
+
// Check current window and adjacent windows for clock drift tolerance
|
|
171
|
+
for (let i = -1; i <= 1; i++) {
|
|
172
|
+
const testCode = this.generateTotpCode(secret, timeStep + i);
|
|
173
|
+
if (testCode === code) {
|
|
174
|
+
return true;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return false;
|
|
178
|
+
}
|
|
179
|
+
generateTotpCode(secret, timeStep) {
|
|
180
|
+
// Simplified TOTP code generation
|
|
181
|
+
// In production, use proper HMAC-SHA1 implementation
|
|
182
|
+
// This is a mock implementation for demonstration
|
|
183
|
+
const hash = this.simpleHash(secret + timeStep.toString());
|
|
184
|
+
return (hash % 1000000).toString().padStart(6, '0');
|
|
185
|
+
}
|
|
186
|
+
simpleHash(str) {
|
|
187
|
+
let hash = 0;
|
|
188
|
+
for (let i = 0; i < str.length; i++) {
|
|
189
|
+
const char = str.charCodeAt(i);
|
|
190
|
+
hash = ((hash << 5) - hash) + char;
|
|
191
|
+
hash = hash & hash; // Convert to 32-bit integer
|
|
192
|
+
}
|
|
193
|
+
return Math.abs(hash);
|
|
194
|
+
}
|
|
195
|
+
// Cleanup method
|
|
196
|
+
cleanup() {
|
|
197
|
+
const now = new Date();
|
|
198
|
+
for (const [challengeId, challenge] of this.activeChallenges.entries()) {
|
|
199
|
+
if (challenge.expiresAt < now) {
|
|
200
|
+
this.activeChallenges.delete(challengeId);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
exports.TOTPMfaManager = TOTPMfaManager;
|
|
206
|
+
//# sourceMappingURL=mfa-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mfa-manager.js","sourceRoot":"","sources":["../../src/managers/mfa-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { RBACManager, PermissionCheck, PermissionResult, RoleDefinition, PermissionDefinition } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* Basic in-memory RBAC manager
|
|
4
|
+
* For production use, consider database storage
|
|
5
|
+
*/
|
|
6
|
+
export declare class BasicRBACManager implements RBACManager {
|
|
7
|
+
private userRoles;
|
|
8
|
+
private roles;
|
|
9
|
+
private permissions;
|
|
10
|
+
private hierarchical;
|
|
11
|
+
constructor(config: any);
|
|
12
|
+
checkPermission(check: PermissionCheck): Promise<PermissionResult>;
|
|
13
|
+
getUserRoles(userId: string): Promise<string[]>;
|
|
14
|
+
assignRole(userId: string, role: string): Promise<boolean>;
|
|
15
|
+
revokeRole(userId: string, role: string): Promise<boolean>;
|
|
16
|
+
getRolePermissions(roleName: string): Promise<string[]>;
|
|
17
|
+
createRole(role: RoleDefinition): Promise<boolean>;
|
|
18
|
+
deleteRole(roleName: string): Promise<boolean>;
|
|
19
|
+
updateRolePermissions(roleName: string, permissions: string[]): Promise<boolean>;
|
|
20
|
+
createPermission(permission: PermissionDefinition): Promise<boolean>;
|
|
21
|
+
private addInheritedRoles;
|
|
22
|
+
private checkConditions;
|
|
23
|
+
private evaluateCondition;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=rbac-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rbac-manager.d.ts","sourceRoot":"","sources":["../../src/managers/rbac-manager.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EACV,WAAW,EACX,eAAe,EACf,gBAAgB,EAChB,cAAc,EACd,oBAAoB,EACrB,MAAM,UAAU,CAAC;AAElB;;;GAGG;AACH,qBAAa,gBAAiB,YAAW,WAAW;IAClD,OAAO,CAAC,SAAS,CAAkC;IACnD,OAAO,CAAC,KAAK,CAA8B;IAC3C,OAAO,CAAC,WAAW,CAAoC;IACvD,OAAO,CAAC,YAAY,CAAU;gBAElB,MAAM,EAAE,GAAG;IAMjB,eAAe,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,gBAAgB,CAAC;IA6DlE,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAkB/C,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAW1D,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAc1D,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAWvD,UAAU,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC;IASlD,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAgB9C,qBAAqB,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC;IAWhF,gBAAgB,CAAC,UAAU,EAAE,oBAAoB,GAAG,OAAO,CAAC,OAAO,CAAC;IAa1E,OAAO,CAAC,iBAAiB;YAUX,eAAe;IAY7B,OAAO,CAAC,iBAAiB;CAgB1B"}
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
Copyright (c) 2025 Bernier LLC
|
|
4
|
+
|
|
5
|
+
This file is licensed to the client under a limited-use license.
|
|
6
|
+
The client may use and modify this code *only within the scope of the project it was delivered for*.
|
|
7
|
+
Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.BasicRBACManager = void 0;
|
|
11
|
+
/**
|
|
12
|
+
* Basic in-memory RBAC manager
|
|
13
|
+
* For production use, consider database storage
|
|
14
|
+
*/
|
|
15
|
+
class BasicRBACManager {
|
|
16
|
+
userRoles = new Map();
|
|
17
|
+
roles;
|
|
18
|
+
permissions;
|
|
19
|
+
hierarchical;
|
|
20
|
+
constructor(config) {
|
|
21
|
+
this.hierarchical = config.hierarchical || false;
|
|
22
|
+
this.roles = new Map(config.roles?.map((role) => [role.name, role]) || []);
|
|
23
|
+
this.permissions = new Map(config.permissions?.map((perm) => [perm.name, perm]) || []);
|
|
24
|
+
}
|
|
25
|
+
async checkPermission(check) {
|
|
26
|
+
const userRoles = await this.getUserRoles(check.userId);
|
|
27
|
+
if (userRoles.length === 0) {
|
|
28
|
+
return {
|
|
29
|
+
allowed: false,
|
|
30
|
+
reason: 'User has no roles assigned'
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
// Get all permissions for user's roles
|
|
34
|
+
const userPermissions = new Set();
|
|
35
|
+
for (const roleName of userRoles) {
|
|
36
|
+
const rolePermissions = await this.getRolePermissions(roleName);
|
|
37
|
+
rolePermissions.forEach(perm => userPermissions.add(perm));
|
|
38
|
+
}
|
|
39
|
+
// Check for exact permission match
|
|
40
|
+
const requiredPermission = `${check.resource}:${check.action}`;
|
|
41
|
+
if (userPermissions.has(requiredPermission)) {
|
|
42
|
+
return {
|
|
43
|
+
allowed: true,
|
|
44
|
+
reason: 'Direct permission match'
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
// Check for wildcard permissions
|
|
48
|
+
const wildcardPermission = `${check.resource}:*`;
|
|
49
|
+
if (userPermissions.has(wildcardPermission)) {
|
|
50
|
+
return {
|
|
51
|
+
allowed: true,
|
|
52
|
+
reason: 'Wildcard permission match'
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
// Check for global admin permission
|
|
56
|
+
if (userPermissions.has('*:*')) {
|
|
57
|
+
return {
|
|
58
|
+
allowed: true,
|
|
59
|
+
reason: 'Global admin permission'
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
// Check permission conditions if available
|
|
63
|
+
const permission = this.permissions.get(requiredPermission);
|
|
64
|
+
if (permission && permission.conditions) {
|
|
65
|
+
const conditionsMet = await this.checkConditions(permission.conditions, check.context || {});
|
|
66
|
+
if (conditionsMet) {
|
|
67
|
+
return {
|
|
68
|
+
allowed: true,
|
|
69
|
+
reason: 'Permission conditions satisfied'
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return {
|
|
74
|
+
allowed: false,
|
|
75
|
+
reason: `No permission found for ${requiredPermission}`
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
async getUserRoles(userId) {
|
|
79
|
+
const roleSet = this.userRoles.get(userId) || new Set();
|
|
80
|
+
const roles = Array.from(roleSet);
|
|
81
|
+
// If hierarchical, include inherited roles
|
|
82
|
+
if (this.hierarchical) {
|
|
83
|
+
const inheritedRoles = new Set();
|
|
84
|
+
for (const roleName of roles) {
|
|
85
|
+
this.addInheritedRoles(roleName, inheritedRoles);
|
|
86
|
+
}
|
|
87
|
+
return Array.from(new Set([...roles, ...inheritedRoles]));
|
|
88
|
+
}
|
|
89
|
+
return roles;
|
|
90
|
+
}
|
|
91
|
+
async assignRole(userId, role) {
|
|
92
|
+
if (!this.roles.has(role)) {
|
|
93
|
+
return false;
|
|
94
|
+
}
|
|
95
|
+
const userRoleSet = this.userRoles.get(userId) || new Set();
|
|
96
|
+
userRoleSet.add(role);
|
|
97
|
+
this.userRoles.set(userId, userRoleSet);
|
|
98
|
+
return true;
|
|
99
|
+
}
|
|
100
|
+
async revokeRole(userId, role) {
|
|
101
|
+
const userRoleSet = this.userRoles.get(userId);
|
|
102
|
+
if (!userRoleSet) {
|
|
103
|
+
return false;
|
|
104
|
+
}
|
|
105
|
+
const removed = userRoleSet.delete(role);
|
|
106
|
+
if (userRoleSet.size === 0) {
|
|
107
|
+
this.userRoles.delete(userId);
|
|
108
|
+
}
|
|
109
|
+
return removed;
|
|
110
|
+
}
|
|
111
|
+
async getRolePermissions(roleName) {
|
|
112
|
+
const role = this.roles.get(roleName);
|
|
113
|
+
if (!role) {
|
|
114
|
+
return [];
|
|
115
|
+
}
|
|
116
|
+
return role.permissions || [];
|
|
117
|
+
}
|
|
118
|
+
// Additional methods for role/permission management
|
|
119
|
+
async createRole(role) {
|
|
120
|
+
if (this.roles.has(role.name)) {
|
|
121
|
+
return false;
|
|
122
|
+
}
|
|
123
|
+
this.roles.set(role.name, role);
|
|
124
|
+
return true;
|
|
125
|
+
}
|
|
126
|
+
async deleteRole(roleName) {
|
|
127
|
+
const deleted = this.roles.delete(roleName);
|
|
128
|
+
if (deleted) {
|
|
129
|
+
// Remove role from all users
|
|
130
|
+
for (const [userId, userRoles] of this.userRoles.entries()) {
|
|
131
|
+
userRoles.delete(roleName);
|
|
132
|
+
if (userRoles.size === 0) {
|
|
133
|
+
this.userRoles.delete(userId);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
return deleted;
|
|
138
|
+
}
|
|
139
|
+
async updateRolePermissions(roleName, permissions) {
|
|
140
|
+
const role = this.roles.get(roleName);
|
|
141
|
+
if (!role) {
|
|
142
|
+
return false;
|
|
143
|
+
}
|
|
144
|
+
role.permissions = permissions;
|
|
145
|
+
this.roles.set(roleName, role);
|
|
146
|
+
return true;
|
|
147
|
+
}
|
|
148
|
+
async createPermission(permission) {
|
|
149
|
+
const permissionKey = `${permission.resource}:${permission.actions.join(',')}`;
|
|
150
|
+
if (this.permissions.has(permissionKey)) {
|
|
151
|
+
return false;
|
|
152
|
+
}
|
|
153
|
+
this.permissions.set(permissionKey, permission);
|
|
154
|
+
return true;
|
|
155
|
+
}
|
|
156
|
+
// Private helper methods
|
|
157
|
+
addInheritedRoles(roleName, inheritedRoles) {
|
|
158
|
+
const role = this.roles.get(roleName);
|
|
159
|
+
if (!role || !role.parent) {
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
inheritedRoles.add(role.parent);
|
|
163
|
+
this.addInheritedRoles(role.parent, inheritedRoles);
|
|
164
|
+
}
|
|
165
|
+
async checkConditions(conditions, context) {
|
|
166
|
+
for (const condition of conditions) {
|
|
167
|
+
const contextValue = context[condition.field];
|
|
168
|
+
if (!this.evaluateCondition(contextValue, condition.operator, condition.value)) {
|
|
169
|
+
return false;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
return true;
|
|
173
|
+
}
|
|
174
|
+
evaluateCondition(contextValue, operator, conditionValue) {
|
|
175
|
+
switch (operator) {
|
|
176
|
+
case 'equals':
|
|
177
|
+
return contextValue === conditionValue;
|
|
178
|
+
case 'contains':
|
|
179
|
+
return typeof contextValue === 'string' && contextValue.includes(conditionValue);
|
|
180
|
+
case 'startsWith':
|
|
181
|
+
return typeof contextValue === 'string' && contextValue.startsWith(conditionValue);
|
|
182
|
+
case 'endsWith':
|
|
183
|
+
return typeof contextValue === 'string' && contextValue.endsWith(conditionValue);
|
|
184
|
+
case 'regex':
|
|
185
|
+
return typeof contextValue === 'string' && new RegExp(conditionValue).test(contextValue);
|
|
186
|
+
default:
|
|
187
|
+
return false;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
exports.BasicRBACManager = BasicRBACManager;
|
|
192
|
+
//# sourceMappingURL=rbac-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rbac-manager.js","sourceRoot":"","sources":["../../src/managers/rbac-manager.ts"],"names":[],"mappings":"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"}
|