@spine-event-engine/auth 2.0.0-snapshot.26 → 2.0.0-snapshot.29
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 +102 -11
- package/REFERENCE.md +125 -3
- package/dist/index.d.ts +15 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/oidc/contracts.d.ts +18 -4
- package/dist/oidc/contracts.d.ts.map +1 -1
- package/dist/oidc/flow-store.d.ts +143 -0
- package/dist/oidc/flow-store.d.ts.map +1 -0
- package/dist/oidc/flow-store.js +184 -0
- package/dist/oidc/flow-store.js.map +1 -0
- package/dist/oidc/index.d.ts +29 -9
- package/dist/oidc/index.d.ts.map +1 -1
- package/dist/oidc/index.js +611 -152
- package/dist/oidc/index.js.map +1 -1
- package/dist/oidc/persistent-flow-store.d.ts +117 -0
- package/dist/oidc/persistent-flow-store.d.ts.map +1 -0
- package/dist/oidc/persistent-flow-store.js +413 -0
- package/dist/oidc/persistent-flow-store.js.map +1 -0
- package/dist/oidc/records.d.ts +15 -0
- package/dist/oidc/records.d.ts.map +1 -0
- package/dist/oidc/records.js +91 -0
- package/dist/oidc/records.js.map +1 -0
- package/dist/providers/index.d.ts +10 -5
- package/dist/providers/index.d.ts.map +1 -1
- package/dist/providers/index.js +103 -30
- package/dist/providers/index.js.map +1 -1
- package/dist/sessions/cookies.d.ts +46 -8
- package/dist/sessions/cookies.d.ts.map +1 -1
- package/dist/sessions/cookies.js +269 -47
- package/dist/sessions/cookies.js.map +1 -1
- package/dist/sessions/opaque-session-store.d.ts +143 -0
- package/dist/sessions/opaque-session-store.d.ts.map +1 -0
- package/dist/sessions/opaque-session-store.js +185 -0
- package/dist/sessions/opaque-session-store.js.map +1 -0
- package/dist/sessions/opaque.d.ts +93 -106
- package/dist/sessions/opaque.d.ts.map +1 -1
- package/dist/sessions/opaque.js +501 -232
- package/dist/sessions/opaque.js.map +1 -1
- package/dist/sessions/persistent-opaque-session-store.d.ts +105 -0
- package/dist/sessions/persistent-opaque-session-store.d.ts.map +1 -0
- package/dist/sessions/persistent-opaque-session-store.js +333 -0
- package/dist/sessions/persistent-opaque-session-store.js.map +1 -0
- package/dist/sessions/persistent-token-revocations.d.ts +90 -0
- package/dist/sessions/persistent-token-revocations.d.ts.map +1 -0
- package/dist/sessions/persistent-token-revocations.js +422 -0
- package/dist/sessions/persistent-token-revocations.js.map +1 -0
- package/dist/sessions/session-lifetime.d.ts +67 -0
- package/dist/sessions/session-lifetime.d.ts.map +1 -0
- package/dist/sessions/session-lifetime.js +165 -0
- package/dist/sessions/session-lifetime.js.map +1 -0
- package/dist/sessions/session-record.d.ts +15 -0
- package/dist/sessions/session-record.d.ts.map +1 -0
- package/dist/sessions/session-record.js +109 -0
- package/dist/sessions/session-record.js.map +1 -0
- package/dist/sessions/signed.d.ts +5 -4
- package/dist/sessions/signed.d.ts.map +1 -1
- package/dist/sessions/signed.js +212 -74
- package/dist/sessions/signed.js.map +1 -1
- package/dist/subscriptions/index.d.ts.map +1 -1
- package/dist/subscriptions/index.js +260 -26
- package/dist/subscriptions/index.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +20 -6
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2026, CodeMatters. All rights reserved.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
|
5
|
+
* in compliance with the License. You may obtain a copy of the License at
|
|
6
|
+
*
|
|
7
|
+
* https://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
*
|
|
9
|
+
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
|
10
|
+
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
|
11
|
+
* or implied. See the License for the specific language governing permissions and limitations under
|
|
12
|
+
* the License.
|
|
13
|
+
*/
|
|
14
|
+
import { clone, equals } from "@bufbuild/protobuf";
|
|
15
|
+
import {} from "@bufbuild/protobuf/wkt";
|
|
16
|
+
import { Time } from "@spine-event-engine/core/time";
|
|
17
|
+
import { OpaqueSessionRecordSchema, } from "@spine-event-engine/proto/auth";
|
|
18
|
+
import { SessionRecords } from "./session-record.js";
|
|
19
|
+
/**
|
|
20
|
+
* Process-local implementation of the same atomic session transitions.
|
|
21
|
+
*/
|
|
22
|
+
export class MemoryOpaqueSessionStore {
|
|
23
|
+
#records = new Map();
|
|
24
|
+
#clock;
|
|
25
|
+
#maxSessions;
|
|
26
|
+
#closed = false;
|
|
27
|
+
/**
|
|
28
|
+
* Creates a process-local store with a trusted maintenance clock.
|
|
29
|
+
*
|
|
30
|
+
* @param clock Supplies the latest allowed purge cutoff.
|
|
31
|
+
* @param maxSessions Process-local retained record bound; defaults to 10,000.
|
|
32
|
+
*/
|
|
33
|
+
constructor(clock = Time.currentTime, maxSessions = 10_000) {
|
|
34
|
+
if (!Number.isSafeInteger(maxSessions) || maxSessions <= 0)
|
|
35
|
+
throw new RangeError("maxSessions must be a positive safe integer.");
|
|
36
|
+
this.#clock = clock;
|
|
37
|
+
this.#maxSessions = maxSessions;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Returns whether the process-local retained record bound is reached.
|
|
41
|
+
*
|
|
42
|
+
* @returns Whether another insert requires explicit expiry maintenance.
|
|
43
|
+
*/
|
|
44
|
+
atCapacity() {
|
|
45
|
+
return this.#records.size >= this.#maxSessions;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Creates a complete session only when its stable reference is absent.
|
|
49
|
+
*
|
|
50
|
+
* @param record Complete session to insert.
|
|
51
|
+
* @param signal Optional cancellation.
|
|
52
|
+
* @returns Whether insertion won.
|
|
53
|
+
*/
|
|
54
|
+
insert(record, signal) {
|
|
55
|
+
return this.#run(() => {
|
|
56
|
+
this.#check(signal);
|
|
57
|
+
if (this.#records.has(record.id))
|
|
58
|
+
return false;
|
|
59
|
+
if (this.atCapacity())
|
|
60
|
+
return false;
|
|
61
|
+
SessionRecords.expiry(record);
|
|
62
|
+
this.#records.set(record.id, clone(OpaqueSessionRecordSchema, record));
|
|
63
|
+
return true;
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Reads one authoritative session by stable reference.
|
|
68
|
+
*
|
|
69
|
+
* @param id Stable session reference.
|
|
70
|
+
* @param signal Optional cancellation.
|
|
71
|
+
* @returns Detached current record, if present.
|
|
72
|
+
*/
|
|
73
|
+
read(id, signal) {
|
|
74
|
+
return this.#run(() => {
|
|
75
|
+
this.#check(signal);
|
|
76
|
+
const record = this.#records.get(id);
|
|
77
|
+
return record === undefined ? undefined : clone(OpaqueSessionRecordSchema, record);
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Replaces exactly one expected session record.
|
|
82
|
+
*
|
|
83
|
+
* @param expected Complete record that must still be current.
|
|
84
|
+
* @param next Replacement with the same stable reference.
|
|
85
|
+
* @param signal Optional cancellation.
|
|
86
|
+
* @returns Whether replacement won.
|
|
87
|
+
*/
|
|
88
|
+
replace(expected, next, signal) {
|
|
89
|
+
return this.#run(() => {
|
|
90
|
+
this.#check(signal);
|
|
91
|
+
if (expected.id !== next.id)
|
|
92
|
+
throw new Error("Replacement must retain the stable reference.");
|
|
93
|
+
SessionRecords.expiry(next);
|
|
94
|
+
const current = this.#records.get(expected.id);
|
|
95
|
+
if (current === undefined || !equals(OpaqueSessionRecordSchema, current, expected))
|
|
96
|
+
return false;
|
|
97
|
+
this.#records.set(next.id, clone(OpaqueSessionRecordSchema, next));
|
|
98
|
+
return true;
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Deletes the current generation behind a stable reference.
|
|
103
|
+
*
|
|
104
|
+
* @param id Stable session reference.
|
|
105
|
+
* @param signal Optional cancellation.
|
|
106
|
+
* @returns Whether a record was removed.
|
|
107
|
+
*/
|
|
108
|
+
revoke(id, signal) {
|
|
109
|
+
return this.#run(() => {
|
|
110
|
+
this.#check(signal);
|
|
111
|
+
return this.#records.delete(id);
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Deletes only one complete expected record.
|
|
116
|
+
*
|
|
117
|
+
* @param expected Complete record that may be removed.
|
|
118
|
+
* @param signal Optional cancellation.
|
|
119
|
+
* @returns Whether the expected record was removed.
|
|
120
|
+
*/
|
|
121
|
+
remove(expected, signal) {
|
|
122
|
+
return this.#run(() => {
|
|
123
|
+
this.#check(signal);
|
|
124
|
+
const current = this.#records.get(expected.id);
|
|
125
|
+
if (current === undefined || !equals(OpaqueSessionRecordSchema, current, expected))
|
|
126
|
+
return false;
|
|
127
|
+
return this.#records.delete(expected.id);
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Removes exact deadlines at or before the trusted cutoff.
|
|
132
|
+
*
|
|
133
|
+
* @param cutoff Current-or-earlier exact deadline.
|
|
134
|
+
* @param signal Optional maintenance cancellation.
|
|
135
|
+
* @returns Number of conditionally removed records.
|
|
136
|
+
*/
|
|
137
|
+
purgeExpired(cutoff, signal) {
|
|
138
|
+
return this.#run(() => {
|
|
139
|
+
this.#check(signal);
|
|
140
|
+
const valid = SessionRecords.deadline(cutoff);
|
|
141
|
+
if (SessionRecords.compare(valid, SessionRecords.deadline(this.#clock())) > 0)
|
|
142
|
+
throw new RangeError("Purge cutoff cannot be later than the trusted clock.");
|
|
143
|
+
let removed = 0;
|
|
144
|
+
for (const record of this.#records.values()) {
|
|
145
|
+
this.#check(signal);
|
|
146
|
+
if (SessionRecords.compare(SessionRecords.expiry(record), valid) <= 0) {
|
|
147
|
+
this.#records.delete(record.id);
|
|
148
|
+
removed += 1;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
return removed;
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Closes and drops the process-local record references.
|
|
156
|
+
*
|
|
157
|
+
* @returns Completion after local records are dropped.
|
|
158
|
+
*/
|
|
159
|
+
close() {
|
|
160
|
+
this.#closed = true;
|
|
161
|
+
this.#records.clear();
|
|
162
|
+
return Promise.resolve();
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Converts one synchronous memory transition to the asynchronous port.
|
|
166
|
+
*
|
|
167
|
+
* @typeParam T Result produced by the atomic transition.
|
|
168
|
+
* @param action Atomic memory transition.
|
|
169
|
+
* @returns Transition result or rejected failure.
|
|
170
|
+
*/
|
|
171
|
+
#run(action) {
|
|
172
|
+
return Promise.resolve().then(action);
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Rejects new work after close or cancellation.
|
|
176
|
+
*
|
|
177
|
+
* @param signal Optional operation cancellation.
|
|
178
|
+
*/
|
|
179
|
+
#check(signal) {
|
|
180
|
+
if (this.#closed)
|
|
181
|
+
throw new Error("Opaque session store is closed.");
|
|
182
|
+
signal?.throwIfAborted();
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
//# sourceMappingURL=opaque-session-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"opaque-session-store.js","sourceRoot":"","sources":["../../src/sessions/opaque-session-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,200 +1,187 @@
|
|
|
1
|
+
import { type Timestamp } from "@bufbuild/protobuf/wkt";
|
|
2
|
+
import { type OpaqueSessionStore } from "./opaque-session-store.js";
|
|
1
3
|
import type { AuthenticatedPrincipal, CookieCredential, RequestCredential, ResolvedSession, SessionResolver } from "../index.js";
|
|
2
4
|
/**
|
|
3
|
-
*
|
|
5
|
+
* Trusted millisecond clock for exact application-session validity.
|
|
4
6
|
*/
|
|
5
7
|
export interface OpaqueSessionClock {
|
|
6
8
|
/**
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
+
* Reads a safe Unix epoch millisecond in the Protobuf Timestamp range.
|
|
10
|
+
*
|
|
11
|
+
* @returns Current milliseconds.
|
|
9
12
|
*/
|
|
10
13
|
now(): number;
|
|
11
14
|
}
|
|
12
15
|
/**
|
|
13
|
-
* Creates
|
|
14
|
-
*
|
|
15
|
-
* @
|
|
16
|
+
* Creates cryptographic bytes for a stable ID or credential generation.
|
|
17
|
+
*
|
|
18
|
+
* @param length Required byte count.
|
|
19
|
+
* @returns Random bytes that the caller clears after use.
|
|
16
20
|
*/
|
|
17
21
|
export type OpaqueSessionRandom = (length: number) => Uint8Array;
|
|
18
22
|
/**
|
|
19
|
-
*
|
|
23
|
+
* Required sealing and lifetime policy with optional replaceable storage.
|
|
20
24
|
*/
|
|
21
25
|
export interface OpaqueSessionsOptions {
|
|
22
26
|
/**
|
|
23
|
-
*
|
|
27
|
+
* Store selected for authoritative session transitions; omission selects memory.
|
|
24
28
|
*/
|
|
25
|
-
readonly
|
|
29
|
+
readonly store?: OpaqueSessionStore;
|
|
26
30
|
/**
|
|
27
|
-
*
|
|
28
|
-
* Throwing or wrong-length results consume a bounded collision attempt, and
|
|
29
|
-
* every returned mutable buffer is zeroed before this resolver returns.
|
|
31
|
+
* Application and purpose binding authenticated into every seal.
|
|
30
32
|
*/
|
|
31
|
-
readonly
|
|
33
|
+
readonly scope: string;
|
|
32
34
|
/**
|
|
33
|
-
*
|
|
35
|
+
* Iron-session secret or numeric version-to-secret rotation map.
|
|
34
36
|
*/
|
|
35
|
-
readonly
|
|
37
|
+
readonly password: string | Readonly<Record<string, string>>;
|
|
36
38
|
/**
|
|
37
|
-
*
|
|
39
|
+
* Trusted application clock for exact expiry checks.
|
|
38
40
|
*/
|
|
39
|
-
readonly
|
|
41
|
+
readonly clock: OpaqueSessionClock;
|
|
40
42
|
/**
|
|
41
|
-
* Positive safe
|
|
43
|
+
* Positive safe lifetime in milliseconds.
|
|
44
|
+
*/
|
|
45
|
+
readonly ttlMilliseconds: number;
|
|
46
|
+
/**
|
|
47
|
+
* Optional injected random source for session ID and generation.
|
|
48
|
+
*/
|
|
49
|
+
readonly randomBytes?: OpaqueSessionRandom;
|
|
50
|
+
/**
|
|
51
|
+
* Existing bounded retry policy for random-ID collisions; defaults to three.
|
|
42
52
|
*/
|
|
43
53
|
readonly collisionAttempts?: number;
|
|
54
|
+
/**
|
|
55
|
+
* Memory-only retained-session bound; defaults to 10,000.
|
|
56
|
+
*/
|
|
57
|
+
readonly maxSessions?: number;
|
|
44
58
|
}
|
|
45
59
|
/**
|
|
46
|
-
*
|
|
60
|
+
* Issuance outcome, including a sealed cookie on success.
|
|
47
61
|
*/
|
|
48
62
|
export type OpaqueSessionCreateResult = {
|
|
49
63
|
/**
|
|
50
|
-
*
|
|
64
|
+
* Successful issuance through the selected store.
|
|
51
65
|
*/
|
|
52
66
|
readonly kind: "created";
|
|
53
67
|
/**
|
|
54
|
-
*
|
|
68
|
+
* Sealed cookie credential.
|
|
55
69
|
*/
|
|
56
70
|
readonly credential: CookieCredential;
|
|
57
71
|
/**
|
|
58
|
-
*
|
|
72
|
+
* Detached resolved session.
|
|
59
73
|
*/
|
|
60
74
|
readonly session: ResolvedSession;
|
|
61
75
|
} | {
|
|
62
76
|
/**
|
|
63
|
-
*
|
|
77
|
+
* Rejected issuance.
|
|
64
78
|
*/
|
|
65
79
|
readonly kind: "rejected";
|
|
66
80
|
/**
|
|
67
|
-
*
|
|
81
|
+
* Application-level rejection reason.
|
|
68
82
|
*/
|
|
69
83
|
readonly reason: "capacity-exceeded" | "entropy-exhausted" | "clock-failure" | "closed";
|
|
70
84
|
};
|
|
71
85
|
/**
|
|
72
|
-
*
|
|
86
|
+
* Rotation outcome, including a newly sealed cookie on success.
|
|
73
87
|
*/
|
|
74
88
|
export type OpaqueSessionRotateResult = {
|
|
75
89
|
/**
|
|
76
|
-
*
|
|
90
|
+
* Successful atomic generation replacement.
|
|
77
91
|
*/
|
|
78
92
|
readonly kind: "rotated";
|
|
79
93
|
/**
|
|
80
|
-
*
|
|
94
|
+
* Replacement sealed cookie credential.
|
|
81
95
|
*/
|
|
82
96
|
readonly credential: CookieCredential;
|
|
83
97
|
/**
|
|
84
|
-
*
|
|
98
|
+
* Detached replacement session.
|
|
85
99
|
*/
|
|
86
100
|
readonly session: ResolvedSession;
|
|
87
101
|
} | {
|
|
88
102
|
/**
|
|
89
|
-
*
|
|
103
|
+
* Rejected rotation.
|
|
90
104
|
*/
|
|
91
105
|
readonly kind: "rejected";
|
|
92
106
|
/**
|
|
93
|
-
*
|
|
107
|
+
* Application-level rejection reason.
|
|
94
108
|
*/
|
|
95
109
|
readonly reason: "not-found" | "expired" | "unsupported-credential" | "entropy-exhausted" | "clock-failure" | "closed";
|
|
96
110
|
};
|
|
97
111
|
/**
|
|
98
|
-
* Enumeration-safe
|
|
112
|
+
* Enumeration-safe logout acknowledgement.
|
|
99
113
|
*/
|
|
100
114
|
export interface OpaqueSessionLogoutResult {
|
|
101
115
|
/**
|
|
102
|
-
*
|
|
116
|
+
* Acknowledges logout without revealing session presence.
|
|
103
117
|
*/
|
|
104
118
|
readonly kind: "logged-out";
|
|
105
119
|
}
|
|
106
120
|
/**
|
|
107
|
-
*
|
|
108
|
-
*
|
|
109
|
-
* It is intentionally process-local: applications needing durable or shared
|
|
110
|
-
* sessions provide another `SessionResolver` implementation.
|
|
121
|
+
* Sealed opaque credentials backed by atomic stable-reference transitions.
|
|
111
122
|
*/
|
|
112
123
|
export declare class OpaqueSessions implements SessionResolver {
|
|
113
|
-
private
|
|
114
|
-
private readonly clock;
|
|
115
|
-
private readonly random;
|
|
116
|
-
private readonly ttlMilliseconds;
|
|
117
|
-
private readonly maxSessions;
|
|
118
|
-
private readonly collisionAttempts;
|
|
119
|
-
private closed;
|
|
120
|
-
/**
|
|
121
|
-
* Creates a bounded in-memory session store.
|
|
122
|
-
* @param options The optional clock, entropy, lifetime, and capacity settings.
|
|
123
|
-
*/
|
|
124
|
-
constructor(options?: OpaqueSessionsOptions);
|
|
125
|
-
/**
|
|
126
|
-
* Creates a new session unless the terminal or bounded store state rejects it.
|
|
127
|
-
* @param principal The authenticated principal to retain.
|
|
128
|
-
* @returns The creation outcome and, when accepted, credential and session.
|
|
129
|
-
*/
|
|
130
|
-
create(principal: AuthenticatedPrincipal): Promise<OpaqueSessionCreateResult>;
|
|
124
|
+
#private;
|
|
131
125
|
/**
|
|
132
|
-
*
|
|
133
|
-
*
|
|
134
|
-
* @
|
|
126
|
+
* Binds already validated policy and an authoritative store.
|
|
127
|
+
*
|
|
128
|
+
* @param options Validated session policy.
|
|
129
|
+
* @param store Selected atomic store.
|
|
130
|
+
* @param internalStore Process-local store created by this strategy, if any.
|
|
135
131
|
*/
|
|
136
|
-
|
|
132
|
+
private constructor();
|
|
137
133
|
/**
|
|
138
|
-
*
|
|
139
|
-
*
|
|
140
|
-
* @
|
|
134
|
+
* Validates sealing and lifetime policy before exposing a usable strategy.
|
|
135
|
+
*
|
|
136
|
+
* @param options Required application policy and optional store.
|
|
137
|
+
* @returns Initialized opaque-session strategy.
|
|
141
138
|
*/
|
|
142
|
-
|
|
139
|
+
static create(options: OpaqueSessionsOptions): Promise<OpaqueSessions>;
|
|
143
140
|
/**
|
|
144
|
-
*
|
|
145
|
-
*
|
|
146
|
-
* @
|
|
141
|
+
* Creates one sealed credential after an atomic absent insertion.
|
|
142
|
+
*
|
|
143
|
+
* @param principal Complete authenticated identity.
|
|
144
|
+
* @param signal Optional cancellation.
|
|
145
|
+
* @returns Issuance result; cancellation never returns a credential.
|
|
147
146
|
*/
|
|
148
|
-
|
|
147
|
+
issue(principal: AuthenticatedPrincipal, signal?: AbortSignal): Promise<OpaqueSessionCreateResult>;
|
|
149
148
|
/**
|
|
150
|
-
*
|
|
151
|
-
*
|
|
149
|
+
* Resolves only the current generation before its exact deadline.
|
|
150
|
+
*
|
|
151
|
+
* @param credentialInput Cookie credential to validate.
|
|
152
|
+
* @param signal Optional cancellation.
|
|
153
|
+
* @returns Detached session, or undefined for invalid or expired credentials.
|
|
152
154
|
*/
|
|
153
|
-
|
|
155
|
+
resolve(credentialInput: RequestCredential, signal?: AbortSignal): Promise<ResolvedSession | undefined>;
|
|
154
156
|
/**
|
|
155
|
-
*
|
|
156
|
-
*
|
|
157
|
+
* Creates a new generation before atomically replacing the current record.
|
|
158
|
+
*
|
|
159
|
+
* @param credentialInput Current cookie credential.
|
|
160
|
+
* @param signal Optional cancellation.
|
|
161
|
+
* @returns One winning replacement or a rejection.
|
|
157
162
|
*/
|
|
158
|
-
|
|
163
|
+
rotate(credentialInput: RequestCredential, signal?: AbortSignal): Promise<OpaqueSessionRotateResult>;
|
|
159
164
|
/**
|
|
160
|
-
*
|
|
161
|
-
*
|
|
162
|
-
* @param
|
|
163
|
-
* @
|
|
165
|
+
* Removes the stable reference when the supplied seal is still live.
|
|
166
|
+
*
|
|
167
|
+
* @param credentialInput Cookie credential to revoke.
|
|
168
|
+
* @param signal Optional cancellation.
|
|
169
|
+
* @returns Enumeration-safe acknowledgement.
|
|
164
170
|
*/
|
|
165
|
-
|
|
171
|
+
logout(credentialInput: RequestCredential, signal?: AbortSignal): Promise<OpaqueSessionLogoutResult>;
|
|
166
172
|
/**
|
|
167
|
-
*
|
|
168
|
-
*
|
|
173
|
+
* Removes records at or before a trusted maintenance cutoff.
|
|
174
|
+
*
|
|
175
|
+
* @param cutoff Current-or-earlier exact deadline.
|
|
176
|
+
* @param signal Optional maintenance cancellation.
|
|
177
|
+
* @returns Number of conditionally removed records.
|
|
169
178
|
*/
|
|
170
|
-
|
|
179
|
+
purgeExpired(cutoff: Timestamp, signal?: AbortSignal): Promise<number>;
|
|
171
180
|
/**
|
|
172
|
-
*
|
|
173
|
-
*
|
|
174
|
-
* @
|
|
175
|
-
* @returns The live record, or undefined if absent or expired.
|
|
181
|
+
* Closes new work and drains admitted work and compensation.
|
|
182
|
+
*
|
|
183
|
+
* @returns Repeatable close completion; injected stores remain open.
|
|
176
184
|
*/
|
|
177
|
-
|
|
178
|
-
/**
|
|
179
|
-
* Removes every session that has expired by the supplied time.
|
|
180
|
-
* @param now The validated sweep time in milliseconds.
|
|
181
|
-
*/
|
|
182
|
-
private sweepExpired;
|
|
183
|
-
/**
|
|
184
|
-
* Compares a session expiry with the current millisecond reading.
|
|
185
|
-
* @param record The session record to inspect.
|
|
186
|
-
* @param now The validated current time.
|
|
187
|
-
* @returns Whether the record has expired.
|
|
188
|
-
*/
|
|
189
|
-
private expired;
|
|
190
|
-
/**
|
|
191
|
-
* Reads a safe clock value and closes the store on clock failure.
|
|
192
|
-
* @returns Current epoch milliseconds, or undefined after failure.
|
|
193
|
-
*/
|
|
194
|
-
private now;
|
|
195
|
-
/**
|
|
196
|
-
* Closes the store and clears session records after a clock fault.
|
|
197
|
-
*/
|
|
198
|
-
private failClosed;
|
|
185
|
+
close(): Promise<void>;
|
|
199
186
|
}
|
|
200
187
|
//# sourceMappingURL=opaque.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"opaque.d.ts","sourceRoot":"","sources":["../../src/sessions/opaque.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"opaque.d.ts","sourceRoot":"","sources":["../../src/sessions/opaque.ts"],"names":[],"mappings":"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"}
|