huia-auth-core 1.0.0-alpha.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cookie.d.ts +15 -0
- package/dist/cookie.d.ts.map +1 -0
- package/dist/cookie.js +60 -0
- package/dist/cookie.js.map +1 -0
- package/dist/headless-client.d.ts +81 -0
- package/dist/headless-client.d.ts.map +1 -0
- package/dist/headless-client.js +231 -0
- package/dist/headless-client.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/oidc-client.d.ts +46 -0
- package/dist/oidc-client.d.ts.map +1 -0
- package/dist/oidc-client.js +122 -0
- package/dist/oidc-client.js.map +1 -0
- package/dist/refresh.d.ts +15 -0
- package/dist/refresh.d.ts.map +1 -0
- package/dist/refresh.js +87 -0
- package/dist/refresh.js.map +1 -0
- package/dist/storage.d.ts +50 -0
- package/dist/storage.d.ts.map +1 -0
- package/dist/storage.js +140 -0
- package/dist/storage.js.map +1 -0
- package/dist/tokens.d.ts +18 -0
- package/dist/tokens.d.ts.map +1 -0
- package/dist/tokens.js +69 -0
- package/dist/tokens.js.map +1 -0
- package/dist/types.d.ts +154 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/package.json +43 -0
package/dist/refresh.js
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { randomUUID } from 'uncrypto';
|
|
2
|
+
import { needsRefresh } from './tokens.js';
|
|
3
|
+
export class RefreshTokenExpiredError extends Error {
|
|
4
|
+
constructor(message = 'refresh_token_expired') {
|
|
5
|
+
super(message);
|
|
6
|
+
this.name = 'RefreshTokenExpiredError';
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
const inflight = new Map();
|
|
10
|
+
const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));
|
|
11
|
+
/**
|
|
12
|
+
* Ensures token record is fresh, using deduplicated in-memory promises and storage locking.
|
|
13
|
+
*/
|
|
14
|
+
export async function ensureFreshTokenRecord(storage, record, refreshFn, options = {}) {
|
|
15
|
+
const earlyRefreshSeconds = options.earlyRefreshSeconds ?? 30;
|
|
16
|
+
if (!needsRefresh(record.accessTokenExpiresAt, earlyRefreshSeconds)) {
|
|
17
|
+
return record;
|
|
18
|
+
}
|
|
19
|
+
const sid = record.sid;
|
|
20
|
+
const existing = inflight.get(sid);
|
|
21
|
+
if (existing)
|
|
22
|
+
return existing;
|
|
23
|
+
const p = guardedRefresh(storage, sid, record, refreshFn, options);
|
|
24
|
+
inflight.set(sid, p);
|
|
25
|
+
try {
|
|
26
|
+
return await p;
|
|
27
|
+
}
|
|
28
|
+
finally {
|
|
29
|
+
inflight.delete(sid);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
async function guardedRefresh(storage, sid, record, refreshFn, options) {
|
|
33
|
+
const lockId = randomUUID();
|
|
34
|
+
const ttlMs = options.ttlMs ?? 15000;
|
|
35
|
+
const maxWaitMs = options.maxWaitMs ?? 5000;
|
|
36
|
+
const retryIntervalMs = options.retryIntervalMs ?? 100;
|
|
37
|
+
// 1. Try to acquire the lock
|
|
38
|
+
if (await tryAcquireLock(storage, sid, lockId, ttlMs)) {
|
|
39
|
+
try {
|
|
40
|
+
// Re-check: another process may have refreshed right before we locked
|
|
41
|
+
const current = await storage.getTokenRecord(sid);
|
|
42
|
+
if (current && !needsRefresh(current.accessTokenExpiresAt, options.earlyRefreshSeconds ?? 30)) {
|
|
43
|
+
return current;
|
|
44
|
+
}
|
|
45
|
+
const refreshed = await refreshFn(current ?? record);
|
|
46
|
+
await storage.setTokenRecord(sid, refreshed);
|
|
47
|
+
return refreshed;
|
|
48
|
+
}
|
|
49
|
+
finally {
|
|
50
|
+
await releaseLock(storage, sid, lockId);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
// 2. Someone else holds the lock — wait and inspect
|
|
54
|
+
const started = Date.now();
|
|
55
|
+
while (Date.now() - started < maxWaitMs) {
|
|
56
|
+
await sleep(retryIntervalMs);
|
|
57
|
+
const lock = await storage.getLock(sid);
|
|
58
|
+
if (!lock) {
|
|
59
|
+
// Lock released, read winner's token record
|
|
60
|
+
const latest = await storage.getTokenRecord(sid);
|
|
61
|
+
if (!latest)
|
|
62
|
+
throw new RefreshTokenExpiredError('cleared_by_lock_holder');
|
|
63
|
+
if (!needsRefresh(latest.accessTokenExpiresAt, options.earlyRefreshSeconds ?? 30)) {
|
|
64
|
+
return latest;
|
|
65
|
+
}
|
|
66
|
+
// Still needs refresh, retry acquisition
|
|
67
|
+
return guardedRefresh(storage, sid, latest, refreshFn, options);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
throw new Error('token_refresh_timeout');
|
|
71
|
+
}
|
|
72
|
+
async function tryAcquireLock(storage, sid, lockId, ttlMs) {
|
|
73
|
+
const cur = await storage.getLock(sid);
|
|
74
|
+
if (cur && Date.now() - cur.acquiredAt < ttlMs) {
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
77
|
+
await storage.setLock(sid, { lockId, acquiredAt: Date.now() }, Math.ceil(ttlMs / 1000));
|
|
78
|
+
const check = await storage.getLock(sid);
|
|
79
|
+
return check?.lockId === lockId;
|
|
80
|
+
}
|
|
81
|
+
async function releaseLock(storage, sid, lockId) {
|
|
82
|
+
const cur = await storage.getLock(sid);
|
|
83
|
+
if (cur?.lockId === lockId) {
|
|
84
|
+
await storage.deleteLock(sid).catch(() => { });
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=refresh.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"refresh.js","sourceRoot":"","sources":["../src/refresh.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { Redis } from 'ioredis';
|
|
2
|
+
import type { HuiaStorageAdapter, TokenRecord, AuthStateRecord, LockRecord } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* In-memory storage adapter with TTL support.
|
|
5
|
+
* Thread-safe for single process Node / Next.js / dev servers.
|
|
6
|
+
*/
|
|
7
|
+
export declare class MemoryStorageAdapter implements HuiaStorageAdapter {
|
|
8
|
+
private tokens;
|
|
9
|
+
private states;
|
|
10
|
+
private locks;
|
|
11
|
+
private cleanExpired;
|
|
12
|
+
getTokenRecord(sid: string): Promise<TokenRecord | null>;
|
|
13
|
+
setTokenRecord(sid: string, record: TokenRecord, ttlSeconds?: number): Promise<void>;
|
|
14
|
+
deleteTokenRecord(sid: string): Promise<void>;
|
|
15
|
+
getStateRecord(state: string): Promise<AuthStateRecord | null>;
|
|
16
|
+
setStateRecord(state: string, record: AuthStateRecord, ttlSeconds?: number): Promise<void>;
|
|
17
|
+
deleteStateRecord(state: string): Promise<void>;
|
|
18
|
+
getLock(sid: string): Promise<LockRecord | null>;
|
|
19
|
+
setLock(sid: string, lock: LockRecord, ttlSeconds?: number): Promise<void>;
|
|
20
|
+
deleteLock(sid: string): Promise<void>;
|
|
21
|
+
}
|
|
22
|
+
/** Default singleton in-memory storage */
|
|
23
|
+
export declare const defaultStorage: MemoryStorageAdapter;
|
|
24
|
+
/**
|
|
25
|
+
* Redis-backed storage adapter. Required for the Next.js flavors (next-huia-oidc,
|
|
26
|
+
* next-huia-headless) as soon as more than one server process is in play — which in practice means
|
|
27
|
+
* almost immediately: Next.js's App Router compiles each Route Handler as an independent bundle, and
|
|
28
|
+
* module-level state like {@link MemoryStorageAdapter}'s Map is not reliably shared between them (a
|
|
29
|
+
* token record written by the login route can be invisible to a completely different route reading it
|
|
30
|
+
* back moments later). The Nuxt flavors don't need this — they use Nitro's own `useStorage()` instead,
|
|
31
|
+
* which has no such isolation.
|
|
32
|
+
*/
|
|
33
|
+
export declare class RedisStorageAdapter implements HuiaStorageAdapter {
|
|
34
|
+
private readonly redis;
|
|
35
|
+
private readonly keyPrefix;
|
|
36
|
+
constructor(redis: Redis, keyPrefix?: string);
|
|
37
|
+
private key;
|
|
38
|
+
private getJson;
|
|
39
|
+
private setJson;
|
|
40
|
+
getTokenRecord(sid: string): Promise<TokenRecord | null>;
|
|
41
|
+
setTokenRecord(sid: string, record: TokenRecord, ttlSeconds?: number): Promise<void>;
|
|
42
|
+
deleteTokenRecord(sid: string): Promise<void>;
|
|
43
|
+
getStateRecord(state: string): Promise<AuthStateRecord | null>;
|
|
44
|
+
setStateRecord(state: string, record: AuthStateRecord, ttlSeconds?: number): Promise<void>;
|
|
45
|
+
deleteStateRecord(state: string): Promise<void>;
|
|
46
|
+
getLock(sid: string): Promise<LockRecord | null>;
|
|
47
|
+
setLock(sid: string, lock: LockRecord, ttlSeconds?: number): Promise<void>;
|
|
48
|
+
deleteLock(sid: string): Promise<void>;
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=storage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../src/storage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AACpC,OAAO,KAAK,EACV,kBAAkB,EAClB,WAAW,EACX,eAAe,EACf,UAAU,EACX,MAAM,YAAY,CAAA;AAOnB;;;GAGG;AACH,qBAAa,oBAAqB,YAAW,kBAAkB;IAC7D,OAAO,CAAC,MAAM,CAA6C;IAC3D,OAAO,CAAC,MAAM,CAAiD;IAC/D,OAAO,CAAC,KAAK,CAA4C;IAEzD,OAAO,CAAC,YAAY;IAUd,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IAWxD,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKpF,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAK7C,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;IAW9D,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,EAAE,UAAU,SAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKvF,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAK/C,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAWhD,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,UAAU,SAAK,GAAG,OAAO,CAAC,IAAI,CAAC;IAKtE,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAG7C;AAED,0CAA0C;AAC1C,eAAO,MAAM,cAAc,sBAA6B,CAAA;AAExD;;;;;;;;GAQG;AACH,qBAAa,mBAAoB,YAAW,kBAAkB;IAC5D,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAO;IAC7B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAQ;gBAEtB,KAAK,EAAE,KAAK,EAAE,SAAS,SAAU;IAK7C,OAAO,CAAC,GAAG;YAIG,OAAO;YAKP,OAAO;IAWrB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IAIxD,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI9E,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKnD,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;IAI9D,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,EAAE,UAAU,SAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIjF,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKrD,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAIhD,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,UAAU,SAAK,GAAG,OAAO,CAAC,IAAI,CAAC;IAIhE,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAG7C"}
|
package/dist/storage.js
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* In-memory storage adapter with TTL support.
|
|
3
|
+
* Thread-safe for single process Node / Next.js / dev servers.
|
|
4
|
+
*/
|
|
5
|
+
export class MemoryStorageAdapter {
|
|
6
|
+
tokens = new Map();
|
|
7
|
+
states = new Map();
|
|
8
|
+
locks = new Map();
|
|
9
|
+
cleanExpired(map) {
|
|
10
|
+
const now = Date.now();
|
|
11
|
+
for (const [key, item] of map.entries()) {
|
|
12
|
+
if (item.expiresAt !== null && item.expiresAt <= now) {
|
|
13
|
+
map.delete(key);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
/* ── Tokens ── */
|
|
18
|
+
async getTokenRecord(sid) {
|
|
19
|
+
this.cleanExpired(this.tokens);
|
|
20
|
+
const item = this.tokens.get(sid);
|
|
21
|
+
if (!item)
|
|
22
|
+
return null;
|
|
23
|
+
if (item.expiresAt !== null && item.expiresAt <= Date.now()) {
|
|
24
|
+
this.tokens.delete(sid);
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
return item.value;
|
|
28
|
+
}
|
|
29
|
+
async setTokenRecord(sid, record, ttlSeconds) {
|
|
30
|
+
const expiresAt = ttlSeconds ? Date.now() + ttlSeconds * 1000 : null;
|
|
31
|
+
this.tokens.set(sid, { value: record, expiresAt });
|
|
32
|
+
}
|
|
33
|
+
async deleteTokenRecord(sid) {
|
|
34
|
+
this.tokens.delete(sid);
|
|
35
|
+
}
|
|
36
|
+
/* ── Auth State ── */
|
|
37
|
+
async getStateRecord(state) {
|
|
38
|
+
this.cleanExpired(this.states);
|
|
39
|
+
const item = this.states.get(state);
|
|
40
|
+
if (!item)
|
|
41
|
+
return null;
|
|
42
|
+
if (item.expiresAt !== null && item.expiresAt <= Date.now()) {
|
|
43
|
+
this.states.delete(state);
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
return item.value;
|
|
47
|
+
}
|
|
48
|
+
async setStateRecord(state, record, ttlSeconds = 600) {
|
|
49
|
+
const expiresAt = Date.now() + ttlSeconds * 1000;
|
|
50
|
+
this.states.set(state, { value: record, expiresAt });
|
|
51
|
+
}
|
|
52
|
+
async deleteStateRecord(state) {
|
|
53
|
+
this.states.delete(state);
|
|
54
|
+
}
|
|
55
|
+
/* ── Locks ── */
|
|
56
|
+
async getLock(sid) {
|
|
57
|
+
this.cleanExpired(this.locks);
|
|
58
|
+
const item = this.locks.get(sid);
|
|
59
|
+
if (!item)
|
|
60
|
+
return null;
|
|
61
|
+
if (item.expiresAt !== null && item.expiresAt <= Date.now()) {
|
|
62
|
+
this.locks.delete(sid);
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
return item.value;
|
|
66
|
+
}
|
|
67
|
+
async setLock(sid, lock, ttlSeconds = 15) {
|
|
68
|
+
const expiresAt = Date.now() + ttlSeconds * 1000;
|
|
69
|
+
this.locks.set(sid, { value: lock, expiresAt });
|
|
70
|
+
}
|
|
71
|
+
async deleteLock(sid) {
|
|
72
|
+
this.locks.delete(sid);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
/** Default singleton in-memory storage */
|
|
76
|
+
export const defaultStorage = new MemoryStorageAdapter();
|
|
77
|
+
/**
|
|
78
|
+
* Redis-backed storage adapter. Required for the Next.js flavors (next-huia-oidc,
|
|
79
|
+
* next-huia-headless) as soon as more than one server process is in play — which in practice means
|
|
80
|
+
* almost immediately: Next.js's App Router compiles each Route Handler as an independent bundle, and
|
|
81
|
+
* module-level state like {@link MemoryStorageAdapter}'s Map is not reliably shared between them (a
|
|
82
|
+
* token record written by the login route can be invisible to a completely different route reading it
|
|
83
|
+
* back moments later). The Nuxt flavors don't need this — they use Nitro's own `useStorage()` instead,
|
|
84
|
+
* which has no such isolation.
|
|
85
|
+
*/
|
|
86
|
+
export class RedisStorageAdapter {
|
|
87
|
+
redis;
|
|
88
|
+
keyPrefix;
|
|
89
|
+
constructor(redis, keyPrefix = 'huia:') {
|
|
90
|
+
this.redis = redis;
|
|
91
|
+
this.keyPrefix = keyPrefix;
|
|
92
|
+
}
|
|
93
|
+
key(kind, id) {
|
|
94
|
+
return `${this.keyPrefix}${kind}:${id}`;
|
|
95
|
+
}
|
|
96
|
+
async getJson(key) {
|
|
97
|
+
const raw = await this.redis.get(key);
|
|
98
|
+
return raw ? JSON.parse(raw) : null;
|
|
99
|
+
}
|
|
100
|
+
async setJson(key, value, ttlSeconds) {
|
|
101
|
+
const payload = JSON.stringify(value);
|
|
102
|
+
if (ttlSeconds) {
|
|
103
|
+
await this.redis.set(key, payload, 'EX', ttlSeconds);
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
await this.redis.set(key, payload);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
/* ── Tokens ── */
|
|
110
|
+
getTokenRecord(sid) {
|
|
111
|
+
return this.getJson(this.key('token', sid));
|
|
112
|
+
}
|
|
113
|
+
setTokenRecord(sid, record, ttlSeconds) {
|
|
114
|
+
return this.setJson(this.key('token', sid), record, ttlSeconds);
|
|
115
|
+
}
|
|
116
|
+
async deleteTokenRecord(sid) {
|
|
117
|
+
await this.redis.del(this.key('token', sid));
|
|
118
|
+
}
|
|
119
|
+
/* ── Auth State ── */
|
|
120
|
+
getStateRecord(state) {
|
|
121
|
+
return this.getJson(this.key('state', state));
|
|
122
|
+
}
|
|
123
|
+
setStateRecord(state, record, ttlSeconds = 600) {
|
|
124
|
+
return this.setJson(this.key('state', state), record, ttlSeconds);
|
|
125
|
+
}
|
|
126
|
+
async deleteStateRecord(state) {
|
|
127
|
+
await this.redis.del(this.key('state', state));
|
|
128
|
+
}
|
|
129
|
+
/* ── Locks ── */
|
|
130
|
+
getLock(sid) {
|
|
131
|
+
return this.getJson(this.key('lock', sid));
|
|
132
|
+
}
|
|
133
|
+
setLock(sid, lock, ttlSeconds = 15) {
|
|
134
|
+
return this.setJson(this.key('lock', sid), lock, ttlSeconds);
|
|
135
|
+
}
|
|
136
|
+
async deleteLock(sid) {
|
|
137
|
+
await this.redis.del(this.key('lock', sid));
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
//# sourceMappingURL=storage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage.js","sourceRoot":"","sources":["../src/storage.ts"],"names":[],"mappings":"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"}
|
package/dist/tokens.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { UserClaims } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Copy only the whitelisted keys out of the claims set. `sub` is always kept.
|
|
4
|
+
* Normalizes `role` (scalar or array) into `roles: string[]`.
|
|
5
|
+
*/
|
|
6
|
+
export declare function pickUserClaims(claims: Record<string, unknown>, whitelist?: string[]): UserClaims;
|
|
7
|
+
/** Throw unless the id_token issuer is exactly the resolved per-tenant issuer string. */
|
|
8
|
+
export declare function assertHuiaIssuer(iss: unknown, expected: string): void;
|
|
9
|
+
/** Check if token needs refresh given expiration time and buffer (default 30 seconds). */
|
|
10
|
+
export declare function needsRefresh(accessTokenExpiresAt: number, earlyRefreshSeconds?: number): boolean;
|
|
11
|
+
/** True when a JWT's `exp` is in the past (with a small negative skew tolerance). */
|
|
12
|
+
export declare function isJwtExpired(jwt: string, skewSeconds?: number): boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Accept only a same-origin relative path. Rejects absolute URLs, protocol-relative `//host`,
|
|
15
|
+
* backslash tricks, whitespace and control characters. Returns `/` on rejection.
|
|
16
|
+
*/
|
|
17
|
+
export declare function sanitizeReturnTo(value: string | undefined | null): string;
|
|
18
|
+
//# sourceMappingURL=tokens.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tokens.d.ts","sourceRoot":"","sources":["../src/tokens.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAE5C;;;GAGG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS,CAAC,EAAE,MAAM,EAAE,GAAG,UAAU,CAmBhG;AAED,yFAAyF;AACzF,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAIrE;AAED,0FAA0F;AAC1F,wBAAgB,YAAY,CAAC,oBAAoB,EAAE,MAAM,EAAE,mBAAmB,SAAK,GAAG,OAAO,CAE5F;AAED,qFAAqF;AACrF,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,WAAW,SAAK,GAAG,OAAO,CAcnE;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,GAAG,MAAM,CASzE"}
|
package/dist/tokens.js
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copy only the whitelisted keys out of the claims set. `sub` is always kept.
|
|
3
|
+
* Normalizes `role` (scalar or array) into `roles: string[]`.
|
|
4
|
+
*/
|
|
5
|
+
export function pickUserClaims(claims, whitelist) {
|
|
6
|
+
const out = { sub: String(claims.sub ?? '') };
|
|
7
|
+
const keys = whitelist && whitelist.length > 0 ? whitelist : Object.keys(claims);
|
|
8
|
+
for (const key of keys) {
|
|
9
|
+
if (key === 'sub')
|
|
10
|
+
continue;
|
|
11
|
+
if (key === 'roles' || key === 'role') {
|
|
12
|
+
const roleVal = claims.roles ?? claims.role;
|
|
13
|
+
if (roleVal !== undefined) {
|
|
14
|
+
out.roles = Array.isArray(roleVal) ? roleVal.map(String) : [String(roleVal)];
|
|
15
|
+
}
|
|
16
|
+
continue;
|
|
17
|
+
}
|
|
18
|
+
if (claims[key] !== undefined) {
|
|
19
|
+
out[key] = claims[key];
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return out;
|
|
23
|
+
}
|
|
24
|
+
/** Throw unless the id_token issuer is exactly the resolved per-tenant issuer string. */
|
|
25
|
+
export function assertHuiaIssuer(iss, expected) {
|
|
26
|
+
if (iss !== expected) {
|
|
27
|
+
throw new Error(`issuer_mismatch: id_token iss "${String(iss)}" !== "${expected}"`);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
/** Check if token needs refresh given expiration time and buffer (default 30 seconds). */
|
|
31
|
+
export function needsRefresh(accessTokenExpiresAt, earlyRefreshSeconds = 30) {
|
|
32
|
+
return accessTokenExpiresAt - Date.now() < earlyRefreshSeconds * 1000;
|
|
33
|
+
}
|
|
34
|
+
/** True when a JWT's `exp` is in the past (with a small negative skew tolerance). */
|
|
35
|
+
export function isJwtExpired(jwt, skewSeconds = 30) {
|
|
36
|
+
try {
|
|
37
|
+
const payload = jwt.split('.')[1];
|
|
38
|
+
if (!payload)
|
|
39
|
+
return true;
|
|
40
|
+
const base64 = payload.replace(/-/g, '+').replace(/_/g, '/');
|
|
41
|
+
const decoded = typeof atob === 'function'
|
|
42
|
+
? atob(base64)
|
|
43
|
+
: Buffer.from(base64, 'base64').toString('utf8');
|
|
44
|
+
const json = JSON.parse(decoded);
|
|
45
|
+
return typeof json.exp === 'number' && json.exp * 1000 < Date.now() - skewSeconds * 1000;
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
return true;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Accept only a same-origin relative path. Rejects absolute URLs, protocol-relative `//host`,
|
|
53
|
+
* backslash tricks, whitespace and control characters. Returns `/` on rejection.
|
|
54
|
+
*/
|
|
55
|
+
export function sanitizeReturnTo(value) {
|
|
56
|
+
if (typeof value !== 'string' || value.length === 0)
|
|
57
|
+
return '/';
|
|
58
|
+
if (value[0] !== '/')
|
|
59
|
+
return '/';
|
|
60
|
+
if (value[1] === '/' || value[1] === '\\')
|
|
61
|
+
return '/';
|
|
62
|
+
for (let i = 0; i < value.length; i++) {
|
|
63
|
+
const c = value.charCodeAt(i);
|
|
64
|
+
if (c <= 0x20 || c === 0x7f)
|
|
65
|
+
return '/';
|
|
66
|
+
}
|
|
67
|
+
return value;
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=tokens.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tokens.js","sourceRoot":"","sources":["../src/tokens.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared type definitions for Huia authentication libraries.
|
|
3
|
+
*/
|
|
4
|
+
export interface UserClaims {
|
|
5
|
+
sub?: string;
|
|
6
|
+
name?: string;
|
|
7
|
+
email?: string;
|
|
8
|
+
email_verified?: boolean;
|
|
9
|
+
preferred_username?: string;
|
|
10
|
+
given_name?: string;
|
|
11
|
+
family_name?: string;
|
|
12
|
+
phone_number?: string;
|
|
13
|
+
phone_number_verified?: boolean;
|
|
14
|
+
roles?: string[];
|
|
15
|
+
[key: string]: unknown;
|
|
16
|
+
}
|
|
17
|
+
export interface UserSession {
|
|
18
|
+
user?: UserClaims | null;
|
|
19
|
+
loggedIn?: boolean;
|
|
20
|
+
expiresAt?: number;
|
|
21
|
+
}
|
|
22
|
+
export interface TokenRecord {
|
|
23
|
+
sid: string;
|
|
24
|
+
accessToken: string;
|
|
25
|
+
refreshToken?: string;
|
|
26
|
+
idToken?: string;
|
|
27
|
+
claims: UserClaims;
|
|
28
|
+
scope?: string;
|
|
29
|
+
accessTokenExpiresAt: number;
|
|
30
|
+
refreshTokenExpiresAt?: number;
|
|
31
|
+
updatedAt: number;
|
|
32
|
+
}
|
|
33
|
+
export interface AuthStateRecord {
|
|
34
|
+
state: string;
|
|
35
|
+
codeVerifier: string;
|
|
36
|
+
nonce: string;
|
|
37
|
+
returnTo?: string;
|
|
38
|
+
createdAt: number;
|
|
39
|
+
}
|
|
40
|
+
export interface LockRecord {
|
|
41
|
+
lockId: string;
|
|
42
|
+
acquiredAt: number;
|
|
43
|
+
}
|
|
44
|
+
export interface CookiePayload {
|
|
45
|
+
sid: string;
|
|
46
|
+
user: UserClaims;
|
|
47
|
+
expiresAt: number;
|
|
48
|
+
}
|
|
49
|
+
export interface SessionOptions {
|
|
50
|
+
name?: string;
|
|
51
|
+
password: string;
|
|
52
|
+
maxAge?: number;
|
|
53
|
+
userClaims?: string[];
|
|
54
|
+
}
|
|
55
|
+
export interface CookieOptions {
|
|
56
|
+
chunkSize?: number;
|
|
57
|
+
maxChunks?: number;
|
|
58
|
+
secure?: boolean;
|
|
59
|
+
sameSite?: 'lax' | 'strict' | 'none';
|
|
60
|
+
path?: string;
|
|
61
|
+
}
|
|
62
|
+
export interface HuiaStorageAdapter {
|
|
63
|
+
getTokenRecord(sid: string): Promise<TokenRecord | null>;
|
|
64
|
+
setTokenRecord(sid: string, record: TokenRecord, ttlSeconds?: number): Promise<void>;
|
|
65
|
+
deleteTokenRecord(sid: string): Promise<void>;
|
|
66
|
+
getStateRecord?(state: string): Promise<AuthStateRecord | null>;
|
|
67
|
+
setStateRecord?(state: string, record: AuthStateRecord, ttlSeconds?: number): Promise<void>;
|
|
68
|
+
deleteStateRecord?(state: string): Promise<void>;
|
|
69
|
+
getLock(sid: string): Promise<LockRecord | null>;
|
|
70
|
+
setLock(sid: string, lock: LockRecord, ttlSeconds?: number): Promise<void>;
|
|
71
|
+
deleteLock(sid: string): Promise<void>;
|
|
72
|
+
}
|
|
73
|
+
export interface BackendTokenResponse {
|
|
74
|
+
tokenType: string;
|
|
75
|
+
accessToken: string;
|
|
76
|
+
expiresIn: number;
|
|
77
|
+
refreshToken: string;
|
|
78
|
+
}
|
|
79
|
+
export interface BackendMeResponse {
|
|
80
|
+
email: string;
|
|
81
|
+
isEmailConfirmed: boolean;
|
|
82
|
+
roles?: string[];
|
|
83
|
+
firstName?: string;
|
|
84
|
+
lastName?: string;
|
|
85
|
+
phoneNumber?: string;
|
|
86
|
+
isPhoneNumberConfirmed?: boolean;
|
|
87
|
+
[key: string]: unknown;
|
|
88
|
+
}
|
|
89
|
+
export interface BackendPhoneStartResponse {
|
|
90
|
+
flowId: string;
|
|
91
|
+
expiresInSeconds: number;
|
|
92
|
+
status?: string;
|
|
93
|
+
}
|
|
94
|
+
export interface BackendPhoneVerifyResponse {
|
|
95
|
+
accessToken?: string;
|
|
96
|
+
refreshToken?: string;
|
|
97
|
+
expiresIn?: number;
|
|
98
|
+
requiresProfile?: boolean;
|
|
99
|
+
flowId?: string;
|
|
100
|
+
firstName?: string | null;
|
|
101
|
+
lastName?: string | null;
|
|
102
|
+
}
|
|
103
|
+
export interface BackendExternalExchangeResponse {
|
|
104
|
+
accessToken?: string;
|
|
105
|
+
refreshToken?: string;
|
|
106
|
+
expiresIn?: number;
|
|
107
|
+
requiresProfile?: boolean;
|
|
108
|
+
code?: string;
|
|
109
|
+
email?: string | null;
|
|
110
|
+
firstName?: string | null;
|
|
111
|
+
lastName?: string | null;
|
|
112
|
+
}
|
|
113
|
+
export interface HeadlessAdminUser {
|
|
114
|
+
id: string;
|
|
115
|
+
userName?: string | null;
|
|
116
|
+
email?: string | null;
|
|
117
|
+
emailConfirmed: boolean;
|
|
118
|
+
phoneNumber?: string | null;
|
|
119
|
+
phoneNumberConfirmed: boolean;
|
|
120
|
+
firstName: string;
|
|
121
|
+
lastName: string;
|
|
122
|
+
lockoutEnabled: boolean;
|
|
123
|
+
lockoutEnd?: string | null;
|
|
124
|
+
roles: string[];
|
|
125
|
+
}
|
|
126
|
+
export interface HeadlessAdminRole {
|
|
127
|
+
id: string;
|
|
128
|
+
name: string;
|
|
129
|
+
origin: string;
|
|
130
|
+
}
|
|
131
|
+
export interface HeadlessAdminUsersPage {
|
|
132
|
+
data: HeadlessAdminUser[];
|
|
133
|
+
totalCount: number;
|
|
134
|
+
page: number;
|
|
135
|
+
pageSize: number;
|
|
136
|
+
hasNext: boolean;
|
|
137
|
+
hasPrevious: boolean;
|
|
138
|
+
}
|
|
139
|
+
export interface CreateHeadlessAdminUserRequest {
|
|
140
|
+
email?: string;
|
|
141
|
+
password?: string;
|
|
142
|
+
phoneNumber?: string;
|
|
143
|
+
firstName?: string;
|
|
144
|
+
lastName?: string;
|
|
145
|
+
emailConfirmed?: boolean;
|
|
146
|
+
roles?: string[];
|
|
147
|
+
}
|
|
148
|
+
export interface UpdateHeadlessAdminUserRequest {
|
|
149
|
+
firstName?: string;
|
|
150
|
+
lastName?: string;
|
|
151
|
+
email?: string;
|
|
152
|
+
phoneNumber?: string;
|
|
153
|
+
}
|
|
154
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG"}
|
package/package.json
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "huia-auth-core",
|
|
3
|
+
"version": "1.0.0-alpha.5",
|
|
4
|
+
"description": "Shared authentication primitives for Huia client modules (Next.js & Nuxt 4)",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/Ayman-Elfaki/Huia.git",
|
|
10
|
+
"directory": "src/javascript/shared/huia-auth-core"
|
|
11
|
+
},
|
|
12
|
+
"exports": {
|
|
13
|
+
".": {
|
|
14
|
+
"types": "./dist/index.d.ts",
|
|
15
|
+
"import": "./dist/index.js"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"main": "./dist/index.js",
|
|
19
|
+
"types": "./dist/index.d.ts",
|
|
20
|
+
"files": [
|
|
21
|
+
"dist"
|
|
22
|
+
],
|
|
23
|
+
"scripts": {
|
|
24
|
+
"build": "tsc",
|
|
25
|
+
"dev": "tsc --watch",
|
|
26
|
+
"test": "vitest run",
|
|
27
|
+
"test:watch": "vitest watch"
|
|
28
|
+
},
|
|
29
|
+
"dependencies": {
|
|
30
|
+
"ioredis": "^5.4.1",
|
|
31
|
+
"iron-webcrypto": "^1.2.1",
|
|
32
|
+
"openid-client": "^6.1.0",
|
|
33
|
+
"uncrypto": "^0.1.3"
|
|
34
|
+
},
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"@types/node": "^22.10.0",
|
|
37
|
+
"typescript": "~5.9.3",
|
|
38
|
+
"vitest": "^4.0.2"
|
|
39
|
+
},
|
|
40
|
+
"engines": {
|
|
41
|
+
"node": ">=20.11.0"
|
|
42
|
+
}
|
|
43
|
+
}
|