@idp.global/sdk 18.0.0 → 18.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/changelog.md +28 -0
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts_relyingparty/classes.actorscope.d.ts +23 -0
- package/dist_ts_relyingparty/classes.actorscope.js +22 -0
- package/dist_ts_relyingparty/classes.authorityobserver.d.ts +81 -0
- package/dist_ts_relyingparty/classes.authorityobserver.js +185 -0
- package/dist_ts_relyingparty/classes.errors.d.ts +33 -0
- package/dist_ts_relyingparty/classes.errors.js +53 -0
- package/dist_ts_relyingparty/classes.idpoidcprovider.d.ts +142 -0
- package/dist_ts_relyingparty/classes.idpoidcprovider.js +255 -0
- package/dist_ts_relyingparty/classes.relyingpartyroutes.d.ts +84 -0
- package/dist_ts_relyingparty/classes.relyingpartyroutes.js +232 -0
- package/dist_ts_relyingparty/classes.relyingpartysessions.d.ts +210 -0
- package/dist_ts_relyingparty/classes.relyingpartysessions.js +786 -0
- package/dist_ts_relyingparty/classes.rpmodels.d.ts +79 -0
- package/dist_ts_relyingparty/classes.rpmodels.js +283 -0
- package/dist_ts_relyingparty/classes.secretbox.d.ts +14 -0
- package/dist_ts_relyingparty/classes.secretbox.js +45 -0
- package/dist_ts_relyingparty/classes.socketbinding.d.ts +75 -0
- package/dist_ts_relyingparty/classes.socketbinding.js +94 -0
- package/dist_ts_relyingparty/helpers.cookies.d.ts +11 -0
- package/dist_ts_relyingparty/helpers.cookies.js +62 -0
- package/dist_ts_relyingparty/helpers.crypto.d.ts +12 -0
- package/dist_ts_relyingparty/helpers.crypto.js +40 -0
- package/dist_ts_relyingparty/helpers.returnpath.d.ts +9 -0
- package/dist_ts_relyingparty/helpers.returnpath.js +39 -0
- package/dist_ts_relyingparty/index.d.ts +13 -0
- package/dist_ts_relyingparty/index.js +14 -0
- package/dist_ts_relyingparty/interfaces.d.ts +113 -0
- package/dist_ts_relyingparty/interfaces.js +2 -0
- package/dist_ts_relyingparty/plugins.d.ts +10 -0
- package/dist_ts_relyingparty/plugins.js +11 -0
- package/package.json +14 -11
- package/readme.md +158 -4
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts_relyingparty/classes.actorscope.ts +39 -0
- package/ts_relyingparty/classes.authorityobserver.ts +253 -0
- package/ts_relyingparty/classes.errors.ts +69 -0
- package/ts_relyingparty/classes.idpoidcprovider.ts +386 -0
- package/ts_relyingparty/classes.relyingpartyroutes.ts +286 -0
- package/ts_relyingparty/classes.relyingpartysessions.ts +970 -0
- package/ts_relyingparty/classes.rpmodels.ts +146 -0
- package/ts_relyingparty/classes.secretbox.ts +49 -0
- package/ts_relyingparty/classes.socketbinding.ts +142 -0
- package/ts_relyingparty/helpers.cookies.ts +79 -0
- package/ts_relyingparty/helpers.crypto.ts +49 -0
- package/ts_relyingparty/helpers.returnpath.ts +44 -0
- package/ts_relyingparty/index.ts +13 -0
- package/ts_relyingparty/interfaces.ts +133 -0
- package/ts_relyingparty/plugins.ts +17 -0
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import * as plugins from './plugins.js';
|
|
2
|
+
/**
|
|
3
|
+
* One browser session of a relying party. The persisted field names, their
|
|
4
|
+
* types and the index declarations are the ones nevermind.finance has stored
|
|
5
|
+
* under `SessionDoc` since before this module existed, so its collection is
|
|
6
|
+
* read and written unchanged.
|
|
7
|
+
*/
|
|
8
|
+
export declare class RelyingPartySessionDoc extends plugins.nosqldb.SmartDataDbDoc<RelyingPartySessionDoc, RelyingPartySessionDoc> {
|
|
9
|
+
id: string;
|
|
10
|
+
/** sha256 of the cookie token; the token itself is never stored */
|
|
11
|
+
tokenHash: string;
|
|
12
|
+
/** the application's principal (user) this session acts as */
|
|
13
|
+
userId: string;
|
|
14
|
+
createdAt: number;
|
|
15
|
+
lastSeenAt: number;
|
|
16
|
+
expiresAt: number;
|
|
17
|
+
/** absent while the session is valid */
|
|
18
|
+
revokedAt?: number;
|
|
19
|
+
/** the provider subject of a provider login; absent for a session the application opened itself */
|
|
20
|
+
idpSubject?: string;
|
|
21
|
+
/** the login attempt this session came out of; finalize matches it */
|
|
22
|
+
loginAttemptId?: string;
|
|
23
|
+
/** sealed with the session encryption key; only the server ever sees the tokens */
|
|
24
|
+
sealedAccessToken?: string;
|
|
25
|
+
sealedRefreshToken?: string;
|
|
26
|
+
/** when the sealed access token dies, epoch milliseconds; `0` when the provider named no lifetime */
|
|
27
|
+
accessTokenExpiresAt?: number;
|
|
28
|
+
/** until when one replica holds the right to rotate this session's tokens, epoch milliseconds */
|
|
29
|
+
refreshLockUntil?: number;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* One browser's sign-in transaction: the state hash the callback is matched
|
|
33
|
+
* against, the binding to the browser that started it, the sealed PKCE
|
|
34
|
+
* verifier and the return path. Consumed exactly once by a conditional update.
|
|
35
|
+
* Field names and indexes are the ones nevermind.finance stores under
|
|
36
|
+
* `LoginAttemptDoc`.
|
|
37
|
+
*/
|
|
38
|
+
export declare class RelyingPartyLoginAttemptDoc extends plugins.nosqldb.SmartDataDbDoc<RelyingPartyLoginAttemptDoc, RelyingPartyLoginAttemptDoc> {
|
|
39
|
+
id: string;
|
|
40
|
+
/** sha256 of the `state` parameter; the parameter itself is never stored */
|
|
41
|
+
stateHash: string;
|
|
42
|
+
/** sha256 of the intent cookie value; binds the callback to the browser that started it */
|
|
43
|
+
bindingTokenHash: string;
|
|
44
|
+
sealedPkceVerifier: string;
|
|
45
|
+
nonce: string;
|
|
46
|
+
/** same-origin path the browser returns to */
|
|
47
|
+
returnPath: string;
|
|
48
|
+
createdAt: number;
|
|
49
|
+
expiresAt: number;
|
|
50
|
+
/** absent until the callback consumes the attempt; `null` matches "not consumed" in a filter */
|
|
51
|
+
consumedAt?: number | null;
|
|
52
|
+
/** the session the callback created; finalize releases the return path against it */
|
|
53
|
+
createdSessionId?: string | null;
|
|
54
|
+
}
|
|
55
|
+
export declare const RELYING_PARTY_DEFAULT_COLLECTION_NAMES: {
|
|
56
|
+
readonly sessions: "IdpRelyingPartySession";
|
|
57
|
+
readonly loginAttempts: "IdpRelyingPartyLoginAttempt";
|
|
58
|
+
};
|
|
59
|
+
export interface IRelyingPartyModelsOptions {
|
|
60
|
+
db: plugins.nosqldb.SmartdataDb;
|
|
61
|
+
/**
|
|
62
|
+
* The persisted collection names. An application that already stores these
|
|
63
|
+
* documents names its existing collections here.
|
|
64
|
+
*/
|
|
65
|
+
collectionNames?: {
|
|
66
|
+
sessions?: string;
|
|
67
|
+
loginAttempts?: string;
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
export interface IRelyingPartyModels {
|
|
71
|
+
readonly Session: typeof RelyingPartySessionDoc;
|
|
72
|
+
readonly LoginAttempt: typeof RelyingPartyLoginAttemptDoc;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Binds the two relying-party models to one database. Each call declares its
|
|
76
|
+
* own model classes, so several databases — and several applications in one
|
|
77
|
+
* process — never share a binding.
|
|
78
|
+
*/
|
|
79
|
+
export declare const createRelyingPartyModels: (optionsArg: IRelyingPartyModelsOptions) => IRelyingPartyModels;
|
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
|
|
2
|
+
function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
|
|
3
|
+
var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
|
|
4
|
+
var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
|
|
5
|
+
var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
|
|
6
|
+
var _, done = false;
|
|
7
|
+
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
8
|
+
var context = {};
|
|
9
|
+
for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
|
|
10
|
+
for (var p in contextIn.access) context.access[p] = contextIn.access[p];
|
|
11
|
+
context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
|
|
12
|
+
var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
|
|
13
|
+
if (kind === "accessor") {
|
|
14
|
+
if (result === void 0) continue;
|
|
15
|
+
if (result === null || typeof result !== "object") throw new TypeError("Object expected");
|
|
16
|
+
if (_ = accept(result.get)) descriptor.get = _;
|
|
17
|
+
if (_ = accept(result.set)) descriptor.set = _;
|
|
18
|
+
if (_ = accept(result.init)) initializers.unshift(_);
|
|
19
|
+
}
|
|
20
|
+
else if (_ = accept(result)) {
|
|
21
|
+
if (kind === "field") initializers.unshift(_);
|
|
22
|
+
else descriptor[key] = _;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
if (target) Object.defineProperty(target, contextIn.name, descriptor);
|
|
26
|
+
done = true;
|
|
27
|
+
};
|
|
28
|
+
var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
|
|
29
|
+
var useValue = arguments.length > 2;
|
|
30
|
+
for (var i = 0; i < initializers.length; i++) {
|
|
31
|
+
value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
|
|
32
|
+
}
|
|
33
|
+
return useValue ? value : void 0;
|
|
34
|
+
};
|
|
35
|
+
import * as plugins from './plugins.js';
|
|
36
|
+
/**
|
|
37
|
+
* One browser session of a relying party. The persisted field names, their
|
|
38
|
+
* types and the index declarations are the ones nevermind.finance has stored
|
|
39
|
+
* under `SessionDoc` since before this module existed, so its collection is
|
|
40
|
+
* read and written unchanged.
|
|
41
|
+
*/
|
|
42
|
+
let RelyingPartySessionDoc = (() => {
|
|
43
|
+
let _classSuper = plugins.nosqldb.SmartDataDbDoc;
|
|
44
|
+
let _id_decorators;
|
|
45
|
+
let _id_initializers = [];
|
|
46
|
+
let _id_extraInitializers = [];
|
|
47
|
+
let _tokenHash_decorators;
|
|
48
|
+
let _tokenHash_initializers = [];
|
|
49
|
+
let _tokenHash_extraInitializers = [];
|
|
50
|
+
let _userId_decorators;
|
|
51
|
+
let _userId_initializers = [];
|
|
52
|
+
let _userId_extraInitializers = [];
|
|
53
|
+
let _createdAt_decorators;
|
|
54
|
+
let _createdAt_initializers = [];
|
|
55
|
+
let _createdAt_extraInitializers = [];
|
|
56
|
+
let _lastSeenAt_decorators;
|
|
57
|
+
let _lastSeenAt_initializers = [];
|
|
58
|
+
let _lastSeenAt_extraInitializers = [];
|
|
59
|
+
let _expiresAt_decorators;
|
|
60
|
+
let _expiresAt_initializers = [];
|
|
61
|
+
let _expiresAt_extraInitializers = [];
|
|
62
|
+
let _revokedAt_decorators;
|
|
63
|
+
let _revokedAt_initializers = [];
|
|
64
|
+
let _revokedAt_extraInitializers = [];
|
|
65
|
+
let _idpSubject_decorators;
|
|
66
|
+
let _idpSubject_initializers = [];
|
|
67
|
+
let _idpSubject_extraInitializers = [];
|
|
68
|
+
let _loginAttemptId_decorators;
|
|
69
|
+
let _loginAttemptId_initializers = [];
|
|
70
|
+
let _loginAttemptId_extraInitializers = [];
|
|
71
|
+
let _sealedAccessToken_decorators;
|
|
72
|
+
let _sealedAccessToken_initializers = [];
|
|
73
|
+
let _sealedAccessToken_extraInitializers = [];
|
|
74
|
+
let _sealedRefreshToken_decorators;
|
|
75
|
+
let _sealedRefreshToken_initializers = [];
|
|
76
|
+
let _sealedRefreshToken_extraInitializers = [];
|
|
77
|
+
let _accessTokenExpiresAt_decorators;
|
|
78
|
+
let _accessTokenExpiresAt_initializers = [];
|
|
79
|
+
let _accessTokenExpiresAt_extraInitializers = [];
|
|
80
|
+
let _refreshLockUntil_decorators;
|
|
81
|
+
let _refreshLockUntil_initializers = [];
|
|
82
|
+
let _refreshLockUntil_extraInitializers = [];
|
|
83
|
+
return class RelyingPartySessionDoc extends _classSuper {
|
|
84
|
+
static {
|
|
85
|
+
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
|
|
86
|
+
_id_decorators = [plugins.nosqldb.unI()];
|
|
87
|
+
_tokenHash_decorators = [plugins.nosqldb.unI()];
|
|
88
|
+
_userId_decorators = [plugins.nosqldb.svDb(), plugins.nosqldb.index()];
|
|
89
|
+
_createdAt_decorators = [plugins.nosqldb.svDb()];
|
|
90
|
+
_lastSeenAt_decorators = [plugins.nosqldb.svDb()];
|
|
91
|
+
_expiresAt_decorators = [plugins.nosqldb.svDb()];
|
|
92
|
+
_revokedAt_decorators = [plugins.nosqldb.svDb()];
|
|
93
|
+
_idpSubject_decorators = [plugins.nosqldb.svDb()];
|
|
94
|
+
_loginAttemptId_decorators = [plugins.nosqldb.svDb()];
|
|
95
|
+
_sealedAccessToken_decorators = [plugins.nosqldb.svDb()];
|
|
96
|
+
_sealedRefreshToken_decorators = [plugins.nosqldb.svDb()];
|
|
97
|
+
_accessTokenExpiresAt_decorators = [plugins.nosqldb.svDb()];
|
|
98
|
+
_refreshLockUntil_decorators = [plugins.nosqldb.svDb()];
|
|
99
|
+
__esDecorate(null, null, _id_decorators, { kind: "field", name: "id", static: false, private: false, access: { has: obj => "id" in obj, get: obj => obj.id, set: (obj, value) => { obj.id = value; } }, metadata: _metadata }, _id_initializers, _id_extraInitializers);
|
|
100
|
+
__esDecorate(null, null, _tokenHash_decorators, { kind: "field", name: "tokenHash", static: false, private: false, access: { has: obj => "tokenHash" in obj, get: obj => obj.tokenHash, set: (obj, value) => { obj.tokenHash = value; } }, metadata: _metadata }, _tokenHash_initializers, _tokenHash_extraInitializers);
|
|
101
|
+
__esDecorate(null, null, _userId_decorators, { kind: "field", name: "userId", static: false, private: false, access: { has: obj => "userId" in obj, get: obj => obj.userId, set: (obj, value) => { obj.userId = value; } }, metadata: _metadata }, _userId_initializers, _userId_extraInitializers);
|
|
102
|
+
__esDecorate(null, null, _createdAt_decorators, { kind: "field", name: "createdAt", static: false, private: false, access: { has: obj => "createdAt" in obj, get: obj => obj.createdAt, set: (obj, value) => { obj.createdAt = value; } }, metadata: _metadata }, _createdAt_initializers, _createdAt_extraInitializers);
|
|
103
|
+
__esDecorate(null, null, _lastSeenAt_decorators, { kind: "field", name: "lastSeenAt", static: false, private: false, access: { has: obj => "lastSeenAt" in obj, get: obj => obj.lastSeenAt, set: (obj, value) => { obj.lastSeenAt = value; } }, metadata: _metadata }, _lastSeenAt_initializers, _lastSeenAt_extraInitializers);
|
|
104
|
+
__esDecorate(null, null, _expiresAt_decorators, { kind: "field", name: "expiresAt", static: false, private: false, access: { has: obj => "expiresAt" in obj, get: obj => obj.expiresAt, set: (obj, value) => { obj.expiresAt = value; } }, metadata: _metadata }, _expiresAt_initializers, _expiresAt_extraInitializers);
|
|
105
|
+
__esDecorate(null, null, _revokedAt_decorators, { kind: "field", name: "revokedAt", static: false, private: false, access: { has: obj => "revokedAt" in obj, get: obj => obj.revokedAt, set: (obj, value) => { obj.revokedAt = value; } }, metadata: _metadata }, _revokedAt_initializers, _revokedAt_extraInitializers);
|
|
106
|
+
__esDecorate(null, null, _idpSubject_decorators, { kind: "field", name: "idpSubject", static: false, private: false, access: { has: obj => "idpSubject" in obj, get: obj => obj.idpSubject, set: (obj, value) => { obj.idpSubject = value; } }, metadata: _metadata }, _idpSubject_initializers, _idpSubject_extraInitializers);
|
|
107
|
+
__esDecorate(null, null, _loginAttemptId_decorators, { kind: "field", name: "loginAttemptId", static: false, private: false, access: { has: obj => "loginAttemptId" in obj, get: obj => obj.loginAttemptId, set: (obj, value) => { obj.loginAttemptId = value; } }, metadata: _metadata }, _loginAttemptId_initializers, _loginAttemptId_extraInitializers);
|
|
108
|
+
__esDecorate(null, null, _sealedAccessToken_decorators, { kind: "field", name: "sealedAccessToken", static: false, private: false, access: { has: obj => "sealedAccessToken" in obj, get: obj => obj.sealedAccessToken, set: (obj, value) => { obj.sealedAccessToken = value; } }, metadata: _metadata }, _sealedAccessToken_initializers, _sealedAccessToken_extraInitializers);
|
|
109
|
+
__esDecorate(null, null, _sealedRefreshToken_decorators, { kind: "field", name: "sealedRefreshToken", static: false, private: false, access: { has: obj => "sealedRefreshToken" in obj, get: obj => obj.sealedRefreshToken, set: (obj, value) => { obj.sealedRefreshToken = value; } }, metadata: _metadata }, _sealedRefreshToken_initializers, _sealedRefreshToken_extraInitializers);
|
|
110
|
+
__esDecorate(null, null, _accessTokenExpiresAt_decorators, { kind: "field", name: "accessTokenExpiresAt", static: false, private: false, access: { has: obj => "accessTokenExpiresAt" in obj, get: obj => obj.accessTokenExpiresAt, set: (obj, value) => { obj.accessTokenExpiresAt = value; } }, metadata: _metadata }, _accessTokenExpiresAt_initializers, _accessTokenExpiresAt_extraInitializers);
|
|
111
|
+
__esDecorate(null, null, _refreshLockUntil_decorators, { kind: "field", name: "refreshLockUntil", static: false, private: false, access: { has: obj => "refreshLockUntil" in obj, get: obj => obj.refreshLockUntil, set: (obj, value) => { obj.refreshLockUntil = value; } }, metadata: _metadata }, _refreshLockUntil_initializers, _refreshLockUntil_extraInitializers);
|
|
112
|
+
if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
113
|
+
}
|
|
114
|
+
id = __runInitializers(this, _id_initializers, '');
|
|
115
|
+
/** sha256 of the cookie token; the token itself is never stored */
|
|
116
|
+
tokenHash = (__runInitializers(this, _id_extraInitializers), __runInitializers(this, _tokenHash_initializers, ''));
|
|
117
|
+
/** the application's principal (user) this session acts as */
|
|
118
|
+
userId = (__runInitializers(this, _tokenHash_extraInitializers), __runInitializers(this, _userId_initializers, ''));
|
|
119
|
+
createdAt = (__runInitializers(this, _userId_extraInitializers), __runInitializers(this, _createdAt_initializers, 0));
|
|
120
|
+
lastSeenAt = (__runInitializers(this, _createdAt_extraInitializers), __runInitializers(this, _lastSeenAt_initializers, 0));
|
|
121
|
+
expiresAt = (__runInitializers(this, _lastSeenAt_extraInitializers), __runInitializers(this, _expiresAt_initializers, 0));
|
|
122
|
+
/** absent while the session is valid */
|
|
123
|
+
revokedAt = (__runInitializers(this, _expiresAt_extraInitializers), __runInitializers(this, _revokedAt_initializers, void 0));
|
|
124
|
+
/** the provider subject of a provider login; absent for a session the application opened itself */
|
|
125
|
+
idpSubject = (__runInitializers(this, _revokedAt_extraInitializers), __runInitializers(this, _idpSubject_initializers, void 0));
|
|
126
|
+
/** the login attempt this session came out of; finalize matches it */
|
|
127
|
+
loginAttemptId = (__runInitializers(this, _idpSubject_extraInitializers), __runInitializers(this, _loginAttemptId_initializers, void 0));
|
|
128
|
+
/** sealed with the session encryption key; only the server ever sees the tokens */
|
|
129
|
+
sealedAccessToken = (__runInitializers(this, _loginAttemptId_extraInitializers), __runInitializers(this, _sealedAccessToken_initializers, void 0));
|
|
130
|
+
sealedRefreshToken = (__runInitializers(this, _sealedAccessToken_extraInitializers), __runInitializers(this, _sealedRefreshToken_initializers, void 0));
|
|
131
|
+
/** when the sealed access token dies, epoch milliseconds; `0` when the provider named no lifetime */
|
|
132
|
+
accessTokenExpiresAt = (__runInitializers(this, _sealedRefreshToken_extraInitializers), __runInitializers(this, _accessTokenExpiresAt_initializers, void 0));
|
|
133
|
+
/** until when one replica holds the right to rotate this session's tokens, epoch milliseconds */
|
|
134
|
+
refreshLockUntil = (__runInitializers(this, _accessTokenExpiresAt_extraInitializers), __runInitializers(this, _refreshLockUntil_initializers, void 0));
|
|
135
|
+
constructor() {
|
|
136
|
+
super(...arguments);
|
|
137
|
+
__runInitializers(this, _refreshLockUntil_extraInitializers);
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
})();
|
|
141
|
+
export { RelyingPartySessionDoc };
|
|
142
|
+
/**
|
|
143
|
+
* One browser's sign-in transaction: the state hash the callback is matched
|
|
144
|
+
* against, the binding to the browser that started it, the sealed PKCE
|
|
145
|
+
* verifier and the return path. Consumed exactly once by a conditional update.
|
|
146
|
+
* Field names and indexes are the ones nevermind.finance stores under
|
|
147
|
+
* `LoginAttemptDoc`.
|
|
148
|
+
*/
|
|
149
|
+
let RelyingPartyLoginAttemptDoc = (() => {
|
|
150
|
+
let _classSuper = plugins.nosqldb.SmartDataDbDoc;
|
|
151
|
+
let _id_decorators;
|
|
152
|
+
let _id_initializers = [];
|
|
153
|
+
let _id_extraInitializers = [];
|
|
154
|
+
let _stateHash_decorators;
|
|
155
|
+
let _stateHash_initializers = [];
|
|
156
|
+
let _stateHash_extraInitializers = [];
|
|
157
|
+
let _bindingTokenHash_decorators;
|
|
158
|
+
let _bindingTokenHash_initializers = [];
|
|
159
|
+
let _bindingTokenHash_extraInitializers = [];
|
|
160
|
+
let _sealedPkceVerifier_decorators;
|
|
161
|
+
let _sealedPkceVerifier_initializers = [];
|
|
162
|
+
let _sealedPkceVerifier_extraInitializers = [];
|
|
163
|
+
let _nonce_decorators;
|
|
164
|
+
let _nonce_initializers = [];
|
|
165
|
+
let _nonce_extraInitializers = [];
|
|
166
|
+
let _returnPath_decorators;
|
|
167
|
+
let _returnPath_initializers = [];
|
|
168
|
+
let _returnPath_extraInitializers = [];
|
|
169
|
+
let _createdAt_decorators;
|
|
170
|
+
let _createdAt_initializers = [];
|
|
171
|
+
let _createdAt_extraInitializers = [];
|
|
172
|
+
let _expiresAt_decorators;
|
|
173
|
+
let _expiresAt_initializers = [];
|
|
174
|
+
let _expiresAt_extraInitializers = [];
|
|
175
|
+
let _consumedAt_decorators;
|
|
176
|
+
let _consumedAt_initializers = [];
|
|
177
|
+
let _consumedAt_extraInitializers = [];
|
|
178
|
+
let _createdSessionId_decorators;
|
|
179
|
+
let _createdSessionId_initializers = [];
|
|
180
|
+
let _createdSessionId_extraInitializers = [];
|
|
181
|
+
return class RelyingPartyLoginAttemptDoc extends _classSuper {
|
|
182
|
+
static {
|
|
183
|
+
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
|
|
184
|
+
_id_decorators = [plugins.nosqldb.unI()];
|
|
185
|
+
_stateHash_decorators = [plugins.nosqldb.unI()];
|
|
186
|
+
_bindingTokenHash_decorators = [plugins.nosqldb.unI()];
|
|
187
|
+
_sealedPkceVerifier_decorators = [plugins.nosqldb.svDb()];
|
|
188
|
+
_nonce_decorators = [plugins.nosqldb.svDb()];
|
|
189
|
+
_returnPath_decorators = [plugins.nosqldb.svDb()];
|
|
190
|
+
_createdAt_decorators = [plugins.nosqldb.svDb()];
|
|
191
|
+
_expiresAt_decorators = [plugins.nosqldb.svDb()];
|
|
192
|
+
_consumedAt_decorators = [plugins.nosqldb.svDb()];
|
|
193
|
+
_createdSessionId_decorators = [plugins.nosqldb.svDb()];
|
|
194
|
+
__esDecorate(null, null, _id_decorators, { kind: "field", name: "id", static: false, private: false, access: { has: obj => "id" in obj, get: obj => obj.id, set: (obj, value) => { obj.id = value; } }, metadata: _metadata }, _id_initializers, _id_extraInitializers);
|
|
195
|
+
__esDecorate(null, null, _stateHash_decorators, { kind: "field", name: "stateHash", static: false, private: false, access: { has: obj => "stateHash" in obj, get: obj => obj.stateHash, set: (obj, value) => { obj.stateHash = value; } }, metadata: _metadata }, _stateHash_initializers, _stateHash_extraInitializers);
|
|
196
|
+
__esDecorate(null, null, _bindingTokenHash_decorators, { kind: "field", name: "bindingTokenHash", static: false, private: false, access: { has: obj => "bindingTokenHash" in obj, get: obj => obj.bindingTokenHash, set: (obj, value) => { obj.bindingTokenHash = value; } }, metadata: _metadata }, _bindingTokenHash_initializers, _bindingTokenHash_extraInitializers);
|
|
197
|
+
__esDecorate(null, null, _sealedPkceVerifier_decorators, { kind: "field", name: "sealedPkceVerifier", static: false, private: false, access: { has: obj => "sealedPkceVerifier" in obj, get: obj => obj.sealedPkceVerifier, set: (obj, value) => { obj.sealedPkceVerifier = value; } }, metadata: _metadata }, _sealedPkceVerifier_initializers, _sealedPkceVerifier_extraInitializers);
|
|
198
|
+
__esDecorate(null, null, _nonce_decorators, { kind: "field", name: "nonce", static: false, private: false, access: { has: obj => "nonce" in obj, get: obj => obj.nonce, set: (obj, value) => { obj.nonce = value; } }, metadata: _metadata }, _nonce_initializers, _nonce_extraInitializers);
|
|
199
|
+
__esDecorate(null, null, _returnPath_decorators, { kind: "field", name: "returnPath", static: false, private: false, access: { has: obj => "returnPath" in obj, get: obj => obj.returnPath, set: (obj, value) => { obj.returnPath = value; } }, metadata: _metadata }, _returnPath_initializers, _returnPath_extraInitializers);
|
|
200
|
+
__esDecorate(null, null, _createdAt_decorators, { kind: "field", name: "createdAt", static: false, private: false, access: { has: obj => "createdAt" in obj, get: obj => obj.createdAt, set: (obj, value) => { obj.createdAt = value; } }, metadata: _metadata }, _createdAt_initializers, _createdAt_extraInitializers);
|
|
201
|
+
__esDecorate(null, null, _expiresAt_decorators, { kind: "field", name: "expiresAt", static: false, private: false, access: { has: obj => "expiresAt" in obj, get: obj => obj.expiresAt, set: (obj, value) => { obj.expiresAt = value; } }, metadata: _metadata }, _expiresAt_initializers, _expiresAt_extraInitializers);
|
|
202
|
+
__esDecorate(null, null, _consumedAt_decorators, { kind: "field", name: "consumedAt", static: false, private: false, access: { has: obj => "consumedAt" in obj, get: obj => obj.consumedAt, set: (obj, value) => { obj.consumedAt = value; } }, metadata: _metadata }, _consumedAt_initializers, _consumedAt_extraInitializers);
|
|
203
|
+
__esDecorate(null, null, _createdSessionId_decorators, { kind: "field", name: "createdSessionId", static: false, private: false, access: { has: obj => "createdSessionId" in obj, get: obj => obj.createdSessionId, set: (obj, value) => { obj.createdSessionId = value; } }, metadata: _metadata }, _createdSessionId_initializers, _createdSessionId_extraInitializers);
|
|
204
|
+
if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
205
|
+
}
|
|
206
|
+
id = __runInitializers(this, _id_initializers, '');
|
|
207
|
+
/** sha256 of the `state` parameter; the parameter itself is never stored */
|
|
208
|
+
stateHash = (__runInitializers(this, _id_extraInitializers), __runInitializers(this, _stateHash_initializers, ''));
|
|
209
|
+
/** sha256 of the intent cookie value; binds the callback to the browser that started it */
|
|
210
|
+
bindingTokenHash = (__runInitializers(this, _stateHash_extraInitializers), __runInitializers(this, _bindingTokenHash_initializers, ''));
|
|
211
|
+
sealedPkceVerifier = (__runInitializers(this, _bindingTokenHash_extraInitializers), __runInitializers(this, _sealedPkceVerifier_initializers, ''));
|
|
212
|
+
nonce = (__runInitializers(this, _sealedPkceVerifier_extraInitializers), __runInitializers(this, _nonce_initializers, ''));
|
|
213
|
+
/** same-origin path the browser returns to */
|
|
214
|
+
returnPath = (__runInitializers(this, _nonce_extraInitializers), __runInitializers(this, _returnPath_initializers, '/'));
|
|
215
|
+
createdAt = (__runInitializers(this, _returnPath_extraInitializers), __runInitializers(this, _createdAt_initializers, 0));
|
|
216
|
+
expiresAt = (__runInitializers(this, _createdAt_extraInitializers), __runInitializers(this, _expiresAt_initializers, 0));
|
|
217
|
+
/** absent until the callback consumes the attempt; `null` matches "not consumed" in a filter */
|
|
218
|
+
consumedAt = (__runInitializers(this, _expiresAt_extraInitializers), __runInitializers(this, _consumedAt_initializers, void 0));
|
|
219
|
+
/** the session the callback created; finalize releases the return path against it */
|
|
220
|
+
createdSessionId = (__runInitializers(this, _consumedAt_extraInitializers), __runInitializers(this, _createdSessionId_initializers, void 0));
|
|
221
|
+
constructor() {
|
|
222
|
+
super(...arguments);
|
|
223
|
+
__runInitializers(this, _createdSessionId_extraInitializers);
|
|
224
|
+
}
|
|
225
|
+
};
|
|
226
|
+
})();
|
|
227
|
+
export { RelyingPartyLoginAttemptDoc };
|
|
228
|
+
export const RELYING_PARTY_DEFAULT_COLLECTION_NAMES = {
|
|
229
|
+
sessions: 'IdpRelyingPartySession',
|
|
230
|
+
loginAttempts: 'IdpRelyingPartyLoginAttempt',
|
|
231
|
+
};
|
|
232
|
+
/**
|
|
233
|
+
* Binds the two relying-party models to one database. Each call declares its
|
|
234
|
+
* own model classes, so several databases — and several applications in one
|
|
235
|
+
* process — never share a binding.
|
|
236
|
+
*/
|
|
237
|
+
export const createRelyingPartyModels = (optionsArg) => {
|
|
238
|
+
const db = optionsArg.db;
|
|
239
|
+
if (!(db instanceof plugins.nosqldb.SmartdataDb)) {
|
|
240
|
+
throw new Error('createRelyingPartyModels needs a SmartdataDb of @lossless.org/client/nosqldb');
|
|
241
|
+
}
|
|
242
|
+
const sessions = optionsArg.collectionNames?.sessions ?? RELYING_PARTY_DEFAULT_COLLECTION_NAMES.sessions;
|
|
243
|
+
const loginAttempts = optionsArg.collectionNames?.loginAttempts
|
|
244
|
+
?? RELYING_PARTY_DEFAULT_COLLECTION_NAMES.loginAttempts;
|
|
245
|
+
let BoundSessionDoc = (() => {
|
|
246
|
+
let _classDecorators = [plugins.nosqldb.Collection(() => db, { collectionName: sessions })];
|
|
247
|
+
let _classDescriptor;
|
|
248
|
+
let _classExtraInitializers = [];
|
|
249
|
+
let _classThis;
|
|
250
|
+
let _classSuper = RelyingPartySessionDoc;
|
|
251
|
+
var BoundSessionDoc = class extends _classSuper {
|
|
252
|
+
static { _classThis = this; }
|
|
253
|
+
static {
|
|
254
|
+
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
|
|
255
|
+
__esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
|
|
256
|
+
BoundSessionDoc = _classThis = _classDescriptor.value;
|
|
257
|
+
if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
258
|
+
__runInitializers(_classThis, _classExtraInitializers);
|
|
259
|
+
}
|
|
260
|
+
};
|
|
261
|
+
return BoundSessionDoc = _classThis;
|
|
262
|
+
})();
|
|
263
|
+
let BoundLoginAttemptDoc = (() => {
|
|
264
|
+
let _classDecorators = [plugins.nosqldb.Collection(() => db, { collectionName: loginAttempts })];
|
|
265
|
+
let _classDescriptor;
|
|
266
|
+
let _classExtraInitializers = [];
|
|
267
|
+
let _classThis;
|
|
268
|
+
let _classSuper = RelyingPartyLoginAttemptDoc;
|
|
269
|
+
var BoundLoginAttemptDoc = class extends _classSuper {
|
|
270
|
+
static { _classThis = this; }
|
|
271
|
+
static {
|
|
272
|
+
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
|
|
273
|
+
__esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
|
|
274
|
+
BoundLoginAttemptDoc = _classThis = _classDescriptor.value;
|
|
275
|
+
if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
276
|
+
__runInitializers(_classThis, _classExtraInitializers);
|
|
277
|
+
}
|
|
278
|
+
};
|
|
279
|
+
return BoundLoginAttemptDoc = _classThis;
|
|
280
|
+
})();
|
|
281
|
+
return { Session: BoundSessionDoc, LoginAttempt: BoundLoginAttemptDoc };
|
|
282
|
+
};
|
|
283
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5ycG1vZGVscy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3RzX3JlbHlpbmdwYXJ0eS9jbGFzc2VzLnJwbW9kZWxzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGNBQWMsQ0FBQztBQUV4Qzs7Ozs7R0FLRztJQUNVLHNCQUFzQjtzQkFBUyxPQUFPLENBQUMsT0FBTyxDQUFDLGNBQWM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7aUJBQTdELHNCQUF1QixTQUFRLFdBQThFOzs7OEJBQ3ZILE9BQU8sQ0FBQyxPQUFPLENBQUMsR0FBRyxFQUFFO3FDQUlyQixPQUFPLENBQUMsT0FBTyxDQUFDLEdBQUcsRUFBRTtrQ0FJckIsT0FBTyxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsRUFDdEIsT0FBTyxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUU7cUNBR3ZCLE9BQU8sQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFO3NDQUd0QixPQUFPLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRTtxQ0FHdEIsT0FBTyxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUU7cUNBSXRCLE9BQU8sQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFO3NDQUl0QixPQUFPLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRTswQ0FJdEIsT0FBTyxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUU7NkNBSXRCLE9BQU8sQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFOzhDQUd0QixPQUFPLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRTtnREFJdEIsT0FBTyxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUU7NENBSXRCLE9BQU8sQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFO1lBNUN2Qix3SkFBTyxFQUFFLDZCQUFGLEVBQUUsK0VBQWM7WUFJdkIsNktBQU8sU0FBUyw2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
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Seals small secrets at rest — the PKCE verifier of a login attempt and the
|
|
3
|
+
* provider tokens of a session — with AES-256-GCM under a 32-byte deployment
|
|
4
|
+
* key. The sealed form is `v1:<base64url iv>:<base64url tag>:<base64url
|
|
5
|
+
* ciphertext>`, the form nevermind.finance has stored since before this module
|
|
6
|
+
* existed, so its sealed values open here unchanged.
|
|
7
|
+
*/
|
|
8
|
+
export declare class SecretBox {
|
|
9
|
+
#private;
|
|
10
|
+
constructor(keyArg: Buffer);
|
|
11
|
+
seal(plainArg: string): string;
|
|
12
|
+
/** The plain value, or a throw: another format, another key, or a changed byte. */
|
|
13
|
+
open(sealedArg: string): string;
|
|
14
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import * as plugins from './plugins.js';
|
|
2
|
+
/**
|
|
3
|
+
* The persisted format tag of a sealed value. It names the stored layout of
|
|
4
|
+
* values that already exist and is read as it is; it is not an API version.
|
|
5
|
+
*/
|
|
6
|
+
const SEALED_FORMAT = 'v1';
|
|
7
|
+
const ALGORITHM = 'aes-256-gcm';
|
|
8
|
+
const IV_LENGTH = 12;
|
|
9
|
+
const TAG_LENGTH = 16;
|
|
10
|
+
/**
|
|
11
|
+
* Seals small secrets at rest — the PKCE verifier of a login attempt and the
|
|
12
|
+
* provider tokens of a session — with AES-256-GCM under a 32-byte deployment
|
|
13
|
+
* key. The sealed form is `v1:<base64url iv>:<base64url tag>:<base64url
|
|
14
|
+
* ciphertext>`, the form nevermind.finance has stored since before this module
|
|
15
|
+
* existed, so its sealed values open here unchanged.
|
|
16
|
+
*/
|
|
17
|
+
export class SecretBox {
|
|
18
|
+
#key;
|
|
19
|
+
constructor(keyArg) {
|
|
20
|
+
if (!Buffer.isBuffer(keyArg) || keyArg.length !== 32) {
|
|
21
|
+
throw new Error('SecretBox needs a 32 byte key');
|
|
22
|
+
}
|
|
23
|
+
this.#key = Buffer.from(keyArg);
|
|
24
|
+
}
|
|
25
|
+
seal(plainArg) {
|
|
26
|
+
const iv = plugins.crypto.randomBytes(IV_LENGTH);
|
|
27
|
+
const cipher = plugins.crypto.createCipheriv(ALGORITHM, this.#key, iv, { authTagLength: TAG_LENGTH });
|
|
28
|
+
const ciphertext = Buffer.concat([cipher.update(plainArg, 'utf8'), cipher.final()]);
|
|
29
|
+
const tag = cipher.getAuthTag();
|
|
30
|
+
return [SEALED_FORMAT, iv.toString('base64url'), tag.toString('base64url'), ciphertext.toString('base64url')].join(':');
|
|
31
|
+
}
|
|
32
|
+
/** The plain value, or a throw: another format, another key, or a changed byte. */
|
|
33
|
+
open(sealedArg) {
|
|
34
|
+
const [format, ivText, tagText, cipherText] = sealedArg.split(':');
|
|
35
|
+
if (format !== SEALED_FORMAT || !ivText || !tagText || cipherText === undefined) {
|
|
36
|
+
throw new Error('Sealed secret has an unknown format');
|
|
37
|
+
}
|
|
38
|
+
const decipher = plugins.crypto.createDecipheriv(ALGORITHM, this.#key, Buffer.from(ivText, 'base64url'), {
|
|
39
|
+
authTagLength: TAG_LENGTH,
|
|
40
|
+
});
|
|
41
|
+
decipher.setAuthTag(Buffer.from(tagText, 'base64url'));
|
|
42
|
+
return Buffer.concat([decipher.update(Buffer.from(cipherText, 'base64url')), decipher.final()]).toString('utf8');
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5zZWNyZXRib3guanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90c19yZWx5aW5ncGFydHkvY2xhc3Nlcy5zZWNyZXRib3gudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxjQUFjLENBQUM7QUFFeEM7OztHQUdHO0FBQ0gsTUFBTSxhQUFhLEdBQUcsSUFBSSxDQUFDO0FBQzNCLE1BQU0sU0FBUyxHQUFHLGFBQWEsQ0FBQztBQUNoQyxNQUFNLFNBQVMsR0FBRyxFQUFFLENBQUM7QUFDckIsTUFBTSxVQUFVLEdBQUcsRUFBRSxDQUFDO0FBRXRCOzs7Ozs7R0FNRztBQUNILE1BQU0sT0FBTyxTQUFTO0lBQ1gsSUFBSSxDQUFTO0lBRXRCLFlBQVksTUFBYztRQUN4QixJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsSUFBSSxNQUFNLENBQUMsTUFBTSxLQUFLLEVBQUUsRUFBRSxDQUFDO1lBQ3JELE1BQU0sSUFBSSxLQUFLLENBQUMsK0JBQStCLENBQUMsQ0FBQztRQUNuRCxDQUFDO1FBQ0QsSUFBSSxDQUFDLElBQUksR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQ2xDLENBQUM7SUFFTSxJQUFJLENBQUMsUUFBZ0I7UUFDMUIsTUFBTSxFQUFFLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQyxXQUFXLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDakQsTUFBTSxNQUFNLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQyxjQUFjLENBQUMsU0FBUyxFQUFFLElBQUksQ0FBQyxJQUFJLEVBQUUsRUFBRSxFQUFFLEVBQUUsYUFBYSxFQUFFLFVBQVUsRUFBRSxDQUFDLENBQUM7UUFDdEcsTUFBTSxVQUFVLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsUUFBUSxFQUFFLE1BQU0sQ0FBQyxFQUFFLE1BQU0sQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDcEYsTUFBTSxHQUFHLEdBQUcsTUFBTSxDQUFDLFVBQVUsRUFBRSxDQUFDO1FBQ2hDLE9BQU8sQ0FBQyxhQUFhLEVBQUUsRUFBRSxDQUFDLFFBQVEsQ0FBQyxXQUFXLENBQUMsRUFBRSxHQUFHLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBQyxFQUFFLFVBQVUsQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDMUgsQ0FBQztJQUVELG1GQUFtRjtJQUM1RSxJQUFJLENBQUMsU0FBaUI7UUFDM0IsTUFBTSxDQUFDLE1BQU0sRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFFLFVBQVUsQ0FBQyxHQUFHLFNBQVMsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDbkUsSUFBSSxNQUFNLEtBQUssYUFBYSxJQUFJLENBQUMsTUFBTSxJQUFJLENBQUMsT0FBTyxJQUFJLFVBQVUsS0FBSyxTQUFTLEVBQUUsQ0FBQztZQUNoRixNQUFNLElBQUksS0FBSyxDQUFDLHFDQUFxQyxDQUFDLENBQUM7UUFDekQsQ0FBQztRQUNELE1BQU0sUUFBUSxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUMsZ0JBQWdCLENBQUMsU0FBUyxFQUFFLElBQUksQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsV0FBVyxDQUFDLEVBQUU7WUFDdkcsYUFBYSxFQUFFLFVBQVU7U0FDMUIsQ0FBQyxDQUFDO1FBQ0gsUUFBUSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxXQUFXLENBQUMsQ0FBQyxDQUFDO1FBQ3ZELE9BQU8sTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxVQUFVLEVBQUUsV0FBVyxDQUFDLENBQUMsRUFBRSxRQUFRLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUNuSCxDQUFDO0NBQ0YifQ==
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import * as plugins from './plugins.js';
|
|
2
|
+
import type { RelyingPartySessions } from './classes.relyingpartysessions.js';
|
|
3
|
+
import type { IRelyingPartySession } from './interfaces.js';
|
|
4
|
+
/** The part of a server `TypedSocket` the binding uses. */
|
|
5
|
+
export type TRelyingPartySocketTransport = Pick<plugins.typedsocket.TypedSocket, 'setServerTag' | 'findAllTargetConnectionsByTag'>;
|
|
6
|
+
export type TRelyingPartySocketConnection = plugins.typedsocket.ISmartServeConnectionWrapper;
|
|
7
|
+
/** What a browser connection is pinned to for its whole life; no cookie and no CSRF token is kept. */
|
|
8
|
+
export interface IRelyingPartyPinnedSession {
|
|
9
|
+
sessionId: string;
|
|
10
|
+
principalId: string;
|
|
11
|
+
/** SHA-256 of the CSRF token the registration proved */
|
|
12
|
+
csrfTokenHash: string;
|
|
13
|
+
}
|
|
14
|
+
export interface IRelyingPartySocketRefusal {
|
|
15
|
+
code: 'invalid_input' | 'forbidden' | 'unauthorized';
|
|
16
|
+
status: number;
|
|
17
|
+
}
|
|
18
|
+
export type TRelyingPartySocketRegistration = {
|
|
19
|
+
registered: true;
|
|
20
|
+
pinned: IRelyingPartyPinnedSession;
|
|
21
|
+
expiresAt: number;
|
|
22
|
+
} | {
|
|
23
|
+
registered: false;
|
|
24
|
+
refusal: IRelyingPartySocketRefusal;
|
|
25
|
+
};
|
|
26
|
+
export interface IRelyingPartySocketBindingOptions {
|
|
27
|
+
sessions: RelyingPartySessions;
|
|
28
|
+
/** the transport typedserver created; `undefined` before the server runs */
|
|
29
|
+
transport: () => TRelyingPartySocketTransport | undefined;
|
|
30
|
+
/** the server-owned tag prefix that finds the connections of a session */
|
|
31
|
+
tagPrefix?: string;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Binds typed socket connections to relying-party browser sessions. A
|
|
35
|
+
* connection registers once with the CSRF token of the page; the proof is the
|
|
36
|
+
* upgrade's own `Origin` and `Cookie` — which only a browser on this origin
|
|
37
|
+
* sends — plus the token, and the connection is pinned to the session. Every
|
|
38
|
+
* later request re-validates the session with the same strength as an HTTP
|
|
39
|
+
* request. Connection limits, rate limits and sweeps belong to the
|
|
40
|
+
* application's socket gate.
|
|
41
|
+
*/
|
|
42
|
+
export declare class RelyingPartySocketBinding {
|
|
43
|
+
#private;
|
|
44
|
+
readonly tagPrefix: string;
|
|
45
|
+
constructor(optionsArg: IRelyingPartySocketBindingOptions);
|
|
46
|
+
/** The upgrade headers a connection arrived with. */
|
|
47
|
+
upgradeOf(connectionArg: TRelyingPartySocketConnection): {
|
|
48
|
+
origin: string | null;
|
|
49
|
+
cookie: string | null;
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* What a registration payload `{ csrfToken }` proves, given the upgrade it
|
|
53
|
+
* came on. No connection state is touched, so the application decides about
|
|
54
|
+
* its limits between this answer and `tagConnection`.
|
|
55
|
+
*/
|
|
56
|
+
resolveBrowserRegistration(payloadArg: unknown, upgradeArg: {
|
|
57
|
+
origin: string | null;
|
|
58
|
+
cookie: string | null;
|
|
59
|
+
}): Promise<TRelyingPartySocketRegistration>;
|
|
60
|
+
tagOf(sessionIdArg: string): string;
|
|
61
|
+
/** Tags a connection with its session; throws when the transport is not running or the connection is gone. */
|
|
62
|
+
tagConnection(connectionArg: TRelyingPartySocketConnection, sessionIdArg: string): void;
|
|
63
|
+
/**
|
|
64
|
+
* The pinned session as it stands right now: re-read, live, its principal
|
|
65
|
+
* active and unchanged, touched under the liveness it was read with. The
|
|
66
|
+
* browser keeps proving itself with its CSRF token, compared against the
|
|
67
|
+
* hash the registration kept. Nothing of this is cached.
|
|
68
|
+
*/
|
|
69
|
+
revalidate(pinnedArg: IRelyingPartyPinnedSession): Promise<{
|
|
70
|
+
session: IRelyingPartySession;
|
|
71
|
+
verifyCsrf(candidateArg: unknown): boolean;
|
|
72
|
+
} | null>;
|
|
73
|
+
/** The live connections of one session, for closing them when it ends. */
|
|
74
|
+
connectionsOfSession(sessionIdArg: string): Promise<readonly TRelyingPartySocketConnection[]>;
|
|
75
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import * as plugins from './plugins.js';
|
|
2
|
+
import { sha256, timingSafeEqualString } from './helpers.crypto.js';
|
|
3
|
+
/**
|
|
4
|
+
* Binds typed socket connections to relying-party browser sessions. A
|
|
5
|
+
* connection registers once with the CSRF token of the page; the proof is the
|
|
6
|
+
* upgrade's own `Origin` and `Cookie` — which only a browser on this origin
|
|
7
|
+
* sends — plus the token, and the connection is pinned to the session. Every
|
|
8
|
+
* later request re-validates the session with the same strength as an HTTP
|
|
9
|
+
* request. Connection limits, rate limits and sweeps belong to the
|
|
10
|
+
* application's socket gate.
|
|
11
|
+
*/
|
|
12
|
+
export class RelyingPartySocketBinding {
|
|
13
|
+
#sessions;
|
|
14
|
+
#transport;
|
|
15
|
+
tagPrefix;
|
|
16
|
+
constructor(optionsArg) {
|
|
17
|
+
this.#sessions = optionsArg.sessions;
|
|
18
|
+
this.#transport = optionsArg.transport;
|
|
19
|
+
this.tagPrefix = optionsArg.tagPrefix ?? 'idp_rp_session:';
|
|
20
|
+
}
|
|
21
|
+
/** The upgrade headers a connection arrived with. */
|
|
22
|
+
upgradeOf(connectionArg) {
|
|
23
|
+
const headers = connectionArg.peer.context.headers;
|
|
24
|
+
return { origin: headers.get('origin'), cookie: headers.get('cookie') };
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* What a registration payload `{ csrfToken }` proves, given the upgrade it
|
|
28
|
+
* came on. No connection state is touched, so the application decides about
|
|
29
|
+
* its limits between this answer and `tagConnection`.
|
|
30
|
+
*/
|
|
31
|
+
async resolveBrowserRegistration(payloadArg, upgradeArg) {
|
|
32
|
+
if (!payloadArg || typeof payloadArg !== 'object' || !Reflect.has(payloadArg, 'csrfToken')) {
|
|
33
|
+
return { registered: false, refusal: { code: 'invalid_input', status: 400 } };
|
|
34
|
+
}
|
|
35
|
+
if (upgradeArg.origin !== this.#sessions.publicOrigin) {
|
|
36
|
+
return { registered: false, refusal: { code: 'forbidden', status: 403 } };
|
|
37
|
+
}
|
|
38
|
+
const resolved = await this.#sessions.resolveCookieSession(upgradeArg.cookie);
|
|
39
|
+
if (!resolved) {
|
|
40
|
+
return { registered: false, refusal: { code: 'unauthorized', status: 401 } };
|
|
41
|
+
}
|
|
42
|
+
if (!this.#sessions.validateCsrf(resolved, Reflect.get(payloadArg, 'csrfToken'))) {
|
|
43
|
+
return { registered: false, refusal: { code: 'forbidden', status: 403 } };
|
|
44
|
+
}
|
|
45
|
+
return {
|
|
46
|
+
registered: true,
|
|
47
|
+
pinned: {
|
|
48
|
+
sessionId: resolved.session.id,
|
|
49
|
+
principalId: resolved.session.principalId,
|
|
50
|
+
csrfTokenHash: sha256(resolved.csrfToken),
|
|
51
|
+
},
|
|
52
|
+
expiresAt: resolved.session.expiresAt,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
tagOf(sessionIdArg) {
|
|
56
|
+
return this.tagPrefix + sessionIdArg;
|
|
57
|
+
}
|
|
58
|
+
/** Tags a connection with its session; throws when the transport is not running or the connection is gone. */
|
|
59
|
+
tagConnection(connectionArg, sessionIdArg) {
|
|
60
|
+
const transport = this.#transport();
|
|
61
|
+
if (!transport) {
|
|
62
|
+
throw new Error('The socket transport is not running');
|
|
63
|
+
}
|
|
64
|
+
transport.setServerTag(connectionArg, this.tagOf(sessionIdArg));
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* The pinned session as it stands right now: re-read, live, its principal
|
|
68
|
+
* active and unchanged, touched under the liveness it was read with. The
|
|
69
|
+
* browser keeps proving itself with its CSRF token, compared against the
|
|
70
|
+
* hash the registration kept. Nothing of this is cached.
|
|
71
|
+
*/
|
|
72
|
+
async revalidate(pinnedArg) {
|
|
73
|
+
const session = await this.#sessions.revalidateSession(pinnedArg.sessionId);
|
|
74
|
+
if (!session || session.principalId !== pinnedArg.principalId) {
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
const expectedHash = pinnedArg.csrfTokenHash;
|
|
78
|
+
return {
|
|
79
|
+
session,
|
|
80
|
+
verifyCsrf: (candidateArg) => typeof candidateArg === 'string'
|
|
81
|
+
&& expectedHash.length > 0
|
|
82
|
+
&& timingSafeEqualString(expectedHash, sha256(candidateArg)),
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
/** The live connections of one session, for closing them when it ends. */
|
|
86
|
+
async connectionsOfSession(sessionIdArg) {
|
|
87
|
+
const transport = this.#transport();
|
|
88
|
+
if (!transport) {
|
|
89
|
+
return [];
|
|
90
|
+
}
|
|
91
|
+
return transport.findAllTargetConnectionsByTag(this.tagOf(sessionIdArg));
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5zb2NrZXRiaW5kaW5nLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdHNfcmVseWluZ3BhcnR5L2NsYXNzZXMuc29ja2V0YmluZGluZy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGNBQWMsQ0FBQztBQUV4QyxPQUFPLEVBQUUsTUFBTSxFQUFFLHFCQUFxQixFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFvQ3BFOzs7Ozs7OztHQVFHO0FBQ0gsTUFBTSxPQUFPLHlCQUF5QjtJQUMzQixTQUFTLENBQXVCO0lBQ2hDLFVBQVUsQ0FBaUQ7SUFDcEQsU0FBUyxDQUFTO0lBRWxDLFlBQVksVUFBNkM7UUFDdkQsSUFBSSxDQUFDLFNBQVMsR0FBRyxVQUFVLENBQUMsUUFBUSxDQUFDO1FBQ3JDLElBQUksQ0FBQyxVQUFVLEdBQUcsVUFBVSxDQUFDLFNBQVMsQ0FBQztRQUN2QyxJQUFJLENBQUMsU0FBUyxHQUFHLFVBQVUsQ0FBQyxTQUFTLElBQUksaUJBQWlCLENBQUM7SUFDN0QsQ0FBQztJQUVELHFEQUFxRDtJQUM5QyxTQUFTLENBQUMsYUFBNEM7UUFDM0QsTUFBTSxPQUFPLEdBQUcsYUFBYSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDO1FBQ25ELE9BQU8sRUFBRSxNQUFNLEVBQUUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsRUFBRSxNQUFNLEVBQUUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDO0lBQzFFLENBQUM7SUFFRDs7OztPQUlHO0lBQ0ksS0FBSyxDQUFDLDBCQUEwQixDQUNyQyxVQUFtQixFQUNuQixVQUE0RDtRQUU1RCxJQUFJLENBQUMsVUFBVSxJQUFJLE9BQU8sVUFBVSxLQUFLLFFBQVEsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsVUFBVSxFQUFFLFdBQVcsQ0FBQyxFQUFFLENBQUM7WUFDM0YsT0FBTyxF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
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface ICookieOptions {
|
|
2
|
+
httpOnly?: boolean;
|
|
3
|
+
maxAgeSeconds?: number;
|
|
4
|
+
sameSite?: 'Lax' | 'Strict' | 'None';
|
|
5
|
+
secure?: boolean;
|
|
6
|
+
}
|
|
7
|
+
/** The cookies of a `Cookie` header; the first value of a repeated name wins, an undecodable value is skipped. */
|
|
8
|
+
export declare const parseCookies: (cookieHeaderArg: string | null | undefined) => Map<string, string>;
|
|
9
|
+
/** One `Set-Cookie` value, always `Path=/` and never with a `Domain`, so a `__Host-` name stays valid. */
|
|
10
|
+
export declare const serializeCookie: (nameArg: string, valueArg: string, optionsArg?: ICookieOptions) => string;
|
|
11
|
+
export declare const serializeClearedCookie: (nameArg: string, optionsArg?: Omit<ICookieOptions, "maxAgeSeconds">) => string;
|