@rapidrest/auth 1.0.0-beta.1
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 +75 -0
- package/dist/lib/auth/BasicStrategy.js +82 -0
- package/dist/lib/auth/BasicStrategy.js.map +1 -0
- package/dist/lib/auth/FIDO2Strategy.js +179 -0
- package/dist/lib/auth/FIDO2Strategy.js.map +1 -0
- package/dist/lib/auth/MFAStrategy.js +219 -0
- package/dist/lib/auth/MFAStrategy.js.map +1 -0
- package/dist/lib/auth/OIDCStrategy.js +397 -0
- package/dist/lib/auth/OIDCStrategy.js.map +1 -0
- package/dist/lib/auth/OTPStrategy.js +143 -0
- package/dist/lib/auth/OTPStrategy.js.map +1 -0
- package/dist/lib/auth/PasskeyStrategy.js +185 -0
- package/dist/lib/auth/PasskeyStrategy.js.map +1 -0
- package/dist/lib/auth/TOTPStrategy.js +84 -0
- package/dist/lib/auth/TOTPStrategy.js.map +1 -0
- package/dist/lib/auth/index.js +10 -0
- package/dist/lib/auth/index.js.map +1 -0
- package/dist/lib/auth/shared.js +431 -0
- package/dist/lib/auth/shared.js.map +1 -0
- package/dist/lib/auth/types.js +12 -0
- package/dist/lib/auth/types.js.map +1 -0
- package/dist/lib/index.js +4 -0
- package/dist/lib/index.js.map +1 -0
- package/dist/lib/models/index.js +2 -0
- package/dist/lib/models/index.js.map +1 -0
- package/dist/lib/models/mongo/AliasMongo.js +77 -0
- package/dist/lib/models/mongo/AliasMongo.js.map +1 -0
- package/dist/lib/models/mongo/ProfileMongo.js +99 -0
- package/dist/lib/models/mongo/ProfileMongo.js.map +1 -0
- package/dist/lib/models/mongo/SecretMongo.js +71 -0
- package/dist/lib/models/mongo/SecretMongo.js.map +1 -0
- package/dist/lib/models/mongo/UserMongo.js +71 -0
- package/dist/lib/models/mongo/UserMongo.js.map +1 -0
- package/dist/lib/models/mongo/index.js +5 -0
- package/dist/lib/models/mongo/index.js.map +1 -0
- package/dist/lib/models/mongo.js +2 -0
- package/dist/lib/models/mongo.js.map +1 -0
- package/dist/lib/models/sql/AliasSQL.js +77 -0
- package/dist/lib/models/sql/AliasSQL.js.map +1 -0
- package/dist/lib/models/sql/ProfileSQL.js +99 -0
- package/dist/lib/models/sql/ProfileSQL.js.map +1 -0
- package/dist/lib/models/sql/SecretSQL.js +71 -0
- package/dist/lib/models/sql/SecretSQL.js.map +1 -0
- package/dist/lib/models/sql/UserSQL.js +68 -0
- package/dist/lib/models/sql/UserSQL.js.map +1 -0
- package/dist/lib/models/sql/index.js +5 -0
- package/dist/lib/models/sql/index.js.map +1 -0
- package/dist/lib/models/sql.js +2 -0
- package/dist/lib/models/sql.js.map +1 -0
- package/dist/lib/models/types.js +35 -0
- package/dist/lib/models/types.js.map +1 -0
- package/dist/lib/mongo.js +3 -0
- package/dist/lib/mongo.js.map +1 -0
- package/dist/lib/routes/BaseAliasRoute.js +10 -0
- package/dist/lib/routes/BaseAliasRoute.js.map +1 -0
- package/dist/lib/routes/BaseAuthBasicRoute.js +132 -0
- package/dist/lib/routes/BaseAuthBasicRoute.js.map +1 -0
- package/dist/lib/routes/BaseAuthFIDO2Route.js +191 -0
- package/dist/lib/routes/BaseAuthFIDO2Route.js.map +1 -0
- package/dist/lib/routes/BaseAuthMFARoute.js +310 -0
- package/dist/lib/routes/BaseAuthMFARoute.js.map +1 -0
- package/dist/lib/routes/BaseAuthOIDCRoute.js +231 -0
- package/dist/lib/routes/BaseAuthOIDCRoute.js.map +1 -0
- package/dist/lib/routes/BaseAuthOTPRoute.js +214 -0
- package/dist/lib/routes/BaseAuthOTPRoute.js.map +1 -0
- package/dist/lib/routes/BaseAuthPasskeyRoute.js +182 -0
- package/dist/lib/routes/BaseAuthPasskeyRoute.js.map +1 -0
- package/dist/lib/routes/BaseAuthTOTPRoute.js +133 -0
- package/dist/lib/routes/BaseAuthTOTPRoute.js.map +1 -0
- package/dist/lib/routes/BaseProfileRoute.js +10 -0
- package/dist/lib/routes/BaseProfileRoute.js.map +1 -0
- package/dist/lib/routes/BaseSecretRoute.js +399 -0
- package/dist/lib/routes/BaseSecretRoute.js.map +1 -0
- package/dist/lib/routes/BaseUserRoute.js +10 -0
- package/dist/lib/routes/BaseUserRoute.js.map +1 -0
- package/dist/lib/routes/UserUtils.js +78 -0
- package/dist/lib/routes/UserUtils.js.map +1 -0
- package/dist/lib/routes/index.js +13 -0
- package/dist/lib/routes/index.js.map +1 -0
- package/dist/lib/routes/mongo/BaseAliasRouteMongo.js +20 -0
- package/dist/lib/routes/mongo/BaseAliasRouteMongo.js.map +1 -0
- package/dist/lib/routes/mongo/BaseAuthBasicRouteMongo.js +14 -0
- package/dist/lib/routes/mongo/BaseAuthBasicRouteMongo.js.map +1 -0
- package/dist/lib/routes/mongo/BaseAuthFIDO2RouteMongo.js +14 -0
- package/dist/lib/routes/mongo/BaseAuthFIDO2RouteMongo.js.map +1 -0
- package/dist/lib/routes/mongo/BaseAuthMFARouteMongo.js +14 -0
- package/dist/lib/routes/mongo/BaseAuthMFARouteMongo.js.map +1 -0
- package/dist/lib/routes/mongo/BaseAuthOIDCRouteMongo.js +11 -0
- package/dist/lib/routes/mongo/BaseAuthOIDCRouteMongo.js.map +1 -0
- package/dist/lib/routes/mongo/BaseAuthOTPRouteMongo.js +14 -0
- package/dist/lib/routes/mongo/BaseAuthOTPRouteMongo.js.map +1 -0
- package/dist/lib/routes/mongo/BaseAuthPasskeyRouteMongo.js +14 -0
- package/dist/lib/routes/mongo/BaseAuthPasskeyRouteMongo.js.map +1 -0
- package/dist/lib/routes/mongo/BaseAuthTOTPRouteMongo.js +14 -0
- package/dist/lib/routes/mongo/BaseAuthTOTPRouteMongo.js.map +1 -0
- package/dist/lib/routes/mongo/BaseProfileRouteMongo.js +20 -0
- package/dist/lib/routes/mongo/BaseProfileRouteMongo.js.map +1 -0
- package/dist/lib/routes/mongo/BaseSecretRouteMongo.js +20 -0
- package/dist/lib/routes/mongo/BaseSecretRouteMongo.js.map +1 -0
- package/dist/lib/routes/mongo/BaseUserRouteMongo.js +20 -0
- package/dist/lib/routes/mongo/BaseUserRouteMongo.js.map +1 -0
- package/dist/lib/routes/mongo/index.js +12 -0
- package/dist/lib/routes/mongo/index.js.map +1 -0
- package/dist/lib/routes/mongo.js +2 -0
- package/dist/lib/routes/mongo.js.map +1 -0
- package/dist/lib/routes/sql/BaseAliasRouteSQL.js +20 -0
- package/dist/lib/routes/sql/BaseAliasRouteSQL.js.map +1 -0
- package/dist/lib/routes/sql/BaseAuthBasicRouteSQL.js +14 -0
- package/dist/lib/routes/sql/BaseAuthBasicRouteSQL.js.map +1 -0
- package/dist/lib/routes/sql/BaseAuthFIDO2RouteSQL.js +14 -0
- package/dist/lib/routes/sql/BaseAuthFIDO2RouteSQL.js.map +1 -0
- package/dist/lib/routes/sql/BaseAuthMFARouteSQL.js +14 -0
- package/dist/lib/routes/sql/BaseAuthMFARouteSQL.js.map +1 -0
- package/dist/lib/routes/sql/BaseAuthOIDCRouteSQL.js +11 -0
- package/dist/lib/routes/sql/BaseAuthOIDCRouteSQL.js.map +1 -0
- package/dist/lib/routes/sql/BaseAuthOTPRouteSQL.js +14 -0
- package/dist/lib/routes/sql/BaseAuthOTPRouteSQL.js.map +1 -0
- package/dist/lib/routes/sql/BaseAuthPasskeyRouteSQL.js +14 -0
- package/dist/lib/routes/sql/BaseAuthPasskeyRouteSQL.js.map +1 -0
- package/dist/lib/routes/sql/BaseAuthTOTPRouteSQL.js +14 -0
- package/dist/lib/routes/sql/BaseAuthTOTPRouteSQL.js.map +1 -0
- package/dist/lib/routes/sql/BaseProfileRouteSQL.js +20 -0
- package/dist/lib/routes/sql/BaseProfileRouteSQL.js.map +1 -0
- package/dist/lib/routes/sql/BaseSecretRouteSQL.js +20 -0
- package/dist/lib/routes/sql/BaseSecretRouteSQL.js.map +1 -0
- package/dist/lib/routes/sql/BaseUserRouteSQL.js +20 -0
- package/dist/lib/routes/sql/BaseUserRouteSQL.js.map +1 -0
- package/dist/lib/routes/sql/index.js +12 -0
- package/dist/lib/routes/sql/index.js.map +1 -0
- package/dist/lib/routes/sql.js +2 -0
- package/dist/lib/routes/sql.js.map +1 -0
- package/dist/lib/sql.js +3 -0
- package/dist/lib/sql.js.map +1 -0
- package/dist/types/auth/BasicStrategy.d.ts +39 -0
- package/dist/types/auth/FIDO2Strategy.d.ts +85 -0
- package/dist/types/auth/MFAStrategy.d.ts +110 -0
- package/dist/types/auth/OIDCStrategy.d.ts +188 -0
- package/dist/types/auth/OTPStrategy.d.ts +88 -0
- package/dist/types/auth/PasskeyStrategy.d.ts +81 -0
- package/dist/types/auth/TOTPStrategy.d.ts +49 -0
- package/dist/types/auth/index.d.ts +9 -0
- package/dist/types/auth/shared.d.ts +136 -0
- package/dist/types/auth/types.d.ts +127 -0
- package/dist/types/index.d.ts +3 -0
- package/dist/types/models/index.d.ts +1 -0
- package/dist/types/models/mongo/AliasMongo.d.ts +15 -0
- package/dist/types/models/mongo/ProfileMongo.d.ts +17 -0
- package/dist/types/models/mongo/SecretMongo.d.ts +14 -0
- package/dist/types/models/mongo/UserMongo.d.ts +14 -0
- package/dist/types/models/mongo/index.d.ts +4 -0
- package/dist/types/models/mongo.d.ts +1 -0
- package/dist/types/models/sql/AliasSQL.d.ts +15 -0
- package/dist/types/models/sql/ProfileSQL.d.ts +17 -0
- package/dist/types/models/sql/SecretSQL.d.ts +14 -0
- package/dist/types/models/sql/UserSQL.d.ts +14 -0
- package/dist/types/models/sql/index.d.ts +4 -0
- package/dist/types/models/sql.d.ts +1 -0
- package/dist/types/models/types.d.ts +136 -0
- package/dist/types/mongo.d.ts +2 -0
- package/dist/types/routes/BaseAliasRoute.d.ts +7 -0
- package/dist/types/routes/BaseAuthBasicRoute.d.ts +27 -0
- package/dist/types/routes/BaseAuthFIDO2Route.d.ts +50 -0
- package/dist/types/routes/BaseAuthMFARoute.d.ts +61 -0
- package/dist/types/routes/BaseAuthOIDCRoute.d.ts +33 -0
- package/dist/types/routes/BaseAuthOTPRoute.d.ts +53 -0
- package/dist/types/routes/BaseAuthPasskeyRoute.d.ts +41 -0
- package/dist/types/routes/BaseAuthTOTPRoute.d.ts +38 -0
- package/dist/types/routes/BaseProfileRoute.d.ts +7 -0
- package/dist/types/routes/BaseSecretRoute.d.ts +89 -0
- package/dist/types/routes/BaseUserRoute.d.ts +7 -0
- package/dist/types/routes/UserUtils.d.ts +21 -0
- package/dist/types/routes/index.d.ts +12 -0
- package/dist/types/routes/mongo/BaseAliasRouteMongo.d.ts +4 -0
- package/dist/types/routes/mongo/BaseAuthBasicRouteMongo.d.ts +7 -0
- package/dist/types/routes/mongo/BaseAuthFIDO2RouteMongo.d.ts +7 -0
- package/dist/types/routes/mongo/BaseAuthMFARouteMongo.d.ts +7 -0
- package/dist/types/routes/mongo/BaseAuthOIDCRouteMongo.d.ts +7 -0
- package/dist/types/routes/mongo/BaseAuthOTPRouteMongo.d.ts +7 -0
- package/dist/types/routes/mongo/BaseAuthPasskeyRouteMongo.d.ts +7 -0
- package/dist/types/routes/mongo/BaseAuthTOTPRouteMongo.d.ts +7 -0
- package/dist/types/routes/mongo/BaseProfileRouteMongo.d.ts +4 -0
- package/dist/types/routes/mongo/BaseSecretRouteMongo.d.ts +4 -0
- package/dist/types/routes/mongo/BaseUserRouteMongo.d.ts +4 -0
- package/dist/types/routes/mongo/index.d.ts +11 -0
- package/dist/types/routes/mongo.d.ts +1 -0
- package/dist/types/routes/sql/BaseAliasRouteSQL.d.ts +4 -0
- package/dist/types/routes/sql/BaseAuthBasicRouteSQL.d.ts +7 -0
- package/dist/types/routes/sql/BaseAuthFIDO2RouteSQL.d.ts +7 -0
- package/dist/types/routes/sql/BaseAuthMFARouteSQL.d.ts +7 -0
- package/dist/types/routes/sql/BaseAuthOIDCRouteSQL.d.ts +7 -0
- package/dist/types/routes/sql/BaseAuthOTPRouteSQL.d.ts +7 -0
- package/dist/types/routes/sql/BaseAuthPasskeyRouteSQL.d.ts +7 -0
- package/dist/types/routes/sql/BaseAuthTOTPRouteSQL.d.ts +7 -0
- package/dist/types/routes/sql/BaseProfileRouteSQL.d.ts +4 -0
- package/dist/types/routes/sql/BaseSecretRouteSQL.d.ts +4 -0
- package/dist/types/routes/sql/BaseUserRouteSQL.d.ts +4 -0
- package/dist/types/routes/sql/index.d.ts +11 -0
- package/dist/types/routes/sql.d.ts +1 -0
- package/dist/types/sql.d.ts +2 -0
- package/package.json +138 -0
|
@@ -0,0 +1,431 @@
|
|
|
1
|
+
import { OTPContactType, } from "./types.js";
|
|
2
|
+
const headerSchemeRegExps = new Map();
|
|
3
|
+
/**
|
|
4
|
+
* Attempts to decode the request for authentication Basic request data
|
|
5
|
+
* (e.g. `Authorization: basic base64("<id>:<password>")).
|
|
6
|
+
*
|
|
7
|
+
* @param req The request to return auth request data for.
|
|
8
|
+
* @param headerKey The name of a header to look for request data in. Set to an empty string to skip
|
|
9
|
+
* the header search entirely — passing `undefined` has no effect, since that just triggers the
|
|
10
|
+
* default value. Default is 'Authorization'.
|
|
11
|
+
* @param headerScheme The header scheme to look for. Default is 'basic'.
|
|
12
|
+
* @returns An object with format `{id: <username>, password: <password> }, otherwise `undefined`.
|
|
13
|
+
*/
|
|
14
|
+
export const getBasicData = function (req, headerKey = "authorization", headerScheme = "basic") {
|
|
15
|
+
let result = undefined;
|
|
16
|
+
// Check the headers. It's possible there is more than one header value defined. Loop through each of
|
|
17
|
+
// them until we have verified auth request data.
|
|
18
|
+
if (headerKey in req.headers) {
|
|
19
|
+
const value = req.headers[headerKey];
|
|
20
|
+
const headers = Array.isArray(value) ? value : typeof value === "string" ? [value] : [];
|
|
21
|
+
// Loop throught through the headers looking for a value with a matching scheme
|
|
22
|
+
for (const header in headers) {
|
|
23
|
+
const parts = headers[header].split(" ");
|
|
24
|
+
if (parts.length !== 2) {
|
|
25
|
+
continue;
|
|
26
|
+
}
|
|
27
|
+
const regexHeaderScheme = headerSchemeRegExps.get(headerScheme) ?? new RegExp("^" + headerScheme + "$", "i");
|
|
28
|
+
if (!headerSchemeRegExps.has(headerScheme)) {
|
|
29
|
+
headerSchemeRegExps.set(headerScheme, regexHeaderScheme);
|
|
30
|
+
}
|
|
31
|
+
if (!parts[0].match(regexHeaderScheme)) {
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
result = Buffer.from(parts[1], "base64").toString("utf-8");
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
if (typeof result === "string") {
|
|
38
|
+
const obj = {};
|
|
39
|
+
const parts = result.split(":");
|
|
40
|
+
obj.id = parts[0];
|
|
41
|
+
obj.password = parts[1];
|
|
42
|
+
result = obj;
|
|
43
|
+
}
|
|
44
|
+
return result;
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* Attempts to decode the request for authentication request data. The auth request data may be in a header, a query
|
|
48
|
+
* parameter or the request body itself. It may either be JSON encoded or form-data encoded. We want to return a
|
|
49
|
+
* regular object.
|
|
50
|
+
*
|
|
51
|
+
* @param req The request to return auth request data for.
|
|
52
|
+
* @param headerKey The name of a header to look for request data in. Set to an empty string to skip
|
|
53
|
+
* the header search entirely — passing `undefined` has no effect, since that just triggers the
|
|
54
|
+
* default value. Default is 'Authorization'.
|
|
55
|
+
* @param headerScheme The header scheme to look for. Default is 'basic'.
|
|
56
|
+
* @returns The found request data and its decoded payload object.
|
|
57
|
+
*/
|
|
58
|
+
export const getRequestData = function (req, headerKey = "authorization", headerScheme = "basic") {
|
|
59
|
+
let data = undefined;
|
|
60
|
+
let payload = undefined;
|
|
61
|
+
// The request body may have the form of JSON (`{ id: "...", password: "" }`) or form-data (`id=...&code=...`)
|
|
62
|
+
if (typeof req.body === "object") {
|
|
63
|
+
data = payload = req.body;
|
|
64
|
+
}
|
|
65
|
+
else if (typeof req.body === "string") {
|
|
66
|
+
// First try to see if this is actually JSON
|
|
67
|
+
try {
|
|
68
|
+
payload = JSON.parse(req.body);
|
|
69
|
+
}
|
|
70
|
+
catch (err) {
|
|
71
|
+
// The body is probably form-data. It'll be processed later
|
|
72
|
+
}
|
|
73
|
+
data = req.body;
|
|
74
|
+
}
|
|
75
|
+
// Check the headers. It's possible there is more than one header value defined. Loop through each of
|
|
76
|
+
// them until we have verified auth request data.
|
|
77
|
+
if (!data && headerKey && headerKey in req.headers) {
|
|
78
|
+
const value = req.headers[headerKey];
|
|
79
|
+
const headers = Array.isArray(value) ? value : typeof value === "string" ? [value] : [];
|
|
80
|
+
// Loop throught through the headers looking for a value with a matching scheme
|
|
81
|
+
for (const header in headers) {
|
|
82
|
+
const parts = headers[header].split(" ");
|
|
83
|
+
if (parts.length !== 2) {
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
const regexHeaderScheme = headerSchemeRegExps.get(headerScheme) ?? new RegExp("^" + headerScheme + "$", "i");
|
|
87
|
+
if (!headerSchemeRegExps.has(headerScheme)) {
|
|
88
|
+
headerSchemeRegExps.set(headerScheme, regexHeaderScheme);
|
|
89
|
+
}
|
|
90
|
+
if (!parts[0].match(regexHeaderScheme)) {
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
data = Buffer.from(parts[1], "base64").toString("utf-8");
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
// A string body that already parsed as JSON above has a real payload object — don't clobber it
|
|
97
|
+
// by re-parsing the same raw string as form-data/colon-delimited below.
|
|
98
|
+
if (typeof data === "string" && typeof payload !== "object") {
|
|
99
|
+
const obj = {};
|
|
100
|
+
// The string value may be ':' delimited (e.g. Basic auth) or form-data encoded.
|
|
101
|
+
// Detect which one it is and decode accordingly
|
|
102
|
+
if (data.includes("&")) {
|
|
103
|
+
const formParts = data.split("&");
|
|
104
|
+
for (const part of formParts) {
|
|
105
|
+
const parts = part.split("=");
|
|
106
|
+
obj[parts[0]] = parts[1] ?? undefined;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
else if (data.includes(":")) {
|
|
110
|
+
// This is dirty making assumptions like the following. Should really do
|
|
111
|
+
// something differently probably but I want to reduce the number of times
|
|
112
|
+
// this gets decoded.
|
|
113
|
+
const parts = data.split(":");
|
|
114
|
+
obj.id = parts[0];
|
|
115
|
+
obj.password = parts[1];
|
|
116
|
+
}
|
|
117
|
+
payload = obj;
|
|
118
|
+
}
|
|
119
|
+
return { data, payload };
|
|
120
|
+
};
|
|
121
|
+
export const isOTPResponse = function (response) {
|
|
122
|
+
return response.id && response.token;
|
|
123
|
+
};
|
|
124
|
+
export const isPasskeyResponse = function (response) {
|
|
125
|
+
if (typeof response.id !== "string" ||
|
|
126
|
+
typeof response.response?.clientDataJSON !== "string" ||
|
|
127
|
+
typeof response.response?.authenticatorData !== "string" ||
|
|
128
|
+
typeof response.response?.signature !== "string") {
|
|
129
|
+
return false;
|
|
130
|
+
}
|
|
131
|
+
return true;
|
|
132
|
+
};
|
|
133
|
+
/**
|
|
134
|
+
* Determines if the given value has the shape of a WebAuthn `RegistrationResponseJSON`, as produced by
|
|
135
|
+
* `navigator.credentials.create()` and submitted to finish a passkey registration ceremony.
|
|
136
|
+
*
|
|
137
|
+
* @param response The value to check.
|
|
138
|
+
*/
|
|
139
|
+
export const isPasskeyRegistrationResponse = function (response) {
|
|
140
|
+
if (typeof response?.id !== "string" ||
|
|
141
|
+
typeof response.response?.clientDataJSON !== "string" ||
|
|
142
|
+
typeof response.response?.attestationObject !== "string") {
|
|
143
|
+
return false;
|
|
144
|
+
}
|
|
145
|
+
return true;
|
|
146
|
+
};
|
|
147
|
+
/**
|
|
148
|
+
* Obfuscates the given contact and returns the obfuscated value.
|
|
149
|
+
* @param contact The contact to obfuscate.
|
|
150
|
+
*/
|
|
151
|
+
export const obfuscateContact = function (contact, type) {
|
|
152
|
+
let result = contact;
|
|
153
|
+
switch (type) {
|
|
154
|
+
case OTPContactType.EMAIL:
|
|
155
|
+
result = result.replace(/^(.).*(.{2})(@)/, "$1***$2$3");
|
|
156
|
+
break;
|
|
157
|
+
case OTPContactType.SMS:
|
|
158
|
+
result = result.replace(/.(?=.{4})/g, "*");
|
|
159
|
+
break;
|
|
160
|
+
}
|
|
161
|
+
return result;
|
|
162
|
+
};
|
|
163
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
164
|
+
// OTP
|
|
165
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
166
|
+
/**
|
|
167
|
+
* Generates and returns a new OTP token for authentication. This function stores relevant data for
|
|
168
|
+
* validation of the OTP token in the request's session.
|
|
169
|
+
* @param req The HTTP request to use for storing session data.
|
|
170
|
+
* @returns The generated OTP token.
|
|
171
|
+
*/
|
|
172
|
+
export const generateOTP = async function (req, requestData) {
|
|
173
|
+
if (!req.session) {
|
|
174
|
+
throw new Error("This function requires session support. Configure the `session` config " +
|
|
175
|
+
"block so the session middleware is registered.");
|
|
176
|
+
}
|
|
177
|
+
requestData = requestData ?? getRequestData(req).payload;
|
|
178
|
+
const otplib = await importOTPLib();
|
|
179
|
+
const secret = otplib.generateSecret();
|
|
180
|
+
const token = await otplib.generate({ secret });
|
|
181
|
+
// Store the OTP data in the session for later verification
|
|
182
|
+
req.session.id = requestData.id;
|
|
183
|
+
req.session.secret = secret;
|
|
184
|
+
req.session.token = token;
|
|
185
|
+
return token;
|
|
186
|
+
};
|
|
187
|
+
/**
|
|
188
|
+
* Validates the provided token against the data stored in the request session.
|
|
189
|
+
* @param token The OTP token to validate.
|
|
190
|
+
* @param req The HTTP request with OTP session data.
|
|
191
|
+
*/
|
|
192
|
+
export const verifyOTP = async function (req, payload) {
|
|
193
|
+
if (!req.session) {
|
|
194
|
+
throw new Error("This function requires session support. Configure the `session` config " +
|
|
195
|
+
"block so the session middleware is registered.");
|
|
196
|
+
}
|
|
197
|
+
payload = payload ?? getRequestData(req).payload;
|
|
198
|
+
if (!isOTPResponse(payload)) {
|
|
199
|
+
throw new Error("Invalid authentication request.");
|
|
200
|
+
}
|
|
201
|
+
if (req.session.id !== payload.id) {
|
|
202
|
+
throw new Error("Invalid authentication request.");
|
|
203
|
+
}
|
|
204
|
+
const otplib = await importOTPLib();
|
|
205
|
+
const result = await otplib.verify({
|
|
206
|
+
secret: req.session.secret,
|
|
207
|
+
token: payload.token,
|
|
208
|
+
});
|
|
209
|
+
return result.valid;
|
|
210
|
+
};
|
|
211
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
212
|
+
// PASSKEY
|
|
213
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
214
|
+
export const generatePasskeyChallenge = async function (config, req, allowCredentials) {
|
|
215
|
+
if (!req.session) {
|
|
216
|
+
throw new Error("This function requires session support. Configure the `session` config " +
|
|
217
|
+
"block so the session middleware is registered.");
|
|
218
|
+
}
|
|
219
|
+
const { generateAuthenticationOptions } = await importSimpleWebAuthn();
|
|
220
|
+
const result = await generateAuthenticationOptions({
|
|
221
|
+
rpID: config.rpID,
|
|
222
|
+
allowCredentials,
|
|
223
|
+
userVerification: config.userVerification,
|
|
224
|
+
timeout: config.timeout,
|
|
225
|
+
});
|
|
226
|
+
// Store the challenge in the session so it can be verified
|
|
227
|
+
req.session.challenge = result.challenge;
|
|
228
|
+
return result;
|
|
229
|
+
};
|
|
230
|
+
export const verifyPasskeyChallenge = async function (credential, config, expectedChallenge, payload) {
|
|
231
|
+
const { verifyAuthenticationResponse } = await importSimpleWebAuthn();
|
|
232
|
+
if (!Number.isFinite(credential.counter)) {
|
|
233
|
+
throw new Error("Stored passkey credential has an invalid counter.");
|
|
234
|
+
}
|
|
235
|
+
return await verifyAuthenticationResponse({
|
|
236
|
+
response: payload,
|
|
237
|
+
expectedChallenge,
|
|
238
|
+
expectedOrigin: config.origin,
|
|
239
|
+
expectedRPID: config.rpID,
|
|
240
|
+
credential: {
|
|
241
|
+
id: credential.id,
|
|
242
|
+
counter: credential.counter,
|
|
243
|
+
publicKey: credential.publicKey,
|
|
244
|
+
transports: credential.transports,
|
|
245
|
+
},
|
|
246
|
+
requireUserVerification: config.requireUserVerification ?? true,
|
|
247
|
+
});
|
|
248
|
+
};
|
|
249
|
+
/**
|
|
250
|
+
* Begins a registration ceremony: generates a set of `PublicKeyCredentialCreationOptions` and stores the
|
|
251
|
+
* challenge in the session for later verification. The result is meant to be returned directly to the
|
|
252
|
+
* client for use with `navigator.credentials.create()`.
|
|
253
|
+
*
|
|
254
|
+
* @param config The relying party configuration to use for this ceremony.
|
|
255
|
+
* @param req The source HTTP request. Used to persist the generated challenge in the session.
|
|
256
|
+
* @param user The user the new credential will be associated with.
|
|
257
|
+
* @param excludeCredentials The user's already-registered credentials, if any, so that the authenticator
|
|
258
|
+
* can avoid creating a duplicate credential for one it already holds.
|
|
259
|
+
*/
|
|
260
|
+
export const generatePasskeyRegistrationOptions = async function (config, req, user, excludeCredentials) {
|
|
261
|
+
if (!req.session) {
|
|
262
|
+
throw new Error("This function requires session support. Configure the `session` config " +
|
|
263
|
+
"block so the session middleware is registered.");
|
|
264
|
+
}
|
|
265
|
+
const { generateRegistrationOptions } = await importSimpleWebAuthn();
|
|
266
|
+
const result = await generateRegistrationOptions({
|
|
267
|
+
rpName: config.rpName,
|
|
268
|
+
rpID: config.rpID,
|
|
269
|
+
userName: user.name,
|
|
270
|
+
userID: new TextEncoder().encode(user.id),
|
|
271
|
+
userDisplayName: user.displayName,
|
|
272
|
+
timeout: config.timeout,
|
|
273
|
+
authenticatorSelection: {
|
|
274
|
+
userVerification: config.userVerification ?? "preferred",
|
|
275
|
+
authenticatorAttachment: config.authenticatorAttachment,
|
|
276
|
+
residentKey: config.residentKey,
|
|
277
|
+
},
|
|
278
|
+
excludeCredentials,
|
|
279
|
+
});
|
|
280
|
+
// Store the challenge in the session so it can be verified once the ceremony finishes.
|
|
281
|
+
req.session.challenge = result.challenge;
|
|
282
|
+
return result;
|
|
283
|
+
};
|
|
284
|
+
/**
|
|
285
|
+
* Finishes a registration ceremony: verifies the client-submitted attestation response against the
|
|
286
|
+
* stored challenge and relying party configuration.
|
|
287
|
+
*
|
|
288
|
+
* @param config The relying party configuration to verify the response against.
|
|
289
|
+
* @param expectedChallenge The challenge previously stored in the session by
|
|
290
|
+
* `generatePasskeyRegistrationOptions()`.
|
|
291
|
+
* @param payload The client-submitted `RegistrationResponseJSON`.
|
|
292
|
+
*/
|
|
293
|
+
export const verifyPasskeyRegistrationResponse = async function (config, expectedChallenge, payload) {
|
|
294
|
+
const { verifyRegistrationResponse } = await importSimpleWebAuthn();
|
|
295
|
+
return await verifyRegistrationResponse({
|
|
296
|
+
response: payload,
|
|
297
|
+
expectedChallenge,
|
|
298
|
+
expectedOrigin: config.origin,
|
|
299
|
+
expectedRPID: config.rpID,
|
|
300
|
+
requireUserVerification: config.requireUserVerification ?? true,
|
|
301
|
+
});
|
|
302
|
+
};
|
|
303
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
304
|
+
// TOTP
|
|
305
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
306
|
+
/**
|
|
307
|
+
* Generates and returns a new OTP token for authentication. This function stores relevant data for
|
|
308
|
+
* validation of the OTP token in the request's session.
|
|
309
|
+
* @param req The HTTP request to use for storing session data.
|
|
310
|
+
* @returns The generated OTP token.
|
|
311
|
+
*/
|
|
312
|
+
export const generateTOTP = async function (req, requestData) {
|
|
313
|
+
if (!req.session) {
|
|
314
|
+
throw new Error("This function requires session support. Configure the `session` config " +
|
|
315
|
+
"block so the session middleware is registered.");
|
|
316
|
+
}
|
|
317
|
+
requestData = requestData ?? getRequestData(req).payload;
|
|
318
|
+
const otplib = await importOTPLib();
|
|
319
|
+
const secret = otplib.generateSecret();
|
|
320
|
+
const token = await otplib.generate({ secret });
|
|
321
|
+
// Store the OTP data in the session for later verification
|
|
322
|
+
req.session.id = requestData.id;
|
|
323
|
+
req.session.secret = secret;
|
|
324
|
+
req.session.token = token;
|
|
325
|
+
return token;
|
|
326
|
+
};
|
|
327
|
+
/**
|
|
328
|
+
* Validates the provided token against the specified TOTP secret.
|
|
329
|
+
* @param token The OTP token to validate.
|
|
330
|
+
* @param secret The stored TOTP secret to validate the token against.
|
|
331
|
+
* @returns The otplib verification result if successful, otherwise `undefined`.
|
|
332
|
+
*/
|
|
333
|
+
export const verifyTOTP = async function (token, secret) {
|
|
334
|
+
const otplib = await importOTPLib();
|
|
335
|
+
// Check against all provided TOTP secrets. If at least one of the TOTP
|
|
336
|
+
// secrets is valid then we return success.
|
|
337
|
+
const secrets = Array.isArray(secret) ? secret : [secret];
|
|
338
|
+
for (const secret of secrets) {
|
|
339
|
+
const result = await otplib.verify({
|
|
340
|
+
...secret,
|
|
341
|
+
token,
|
|
342
|
+
});
|
|
343
|
+
if (result.valid) {
|
|
344
|
+
return result;
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
return undefined;
|
|
348
|
+
};
|
|
349
|
+
/**
|
|
350
|
+
* Determines if the given value is usable as a TOTP secret: a Base32-encoded string decoding to at
|
|
351
|
+
* least 128 bits, the minimum shared secret length mandated by RFC 4226 §4 (R6) (which RFC 6238
|
|
352
|
+
* TOTP secrets must also satisfy, per RFC 6238 §5.1).
|
|
353
|
+
*
|
|
354
|
+
* @param secret The value to check.
|
|
355
|
+
*/
|
|
356
|
+
export const isValidTOTPSecret = async function (secret) {
|
|
357
|
+
if (typeof secret !== "string" || secret.length === 0) {
|
|
358
|
+
return false;
|
|
359
|
+
}
|
|
360
|
+
try {
|
|
361
|
+
const { ScureBase32Plugin } = await importOTPLib();
|
|
362
|
+
const decoded = new ScureBase32Plugin().decode(secret);
|
|
363
|
+
// RFC 4226 §4 (R6): the shared secret MUST be at least 128 bits (16 bytes).
|
|
364
|
+
return decoded.length >= 16;
|
|
365
|
+
}
|
|
366
|
+
catch (err) {
|
|
367
|
+
return false;
|
|
368
|
+
}
|
|
369
|
+
};
|
|
370
|
+
/**
|
|
371
|
+
* Generates an `otpauth://` provisioning URI for the given TOTP secret — the "Key URI Format"
|
|
372
|
+
* convention (https://github.com/google/google-authenticator/wiki/Key-Uri-Format) that, while not
|
|
373
|
+
* itself an RFC, is the de facto standard virtually every TOTP authenticator app (Google
|
|
374
|
+
* Authenticator, Authy, 1Password, etc.) relies on to enroll a secret via QR code or manual entry.
|
|
375
|
+
*
|
|
376
|
+
* @param config The relying party configuration to generate the URI for.
|
|
377
|
+
* @param label The account label to embed in the URI (typically a username or email).
|
|
378
|
+
* @param secret The TOTP secret to encode into the URI.
|
|
379
|
+
*/
|
|
380
|
+
export const generateTOTPURI = async function (config, label, secret) {
|
|
381
|
+
const { generateURI } = await importOTPLib();
|
|
382
|
+
return generateURI({
|
|
383
|
+
issuer: config.issuer,
|
|
384
|
+
label,
|
|
385
|
+
secret: secret.secret,
|
|
386
|
+
algorithm: secret.algorithm ?? config.algorithm,
|
|
387
|
+
digits: secret.digits ?? config.digits,
|
|
388
|
+
period: secret.period ?? config.period,
|
|
389
|
+
});
|
|
390
|
+
};
|
|
391
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
392
|
+
// LIBRARY IMPORTS
|
|
393
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
394
|
+
/**
|
|
395
|
+
* Dynamically imports the optional peer dependency `argon2`, throwing a helpful
|
|
396
|
+
* error if it is not installed.
|
|
397
|
+
*/
|
|
398
|
+
export const importArgon2 = async function () {
|
|
399
|
+
try {
|
|
400
|
+
return await import("argon2");
|
|
401
|
+
}
|
|
402
|
+
catch (err) {
|
|
403
|
+
throw new Error("This feature requires the optional peer dependency 'argon2'. Install it with: yarn add argon2");
|
|
404
|
+
}
|
|
405
|
+
};
|
|
406
|
+
/**
|
|
407
|
+
* Dynamically imports the optional peer dependency `otplib`, throwing a helpful
|
|
408
|
+
* error if it is not installed.
|
|
409
|
+
*/
|
|
410
|
+
export const importOTPLib = async function () {
|
|
411
|
+
try {
|
|
412
|
+
return await import("otplib");
|
|
413
|
+
}
|
|
414
|
+
catch (err) {
|
|
415
|
+
throw new Error("This feature requires the optional peer dependency 'otplib'. Install it with: yarn add otplib");
|
|
416
|
+
}
|
|
417
|
+
};
|
|
418
|
+
/**
|
|
419
|
+
* Dynamically imports the optional peer dependency `@simplewebauthn/server`, throwing a helpful
|
|
420
|
+
* error if it is not installed.
|
|
421
|
+
*/
|
|
422
|
+
export const importSimpleWebAuthn = async function () {
|
|
423
|
+
try {
|
|
424
|
+
return await import("@simplewebauthn/server");
|
|
425
|
+
}
|
|
426
|
+
catch (err) {
|
|
427
|
+
throw new Error("This feature requires the optional peer dependency '@simplewebauthn/server'. Install it with: " +
|
|
428
|
+
"yarn add @simplewebauthn/server");
|
|
429
|
+
}
|
|
430
|
+
};
|
|
431
|
+
//# sourceMappingURL=shared.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared.js","sourceRoot":"","sources":["../../../src/auth/shared.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
////////////////////////////////////////////////////////////////////////////////
|
|
2
|
+
// Copyright (C) 2026 Jean-Philippe Steinmetz
|
|
3
|
+
////////////////////////////////////////////////////////////////////////////////
|
|
4
|
+
/**
|
|
5
|
+
* The different types of supported contact methods.
|
|
6
|
+
*/
|
|
7
|
+
export var OTPContactType;
|
|
8
|
+
(function (OTPContactType) {
|
|
9
|
+
OTPContactType["EMAIL"] = "email";
|
|
10
|
+
OTPContactType["SMS"] = "sms";
|
|
11
|
+
})(OTPContactType || (OTPContactType = {}));
|
|
12
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/auth/types.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,6CAA6C;AAC7C,gFAAgF;AAEhF;;GAEG;AACH,MAAM,CAAN,IAAY,cAGX;AAHD,WAAY,cAAc;IACtB,iCAAe,CAAA;IACf,6BAAW,CAAA;AACf,CAAC,EAHW,cAAc,KAAd,cAAc,QAGzB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/models/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
+
};
|
|
10
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
11
|
+
// Copyright (C) 2026 Jean-Philippe Steinmetz. All rights reserved.
|
|
12
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
13
|
+
import { BaseMongoEntity, DocDecorators, ModelDecorators, PersistenceDecorators } from "@rapidrest/service-core";
|
|
14
|
+
import { AliasType } from "../types.js";
|
|
15
|
+
const { Description } = DocDecorators;
|
|
16
|
+
const { DataStore, Identifier, Protect } = ModelDecorators;
|
|
17
|
+
const { Column, Entity, Index } = PersistenceDecorators;
|
|
18
|
+
/**
|
|
19
|
+
* Implementation of the `Alias` interface for storage in a MongoDB database. If SQL is desired, please use
|
|
20
|
+
* `models.sql.AliasSQL` instead.
|
|
21
|
+
*
|
|
22
|
+
* @author Jean-Philippe Steinmetz
|
|
23
|
+
*/
|
|
24
|
+
let AliasMongo = class AliasMongo extends BaseMongoEntity {
|
|
25
|
+
constructor(other) {
|
|
26
|
+
super(other);
|
|
27
|
+
this.alias = "";
|
|
28
|
+
this.type = AliasType.NAME;
|
|
29
|
+
this.userUid = "";
|
|
30
|
+
this.verified = false;
|
|
31
|
+
if (other) {
|
|
32
|
+
this.alias = other.alias !== undefined ? other.alias : this.alias;
|
|
33
|
+
this.type = other.type !== undefined ? other.type : this.type;
|
|
34
|
+
this.userUid = other.userUid !== undefined ? other.userUid : this.userUid;
|
|
35
|
+
this.verified = other.verified !== undefined ? other.verified : this.verified;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
__decorate([
|
|
40
|
+
Column(),
|
|
41
|
+
Identifier,
|
|
42
|
+
Index("alias", { unique: true }),
|
|
43
|
+
__metadata("design:type", String)
|
|
44
|
+
], AliasMongo.prototype, "alias", void 0);
|
|
45
|
+
__decorate([
|
|
46
|
+
Column(),
|
|
47
|
+
__metadata("design:type", String)
|
|
48
|
+
], AliasMongo.prototype, "type", void 0);
|
|
49
|
+
__decorate([
|
|
50
|
+
Column(),
|
|
51
|
+
__metadata("design:type", String)
|
|
52
|
+
], AliasMongo.prototype, "userUid", void 0);
|
|
53
|
+
__decorate([
|
|
54
|
+
Column(),
|
|
55
|
+
__metadata("design:type", Boolean)
|
|
56
|
+
], AliasMongo.prototype, "verified", void 0);
|
|
57
|
+
AliasMongo = __decorate([
|
|
58
|
+
DataStore("mongo"),
|
|
59
|
+
Entity(),
|
|
60
|
+
Description("Defines a record for a single user alias in the system."),
|
|
61
|
+
Protect({
|
|
62
|
+
uid: "UserMongo",
|
|
63
|
+
records: [
|
|
64
|
+
{
|
|
65
|
+
userOrRoleId: "anonymous",
|
|
66
|
+
actions: [],
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
userOrRoleId: ".*",
|
|
70
|
+
actions: [],
|
|
71
|
+
},
|
|
72
|
+
],
|
|
73
|
+
}),
|
|
74
|
+
__metadata("design:paramtypes", [Object])
|
|
75
|
+
], AliasMongo);
|
|
76
|
+
export { AliasMongo };
|
|
77
|
+
//# sourceMappingURL=AliasMongo.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AliasMongo.js","sourceRoot":"","sources":["../../../../src/models/mongo/AliasMongo.ts"],"names":[],"mappings":";;;;;;;;;AAAA,+EAA+E;AAC/E,mEAAmE;AACnE,+EAA+E;AAC/E,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AACjH,OAAO,EAAS,SAAS,EAAE,MAAM,aAAa,CAAC;AAC/C,MAAM,EAAE,WAAW,EAAE,GAAG,aAAa,CAAC;AACtC,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,OAAO,EAAE,GAAG,eAAe,CAAC;AAC3D,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,qBAAqB,CAAC;AAExD;;;;;GAKG;AAiBI,IAAM,UAAU,GAAhB,MAAM,UAAW,SAAQ,eAAe;IAe3C,YAAY,KAA2B;QACnC,KAAK,CAAC,KAAK,CAAC,CAAC;QAZV,UAAK,GAAW,EAAE,CAAC;QAGnB,SAAI,GAAc,SAAS,CAAC,IAAI,CAAC;QAGjC,YAAO,GAAW,EAAE,CAAC;QAGrB,aAAQ,GAAY,KAAK,CAAC;QAK7B,IAAI,KAAK,EAAE,CAAC;YACR,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC;YAClE,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;YAC9D,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC;YAC1E,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC;QAClF,CAAC;IACL,CAAC;CACJ,CAAA;AArBU;IAHN,MAAM,EAAE;IACR,UAAU;IACV,KAAK,CAAC,OAAO,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;;yCACP;AAGnB;IADN,MAAM,EAAE;;wCAC+B;AAGjC;IADN,MAAM,EAAE;;2CACmB;AAGrB;IADN,MAAM,EAAE;;4CACwB;AAbxB,UAAU;IAhBtB,SAAS,CAAC,OAAO,CAAC;IAClB,MAAM,EAAE;IACR,WAAW,CAAC,yDAAyD,CAAC;IACtE,OAAO,CAAC;QACL,GAAG,EAAE,WAAW;QAChB,OAAO,EAAE;YACL;gBACI,YAAY,EAAE,WAAW;gBACzB,OAAO,EAAE,EAAE;aACd;YACD;gBACI,YAAY,EAAE,IAAI;gBAClB,OAAO,EAAE,EAAE;aACd;SACJ;KACJ,CAAC;;GACW,UAAU,CAyBtB"}
|