simple-m-auth 1.0.2 → 1.0.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/README.md +44 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +12 -0
- package/dist/config.js.map +1 -1
- package/dist/crypto.d.ts +8 -0
- package/dist/crypto.d.ts.map +1 -1
- package/dist/crypto.js +60 -0
- package/dist/crypto.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/session.d.ts +8 -3
- package/dist/session.d.ts.map +1 -1
- package/dist/session.js +51 -4
- package/dist/session.js.map +1 -1
- package/dist/types.d.ts +34 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -136,6 +136,50 @@ async function logout() {
|
|
|
136
136
|
}
|
|
137
137
|
```
|
|
138
138
|
|
|
139
|
+
## JWT Support (Stateless Tokens)
|
|
140
|
+
|
|
141
|
+
Enable short-lived JWTs for faster authentication. Based on [Lucia Auth stateless tokens](https://lucia-auth.com/sessions/stateless-tokens) principles:
|
|
142
|
+
|
|
143
|
+
- JWTs are short-lived (5 minutes default)
|
|
144
|
+
- `getUser()` checks JWT first (no DB lookup if valid)
|
|
145
|
+
- Falls back to session validation if JWT expired
|
|
146
|
+
- Auto-refreshes JWT when session is valid
|
|
147
|
+
|
|
148
|
+
Add `jwt` config:
|
|
149
|
+
|
|
150
|
+
```typescript
|
|
151
|
+
export const authConfig: AuthConfig = {
|
|
152
|
+
db: { /* ... */ },
|
|
153
|
+
cookie: { /* ... */ },
|
|
154
|
+
|
|
155
|
+
jwt: {
|
|
156
|
+
secret: 'your-32-character-or-longer-secret-key',
|
|
157
|
+
expiresIn: 300, // 5 minutes (default)
|
|
158
|
+
|
|
159
|
+
getJwtToken: (ctx?) => {
|
|
160
|
+
// Get from Authorization header
|
|
161
|
+
return ctx?.req?.headers.get('Authorization')?.replace('Bearer ', '') ?? null;
|
|
162
|
+
},
|
|
163
|
+
|
|
164
|
+
setJwtToken: (token, ctx?) => {
|
|
165
|
+
// Set in response header
|
|
166
|
+
ctx?.res?.headers.set('Authorization', `Bearer ${token}`);
|
|
167
|
+
},
|
|
168
|
+
},
|
|
169
|
+
};
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
Pass context to functions:
|
|
173
|
+
|
|
174
|
+
```typescript
|
|
175
|
+
// With context for JWT handlers
|
|
176
|
+
const user = await getUser({ req, res });
|
|
177
|
+
const session = await createSession(userId, { req, res });
|
|
178
|
+
|
|
179
|
+
// Without JWT or when context not needed
|
|
180
|
+
const user = await getUser();
|
|
181
|
+
```
|
|
182
|
+
|
|
139
183
|
## Next.js Example
|
|
140
184
|
|
|
141
185
|
```typescript
|
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAa7C,wBAAsB,UAAU,IAAI,OAAO,CAAC,UAAU,CAAC,CA+BtD;
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAa7C,wBAAsB,UAAU,IAAI,OAAO,CAAC,UAAU,CAAC,CA+BtD;AA8CD,wBAAgB,SAAS,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI,CAGlD;AAED,wBAAgB,WAAW,IAAI,IAAI,CAElC"}
|
package/dist/config.js
CHANGED
|
@@ -60,6 +60,18 @@ function validateConfig(config) {
|
|
|
60
60
|
if (typeof config.cookie.delete !== 'function') {
|
|
61
61
|
throw new Error('AuthConfig.cookie.delete must be a function');
|
|
62
62
|
}
|
|
63
|
+
// JWT validation (optional, but if provided must be complete)
|
|
64
|
+
if (config.jwt) {
|
|
65
|
+
if (typeof config.jwt.secret !== 'string' || config.jwt.secret.length < 32) {
|
|
66
|
+
throw new Error('AuthConfig.jwt.secret must be a string of at least 32 characters');
|
|
67
|
+
}
|
|
68
|
+
if (typeof config.jwt.getJwtToken !== 'function') {
|
|
69
|
+
throw new Error('AuthConfig.jwt.getJwtToken must be a function');
|
|
70
|
+
}
|
|
71
|
+
if (typeof config.jwt.setJwtToken !== 'function') {
|
|
72
|
+
throw new Error('AuthConfig.jwt.setJwtToken must be a function');
|
|
73
|
+
}
|
|
74
|
+
}
|
|
63
75
|
}
|
|
64
76
|
// Allow manual config setting (useful for testing or non-standard setups)
|
|
65
77
|
export function setConfig(config) {
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
package/dist/crypto.d.ts
CHANGED
|
@@ -5,4 +5,12 @@ export declare function parseToken(token: string): {
|
|
|
5
5
|
id: string;
|
|
6
6
|
secret: string;
|
|
7
7
|
} | null;
|
|
8
|
+
export interface JwtPayload {
|
|
9
|
+
sessionId: string;
|
|
10
|
+
userId: string;
|
|
11
|
+
iat: number;
|
|
12
|
+
exp: number;
|
|
13
|
+
}
|
|
14
|
+
export declare function signJwt(payload: JwtPayload, secret: string): Promise<string>;
|
|
15
|
+
export declare function verifyJwt(token: string, secret: string): Promise<JwtPayload | null>;
|
|
8
16
|
//# sourceMappingURL=crypto.d.ts.map
|
package/dist/crypto.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"crypto.d.ts","sourceRoot":"","sources":["../src/crypto.ts"],"names":[],"mappings":"AAEA,wBAAgB,0BAA0B,IAAI,MAAM,CASnD;AAED,wBAAsB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAIpE;AAED,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,GAAG,OAAO,CASvE;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAM/E"}
|
|
1
|
+
{"version":3,"file":"crypto.d.ts","sourceRoot":"","sources":["../src/crypto.ts"],"names":[],"mappings":"AAEA,wBAAgB,0BAA0B,IAAI,MAAM,CASnD;AAED,wBAAsB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAIpE;AAED,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,GAAG,OAAO,CASvE;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAM/E;AA2BD,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;CACb;AAID,wBAAsB,OAAO,CAAC,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAWlF;AAED,wBAAsB,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CA0CzF"}
|
package/dist/crypto.js
CHANGED
|
@@ -30,4 +30,64 @@ export function parseToken(token) {
|
|
|
30
30
|
}
|
|
31
31
|
return { id: parts[0], secret: parts[1] };
|
|
32
32
|
}
|
|
33
|
+
// JWT utilities using HMAC SHA-256
|
|
34
|
+
function base64UrlEncode(data) {
|
|
35
|
+
const base64 = btoa(String.fromCharCode(...data));
|
|
36
|
+
return base64.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
|
|
37
|
+
}
|
|
38
|
+
function base64UrlDecode(str) {
|
|
39
|
+
const base64 = str.replace(/-/g, '+').replace(/_/g, '/');
|
|
40
|
+
const padded = base64 + '='.repeat((4 - (base64.length % 4)) % 4);
|
|
41
|
+
const binary = atob(padded);
|
|
42
|
+
return Uint8Array.from(binary, (c) => c.charCodeAt(0));
|
|
43
|
+
}
|
|
44
|
+
async function getHmacKey(secret) {
|
|
45
|
+
const encoder = new TextEncoder();
|
|
46
|
+
return crypto.subtle.importKey('raw', encoder.encode(secret), { name: 'HMAC', hash: 'SHA-256' }, false, ['sign', 'verify']);
|
|
47
|
+
}
|
|
48
|
+
const JWT_HEADER = { alg: 'HS256', typ: 'JWT' };
|
|
49
|
+
export async function signJwt(payload, secret) {
|
|
50
|
+
const encoder = new TextEncoder();
|
|
51
|
+
const headerB64 = base64UrlEncode(encoder.encode(JSON.stringify(JWT_HEADER)));
|
|
52
|
+
const payloadB64 = base64UrlEncode(encoder.encode(JSON.stringify(payload)));
|
|
53
|
+
const data = `${headerB64}.${payloadB64}`;
|
|
54
|
+
const key = await getHmacKey(secret);
|
|
55
|
+
const signature = await crypto.subtle.sign('HMAC', key, encoder.encode(data));
|
|
56
|
+
return `${data}.${base64UrlEncode(new Uint8Array(signature))}`;
|
|
57
|
+
}
|
|
58
|
+
export async function verifyJwt(token, secret) {
|
|
59
|
+
const parts = token.split('.');
|
|
60
|
+
if (parts.length !== 3) {
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
const [headerB64, payloadB64, signatureB64] = parts;
|
|
64
|
+
try {
|
|
65
|
+
// Verify header
|
|
66
|
+
const header = JSON.parse(new TextDecoder().decode(base64UrlDecode(headerB64)));
|
|
67
|
+
if (header.alg !== 'HS256' || header.typ !== 'JWT') {
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
// Verify signature
|
|
71
|
+
const key = await getHmacKey(secret);
|
|
72
|
+
const data = `${headerB64}.${payloadB64}`;
|
|
73
|
+
const signature = base64UrlDecode(signatureB64);
|
|
74
|
+
const encoder = new TextEncoder();
|
|
75
|
+
const signatureArray = new Uint8Array(signature);
|
|
76
|
+
const isValid = await crypto.subtle.verify('HMAC', key, signatureArray, encoder.encode(data));
|
|
77
|
+
if (!isValid) {
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
// Parse and validate payload
|
|
81
|
+
const payload = JSON.parse(new TextDecoder().decode(base64UrlDecode(payloadB64)));
|
|
82
|
+
// Check expiration
|
|
83
|
+
const now = Math.floor(Date.now() / 1000);
|
|
84
|
+
if (payload.exp < now) {
|
|
85
|
+
return null;
|
|
86
|
+
}
|
|
87
|
+
return payload;
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
return null;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
33
93
|
//# sourceMappingURL=crypto.js.map
|
package/dist/crypto.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"crypto.js","sourceRoot":"","sources":["../src/crypto.ts"],"names":[],"mappings":"AAAA,MAAM,QAAQ,GAAG,kCAAkC,CAAC,CAAC,qCAAqC;AAE1F,MAAM,UAAU,0BAA0B;IACxC,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,sBAAsB;IACxD,MAAM,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;IAE9B,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,IAAI,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IACpC,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,MAAc;IAC7C,MAAM,WAAW,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACrD,MAAM,UAAU,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;IACtE,OAAO,IAAI,UAAU,CAAC,UAAU,CAAC,CAAC;AACpC,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,CAAa,EAAE,CAAa;IAC5D,IAAI,CAAC,CAAC,UAAU,KAAK,CAAC,CAAC,UAAU,EAAE,CAAC;QAClC,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACnB,CAAC;IACD,OAAO,CAAC,KAAK,CAAC,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,KAAa;IACtC,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC/B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,EAAE,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;AAC5C,CAAC"}
|
|
1
|
+
{"version":3,"file":"crypto.js","sourceRoot":"","sources":["../src/crypto.ts"],"names":[],"mappings":"AAAA,MAAM,QAAQ,GAAG,kCAAkC,CAAC,CAAC,qCAAqC;AAE1F,MAAM,UAAU,0BAA0B;IACxC,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,sBAAsB;IACxD,MAAM,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;IAE9B,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,IAAI,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IACpC,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,MAAc;IAC7C,MAAM,WAAW,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACrD,MAAM,UAAU,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;IACtE,OAAO,IAAI,UAAU,CAAC,UAAU,CAAC,CAAC;AACpC,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,CAAa,EAAE,CAAa;IAC5D,IAAI,CAAC,CAAC,UAAU,KAAK,CAAC,CAAC,UAAU,EAAE,CAAC;QAClC,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACnB,CAAC;IACD,OAAO,CAAC,KAAK,CAAC,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,KAAa;IACtC,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC/B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,EAAE,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;AAC5C,CAAC;AAED,mCAAmC;AAEnC,SAAS,eAAe,CAAC,IAAgB;IACvC,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;IAClD,OAAO,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;AAC3E,CAAC;AAED,SAAS,eAAe,CAAC,GAAW;IAClC,MAAM,MAAM,GAAG,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IACzD,MAAM,MAAM,GAAG,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAClE,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC;IAC5B,OAAO,UAAU,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;AACzD,CAAC;AAED,KAAK,UAAU,UAAU,CAAC,MAAc;IACtC,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC;IAClC,OAAO,MAAM,CAAC,MAAM,CAAC,SAAS,CAC5B,KAAK,EACL,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,EACtB,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,EACjC,KAAK,EACL,CAAC,MAAM,EAAE,QAAQ,CAAC,CACnB,CAAC;AACJ,CAAC;AASD,MAAM,UAAU,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC;AAEhD,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,OAAmB,EAAE,MAAc;IAC/D,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC;IAElC,MAAM,SAAS,GAAG,eAAe,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;IAC9E,MAAM,UAAU,GAAG,eAAe,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IAC5E,MAAM,IAAI,GAAG,GAAG,SAAS,IAAI,UAAU,EAAE,CAAC;IAE1C,MAAM,GAAG,GAAG,MAAM,UAAU,CAAC,MAAM,CAAC,CAAC;IACrC,MAAM,SAAS,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;IAE9E,OAAO,GAAG,IAAI,IAAI,eAAe,CAAC,IAAI,UAAU,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC;AACjE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,KAAa,EAAE,MAAc;IAC3D,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC/B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,CAAC,SAAS,EAAE,UAAU,EAAE,YAAY,CAAC,GAAG,KAAK,CAAC;IAEpD,IAAI,CAAC;QACH,gBAAgB;QAChB,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;QAChF,IAAI,MAAM,CAAC,GAAG,KAAK,OAAO,IAAI,MAAM,CAAC,GAAG,KAAK,KAAK,EAAE,CAAC;YACnD,OAAO,IAAI,CAAC;QACd,CAAC;QAED,mBAAmB;QACnB,MAAM,GAAG,GAAG,MAAM,UAAU,CAAC,MAAM,CAAC,CAAC;QACrC,MAAM,IAAI,GAAG,GAAG,SAAS,IAAI,UAAU,EAAE,CAAC;QAC1C,MAAM,SAAS,GAAG,eAAe,CAAC,YAAY,CAAC,CAAC;QAChD,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC;QAElC,MAAM,cAAc,GAAG,IAAI,UAAU,CAAC,SAAS,CAAC,CAAC;QACjD,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,EAAE,cAAc,EAAE,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;QAC9F,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,IAAI,CAAC;QACd,CAAC;QAED,6BAA6B;QAC7B,MAAM,OAAO,GAAe,IAAI,CAAC,KAAK,CACpC,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC,CACtD,CAAC;QAEF,mBAAmB;QACnB,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;QAC1C,IAAI,OAAO,CAAC,GAAG,GAAG,GAAG,EAAE,CAAC;YACtB,OAAO,IAAI,CAAC;QACd,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export type { AuthConfig, Session, SessionWithToken, CookieOptions, } from './types.js';
|
|
1
|
+
export type { AuthConfig, Session, SessionWithToken, CookieOptions, JwtConfig, JwtPayload, } from './types.js';
|
|
2
2
|
export { createSession, validateSession, getUser, deleteSession, deleteSessionById, } from './session.js';
|
|
3
3
|
export { setConfig, clearConfig } from './config.js';
|
|
4
|
-
export { generateSecureRandomString, hashSecret, constantTimeEqual, } from './crypto.js';
|
|
4
|
+
export { generateSecureRandomString, hashSecret, constantTimeEqual, signJwt, verifyJwt, } from './crypto.js';
|
|
5
5
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,YAAY,EACV,UAAU,EACV,OAAO,EACP,gBAAgB,EAChB,aAAa,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,YAAY,EACV,UAAU,EACV,OAAO,EACP,gBAAgB,EAChB,aAAa,EACb,SAAS,EACT,UAAU,GACX,MAAM,YAAY,CAAC;AAGpB,OAAO,EACL,aAAa,EACb,eAAe,EACf,OAAO,EACP,aAAa,EACb,iBAAiB,GAClB,MAAM,cAAc,CAAC;AAGtB,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAGrD,OAAO,EACL,0BAA0B,EAC1B,UAAU,EACV,iBAAiB,EACjB,OAAO,EACP,SAAS,GACV,MAAM,aAAa,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -3,5 +3,5 @@ export { createSession, validateSession, getUser, deleteSession, deleteSessionBy
|
|
|
3
3
|
// Config utilities (for advanced use)
|
|
4
4
|
export { setConfig, clearConfig } from './config.js';
|
|
5
5
|
// Crypto utilities (if someone needs them)
|
|
6
|
-
export { generateSecureRandomString, hashSecret, constantTimeEqual, } from './crypto.js';
|
|
6
|
+
export { generateSecureRandomString, hashSecret, constantTimeEqual, signJwt, verifyJwt, } from './crypto.js';
|
|
7
7
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAUA,oBAAoB;AACpB,OAAO,EACL,aAAa,EACb,eAAe,EACf,OAAO,EACP,aAAa,EACb,iBAAiB,GAClB,MAAM,cAAc,CAAC;AAEtB,sCAAsC;AACtC,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAErD,2CAA2C;AAC3C,OAAO,EACL,0BAA0B,EAC1B,UAAU,EACV,iBAAiB,EACjB,OAAO,EACP,SAAS,GACV,MAAM,aAAa,CAAC"}
|
package/dist/session.d.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import type { Session, SessionWithToken } from './types.js';
|
|
2
2
|
/**
|
|
3
3
|
* Create a new session for a user and set the cookie
|
|
4
|
+
* @param userId - The user ID to create a session for
|
|
5
|
+
* @param context - Optional context to pass to JWT handlers (e.g., request/response objects)
|
|
4
6
|
*/
|
|
5
|
-
export declare function createSession(userId: string): Promise<SessionWithToken>;
|
|
7
|
+
export declare function createSession<TContext = unknown>(userId: string, context?: TContext): Promise<SessionWithToken>;
|
|
6
8
|
/**
|
|
7
9
|
* Validate the current session from cookie
|
|
8
10
|
* Returns the session if valid, null otherwise
|
|
@@ -10,9 +12,12 @@ export declare function createSession(userId: string): Promise<SessionWithToken>
|
|
|
10
12
|
export declare function validateSession(): Promise<Session | null>;
|
|
11
13
|
/**
|
|
12
14
|
* Get the current user from session
|
|
13
|
-
*
|
|
15
|
+
* When JWT is enabled, first checks JWT for fast validation.
|
|
16
|
+
* If JWT is expired/invalid, falls back to session validation and refreshes JWT.
|
|
17
|
+
* Returns null if no valid session or user not found.
|
|
18
|
+
* @param context - Optional context to pass to JWT handlers (e.g., request/response objects)
|
|
14
19
|
*/
|
|
15
|
-
export declare function getUser<TUser = any>(): Promise<TUser | null>;
|
|
20
|
+
export declare function getUser<TUser = any, TContext = unknown>(context?: TContext): Promise<TUser | null>;
|
|
16
21
|
/**
|
|
17
22
|
* Delete the current session and clear cookie
|
|
18
23
|
*/
|
package/dist/session.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,gBAAgB,
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,gBAAgB,EAAc,MAAM,YAAY,CAAC;AAkCxE;;;;GAIG;AACH,wBAAsB,aAAa,CAAC,QAAQ,GAAG,OAAO,EACpD,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,QAAQ,GACjB,OAAO,CAAC,gBAAgB,CAAC,CA2C3B;AAED;;;GAGG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAoC/D;AAED;;;;;;GAMG;AACH,wBAAsB,OAAO,CAAC,KAAK,GAAG,GAAG,EAAE,QAAQ,GAAG,OAAO,EAC3D,OAAO,CAAC,EAAE,QAAQ,GACjB,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,CA2CvB;AAED;;GAEG;AACH,wBAAsB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAenD;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAGxE"}
|
package/dist/session.js
CHANGED
|
@@ -1,11 +1,27 @@
|
|
|
1
1
|
import { loadConfig } from './config.js';
|
|
2
|
-
import { generateSecureRandomString, hashSecret, constantTimeEqual, parseToken, } from './crypto.js';
|
|
2
|
+
import { generateSecureRandomString, hashSecret, constantTimeEqual, parseToken, signJwt, verifyJwt, } from './crypto.js';
|
|
3
3
|
const DEFAULT_EXPIRES_IN = 60 * 60 * 24; // 24 hours
|
|
4
4
|
const DEFAULT_COOKIE_NAME = 'session_token';
|
|
5
|
+
const DEFAULT_JWT_EXPIRES_IN = 60 * 5; // 5 minutes (short-lived per Lucia Auth)
|
|
6
|
+
/**
|
|
7
|
+
* Create a JWT for a session
|
|
8
|
+
*/
|
|
9
|
+
async function createJwtForSession(sessionId, userId, secret, expiresIn) {
|
|
10
|
+
const now = Math.floor(Date.now() / 1000);
|
|
11
|
+
const payload = {
|
|
12
|
+
sessionId,
|
|
13
|
+
userId,
|
|
14
|
+
iat: now,
|
|
15
|
+
exp: now + expiresIn,
|
|
16
|
+
};
|
|
17
|
+
return signJwt(payload, secret);
|
|
18
|
+
}
|
|
5
19
|
/**
|
|
6
20
|
* Create a new session for a user and set the cookie
|
|
21
|
+
* @param userId - The user ID to create a session for
|
|
22
|
+
* @param context - Optional context to pass to JWT handlers (e.g., request/response objects)
|
|
7
23
|
*/
|
|
8
|
-
export async function createSession(userId) {
|
|
24
|
+
export async function createSession(userId, context) {
|
|
9
25
|
const config = await loadConfig();
|
|
10
26
|
const id = generateSecureRandomString();
|
|
11
27
|
const secret = generateSecureRandomString();
|
|
@@ -34,6 +50,12 @@ export async function createSession(userId) {
|
|
|
34
50
|
path: '/',
|
|
35
51
|
sameSite: 'lax',
|
|
36
52
|
});
|
|
53
|
+
// Issue JWT if enabled
|
|
54
|
+
if (config.jwt) {
|
|
55
|
+
const jwtExpiresIn = config.jwt.expiresIn ?? DEFAULT_JWT_EXPIRES_IN;
|
|
56
|
+
const jwt = await createJwtForSession(id, userId, config.jwt.secret, jwtExpiresIn);
|
|
57
|
+
await config.jwt.setJwtToken(jwt, context);
|
|
58
|
+
}
|
|
37
59
|
return session;
|
|
38
60
|
}
|
|
39
61
|
/**
|
|
@@ -73,10 +95,35 @@ export async function validateSession() {
|
|
|
73
95
|
}
|
|
74
96
|
/**
|
|
75
97
|
* Get the current user from session
|
|
76
|
-
*
|
|
98
|
+
* When JWT is enabled, first checks JWT for fast validation.
|
|
99
|
+
* If JWT is expired/invalid, falls back to session validation and refreshes JWT.
|
|
100
|
+
* Returns null if no valid session or user not found.
|
|
101
|
+
* @param context - Optional context to pass to JWT handlers (e.g., request/response objects)
|
|
77
102
|
*/
|
|
78
|
-
export async function getUser() {
|
|
103
|
+
export async function getUser(context) {
|
|
79
104
|
const config = await loadConfig();
|
|
105
|
+
// If JWT is enabled, try JWT first (fast path - no DB lookup)
|
|
106
|
+
if (config.jwt) {
|
|
107
|
+
const jwtToken = await config.jwt.getJwtToken(context);
|
|
108
|
+
if (jwtToken) {
|
|
109
|
+
const payload = await verifyJwt(jwtToken, config.jwt.secret);
|
|
110
|
+
if (payload) {
|
|
111
|
+
// JWT is valid, get user directly without session validation
|
|
112
|
+
return config.db.getUserById(payload.userId);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
// JWT missing or invalid - fall back to session validation
|
|
116
|
+
const session = await validateSession();
|
|
117
|
+
if (!session) {
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
120
|
+
// Session is valid - refresh the JWT
|
|
121
|
+
const jwtExpiresIn = config.jwt.expiresIn ?? DEFAULT_JWT_EXPIRES_IN;
|
|
122
|
+
const newJwt = await createJwtForSession(session.id, session.userId, config.jwt.secret, jwtExpiresIn);
|
|
123
|
+
await config.jwt.setJwtToken(newJwt, context);
|
|
124
|
+
return config.db.getUserById(session.userId);
|
|
125
|
+
}
|
|
126
|
+
// No JWT configured - use regular session validation
|
|
80
127
|
const session = await validateSession();
|
|
81
128
|
if (!session) {
|
|
82
129
|
return null;
|
package/dist/session.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.js","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EACL,0BAA0B,EAC1B,UAAU,EACV,iBAAiB,EACjB,UAAU,
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -14,6 +14,34 @@ export interface CookieOptions {
|
|
|
14
14
|
path: string;
|
|
15
15
|
sameSite: 'lax' | 'strict' | 'none';
|
|
16
16
|
}
|
|
17
|
+
export interface JwtPayload {
|
|
18
|
+
sessionId: string;
|
|
19
|
+
userId: string;
|
|
20
|
+
iat: number;
|
|
21
|
+
exp: number;
|
|
22
|
+
}
|
|
23
|
+
export interface JwtConfig<TContext = unknown> {
|
|
24
|
+
/**
|
|
25
|
+
* Secret key for signing JWTs (min 32 characters recommended)
|
|
26
|
+
*/
|
|
27
|
+
secret: string;
|
|
28
|
+
/**
|
|
29
|
+
* JWT lifespan in seconds (default: 300 = 5 minutes)
|
|
30
|
+
* Keep short as per Lucia Auth recommendations
|
|
31
|
+
*/
|
|
32
|
+
expiresIn?: number;
|
|
33
|
+
/**
|
|
34
|
+
* Get JWT from request (e.g., from Authorization header)
|
|
35
|
+
* @param context - Optional context (e.g., request object, headers, etc.)
|
|
36
|
+
*/
|
|
37
|
+
getJwtToken: (context?: TContext) => string | null | Promise<string | null>;
|
|
38
|
+
/**
|
|
39
|
+
* Set JWT in response (e.g., in Authorization header or response body)
|
|
40
|
+
* @param token - The JWT token to set
|
|
41
|
+
* @param context - Optional context (e.g., response object, headers, etc.)
|
|
42
|
+
*/
|
|
43
|
+
setJwtToken: (token: string, context?: TContext) => void | Promise<void>;
|
|
44
|
+
}
|
|
17
45
|
export interface AuthConfig<TUser = any> {
|
|
18
46
|
db: {
|
|
19
47
|
insertSession: (session: Session) => Promise<void>;
|
|
@@ -26,6 +54,12 @@ export interface AuthConfig<TUser = any> {
|
|
|
26
54
|
get: (name: string) => string | null | Promise<string | null>;
|
|
27
55
|
delete: (name: string) => void | Promise<void>;
|
|
28
56
|
};
|
|
57
|
+
/**
|
|
58
|
+
* Enable stateless JWT tokens for faster user lookups.
|
|
59
|
+
* When enabled, getUser() will first check the JWT before hitting the database.
|
|
60
|
+
* JWTs are short-lived (5 min default) and auto-refresh on valid session.
|
|
61
|
+
*/
|
|
62
|
+
jwt?: JwtConfig;
|
|
29
63
|
sessionExpiresIn?: number;
|
|
30
64
|
cookieName?: string;
|
|
31
65
|
}
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,UAAU,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,IAAI,CAAC;CACjB;AAED,MAAM,WAAW,gBAAiB,SAAQ,OAAO;IAC/C,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,OAAO,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;CACrC;AAED,MAAM,WAAW,UAAU,CAAC,KAAK,GAAG,GAAG;IACrC,EAAE,EAAE;QACF,aAAa,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;QACnD,cAAc,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;QAC/D,aAAa,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;QACpD,WAAW,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC;KACxD,CAAC;IAEF,MAAM,EAAE;QACN,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QACnF,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;QAC9D,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;KAChD,CAAC;IAEF,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,UAAU,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,IAAI,CAAC;CACjB;AAED,MAAM,WAAW,gBAAiB,SAAQ,OAAO;IAC/C,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,OAAO,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;CACrC;AAED,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,SAAS,CAAC,QAAQ,GAAG,OAAO;IAC3C;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IAEf;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;OAGG;IACH,WAAW,EAAE,CAAC,OAAO,CAAC,EAAE,QAAQ,KAAK,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAE5E;;;;OAIG;IACH,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,QAAQ,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1E;AAED,MAAM,WAAW,UAAU,CAAC,KAAK,GAAG,GAAG;IACrC,EAAE,EAAE;QACF,aAAa,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;QACnD,cAAc,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;QAC/D,aAAa,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;QACpD,WAAW,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC;KACxD,CAAC;IAEF,MAAM,EAAE;QACN,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QACnF,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;QAC9D,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;KAChD,CAAC;IAEF;;;;OAIG;IACH,GAAG,CAAC,EAAE,SAAS,CAAC;IAEhB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB"}
|