@idp.global/sdk 18.3.1 → 19.0.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 +12 -0
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts_relyingparty/classes.socketbinding.d.ts +33 -14
- package/dist_ts_relyingparty/classes.socketbinding.js +1 -2
- package/dist_ts_relyingparty/plugins.d.ts +1 -2
- package/dist_ts_relyingparty/plugins.js +2 -3
- package/package.json +5 -5
- package/readme.md +18 -1
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts_relyingparty/classes.socketbinding.ts +38 -18
- package/ts_relyingparty/plugins.ts +1 -2
package/changelog.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 2026-10-07 - 19.0.0
|
|
4
|
+
|
|
5
|
+
### Breaking Changes
|
|
6
|
+
|
|
7
|
+
- the relying-party socket binding takes the application's own TypedSocket, of any major (relyingparty)
|
|
8
|
+
- `RelyingPartySocketBinding` named TypedSocket 8 and SmartServe 6 types, so an application whose server runs TypedSocket 9 could not pass its transport. The binding reads only `setServerTag`, `findAllTargetConnectionsByTag` and a peer's upgrade headers; `TRelyingPartySocketConnection`, `TRelyingPartySocketPeer` and `TRelyingPartySocketTransport` are now exactly those structural shapes, and relyingparty imports no TypedSocket.
|
|
9
|
+
- Migration: an application that hands the connections of `connectionsOfSession` back to its TypedSocket (e.g. `removeServerTag`) names its connection type as the second type parameter: `RelyingPartySocketBinding<IUser, ISmartServeConnectionWrapper>`.
|
|
10
|
+
|
|
11
|
+
### Maintenance
|
|
12
|
+
|
|
13
|
+
- release tooling: pnpm 12.8.2, @git.zone/tsbuild ^5.1.2, @git.zone/tsdoc ^3.0.2, @git.zone/tstest ^7.2.0, @types/node 26.6.3
|
|
14
|
+
|
|
3
15
|
## 2026-10-01 - 18.3.1
|
|
4
16
|
|
|
5
17
|
### Fixes
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export const commitinfo = {
|
|
5
5
|
name: '@idp.global/sdk',
|
|
6
|
-
version: '
|
|
6
|
+
version: '19.0.0',
|
|
7
7
|
description: 'Reusable browser and server SDK for idp.global authentication.'
|
|
8
8
|
};
|
|
9
9
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvMDBfY29tbWl0aW5mb19kYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHO0lBQ3hCLElBQUksRUFBRSxpQkFBaUI7SUFDdkIsT0FBTyxFQUFFLFFBQVE7SUFDakIsV0FBVyxFQUFFLGdFQUFnRTtDQUM5RSxDQUFBIn0=
|
|
@@ -1,13 +1,32 @@
|
|
|
1
|
-
import * as plugins from './plugins.js';
|
|
2
1
|
import type { RelyingPartySessions } from './classes.relyingpartysessions.js';
|
|
3
2
|
import type { IRelyingPartySession } from './interfaces.js';
|
|
4
|
-
/**
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
export type TRelyingPartySocketPeer =
|
|
9
|
-
|
|
10
|
-
|
|
3
|
+
/**
|
|
4
|
+
* The WebSocket peer underneath a connection, as far as the binding reads it:
|
|
5
|
+
* the headers its upgrade arrived with. A SmartServe peer of any major fits.
|
|
6
|
+
*/
|
|
7
|
+
export type TRelyingPartySocketPeer = {
|
|
8
|
+
context: {
|
|
9
|
+
headers: {
|
|
10
|
+
get(nameArg: string): string | null;
|
|
11
|
+
};
|
|
12
|
+
};
|
|
13
|
+
};
|
|
14
|
+
/** A server connection as the binding reads it: its peer. A TypedSocket connection wrapper of any major fits. */
|
|
15
|
+
export type TRelyingPartySocketConnection = {
|
|
16
|
+
peer: TRelyingPartySocketPeer;
|
|
17
|
+
};
|
|
18
|
+
/** A connection or its peer; `TypedSocket.setServerTag` takes either. */
|
|
19
|
+
export type TRelyingPartySocketTarget<TConnection extends TRelyingPartySocketConnection = TRelyingPartySocketConnection> = TConnection | TConnection['peer'];
|
|
20
|
+
/**
|
|
21
|
+
* The part of the application's server `TypedSocket` the binding uses. The
|
|
22
|
+
* binding names no TypedSocket or SmartServe version: the application's own
|
|
23
|
+
* transport fits whichever major it runs, and `connectionsOfSession` answers
|
|
24
|
+
* its own connection type.
|
|
25
|
+
*/
|
|
26
|
+
export type TRelyingPartySocketTransport<TConnection extends TRelyingPartySocketConnection = TRelyingPartySocketConnection> = {
|
|
27
|
+
setServerTag(targetArg: TRelyingPartySocketTarget<TConnection>, nameArg: string): void;
|
|
28
|
+
findAllTargetConnectionsByTag(nameArg: string): Promise<TConnection[]>;
|
|
29
|
+
};
|
|
11
30
|
/** What a browser connection is pinned to for its whole life; no cookie and no CSRF token is kept. */
|
|
12
31
|
export interface IRelyingPartyPinnedSession {
|
|
13
32
|
sessionId: string;
|
|
@@ -27,10 +46,10 @@ export type TRelyingPartySocketRegistration = {
|
|
|
27
46
|
registered: false;
|
|
28
47
|
refusal: IRelyingPartySocketRefusal;
|
|
29
48
|
};
|
|
30
|
-
export interface IRelyingPartySocketBindingOptions<TPrincipal extends object | undefined = undefined> {
|
|
49
|
+
export interface IRelyingPartySocketBindingOptions<TPrincipal extends object | undefined = undefined, TConnection extends TRelyingPartySocketConnection = TRelyingPartySocketConnection> {
|
|
31
50
|
sessions: RelyingPartySessions<TPrincipal>;
|
|
32
51
|
/** the transport typedserver created; `undefined` before the server runs */
|
|
33
|
-
transport: () => TRelyingPartySocketTransport | undefined;
|
|
52
|
+
transport: () => TRelyingPartySocketTransport<TConnection> | undefined;
|
|
34
53
|
/** the server-owned tag prefix that finds the connections of a session */
|
|
35
54
|
tagPrefix?: string;
|
|
36
55
|
}
|
|
@@ -43,10 +62,10 @@ export interface IRelyingPartySocketBindingOptions<TPrincipal extends object | u
|
|
|
43
62
|
* request. Connection limits, rate limits and sweeps belong to the
|
|
44
63
|
* application's socket gate.
|
|
45
64
|
*/
|
|
46
|
-
export declare class RelyingPartySocketBinding<TPrincipal extends object | undefined = undefined> {
|
|
65
|
+
export declare class RelyingPartySocketBinding<TPrincipal extends object | undefined = undefined, TConnection extends TRelyingPartySocketConnection = TRelyingPartySocketConnection> {
|
|
47
66
|
#private;
|
|
48
67
|
readonly tagPrefix: string;
|
|
49
|
-
constructor(optionsArg: IRelyingPartySocketBindingOptions<TPrincipal>);
|
|
68
|
+
constructor(optionsArg: IRelyingPartySocketBindingOptions<TPrincipal, TConnection>);
|
|
50
69
|
/** The upgrade headers a connection (or its peer) arrived with. */
|
|
51
70
|
upgradeOf(targetArg: TRelyingPartySocketTarget): {
|
|
52
71
|
origin: string | null;
|
|
@@ -66,7 +85,7 @@ export declare class RelyingPartySocketBinding<TPrincipal extends object | undef
|
|
|
66
85
|
* Tags a connection — its wrapper or its peer — with its session; throws
|
|
67
86
|
* when the transport is not running or the connection is gone.
|
|
68
87
|
*/
|
|
69
|
-
tagConnection(targetArg: TRelyingPartySocketTarget
|
|
88
|
+
tagConnection(targetArg: TRelyingPartySocketTarget<TConnection>, sessionIdArg: string): void;
|
|
70
89
|
/**
|
|
71
90
|
* The pinned session as it stands right now: re-read, live, its principal
|
|
72
91
|
* active and unchanged (and resolved, with `principals.resolve`), touched
|
|
@@ -80,5 +99,5 @@ export declare class RelyingPartySocketBinding<TPrincipal extends object | undef
|
|
|
80
99
|
verifyCsrf(candidateArg: unknown): boolean;
|
|
81
100
|
} | null>;
|
|
82
101
|
/** The live connections of one session, for closing them when it ends. */
|
|
83
|
-
connectionsOfSession(sessionIdArg: string): Promise<readonly
|
|
102
|
+
connectionsOfSession(sessionIdArg: string): Promise<readonly TConnection[]>;
|
|
84
103
|
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import * as plugins from './plugins.js';
|
|
2
1
|
import { sha256, timingSafeEqualString } from './helpers.crypto.js';
|
|
3
2
|
const peerOf = (targetArg) => 'peer' in targetArg ? targetArg.peer : targetArg;
|
|
4
3
|
/**
|
|
@@ -97,4 +96,4 @@ export class RelyingPartySocketBinding {
|
|
|
97
96
|
return transport.findAllTargetConnectionsByTag(this.tagOf(sessionIdArg));
|
|
98
97
|
}
|
|
99
98
|
}
|
|
100
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
99
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5zb2NrZXRiaW5kaW5nLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdHNfcmVseWluZ3BhcnR5L2NsYXNzZXMuc29ja2V0YmluZGluZy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEVBQUUsTUFBTSxFQUFFLHFCQUFxQixFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFnQ3BFLE1BQU0sTUFBTSxHQUFHLENBQUMsU0FBb0MsRUFBMkIsRUFBRSxDQUMvRSxNQUFNLElBQUksU0FBUyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7QUE4Qm5EOzs7Ozs7OztHQVFHO0FBQ0gsTUFBTSxPQUFPLHlCQUF5QjtJQUkzQixTQUFTLENBQW1DO0lBQzVDLFVBQVUsQ0FBOEQ7SUFDakUsU0FBUyxDQUFTO0lBRWxDLFlBQVksVUFBc0U7UUFDaEYsSUFBSSxDQUFDLFNBQVMsR0FBRyxVQUFVLENBQUMsUUFBUSxDQUFDO1FBQ3JDLElBQUksQ0FBQyxVQUFVLEdBQUcsVUFBVSxDQUFDLFNBQVMsQ0FBQztRQUN2QyxJQUFJLENBQUMsU0FBUyxHQUFHLFVBQVUsQ0FBQyxTQUFTLElBQUksaUJBQWlCLENBQUM7SUFDN0QsQ0FBQztJQUVELG1FQUFtRTtJQUM1RCxTQUFTLENBQUMsU0FBb0M7UUFDbkQsTUFBTSxPQUFPLEdBQUcsTUFBTSxDQUFDLFNBQVMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUM7UUFDbEQsT0FBTyxFQUFFLE1BQU0sRUFBRSxPQUFPLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxFQUFFLE1BQU0sRUFBRSxPQUFPLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUM7SUFDMUUsQ0FBQztJQUVEOzs7O09BSUc7SUFDSSxLQUFLLENBQUMsMEJBQTBCLENBQ3JDLFVBQW1CLEVBQ25CLFVBQTREO1FBRTVELElBQUksQ0FBQyxVQUFVLElBQUksT0FB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
|
|
@@ -2,8 +2,7 @@ import * as asyncHooks from 'node:async_hooks';
|
|
|
2
2
|
import * as crypto from 'node:crypto';
|
|
3
3
|
export { asyncHooks, crypto };
|
|
4
4
|
import * as typedrequest from '@api.global/typedrequest';
|
|
5
|
-
|
|
6
|
-
export { typedrequest, typedsocket };
|
|
5
|
+
export { typedrequest };
|
|
7
6
|
import * as nosqldb from '@lossless.org/client/nosqldb';
|
|
8
7
|
export { nosqldb };
|
|
9
8
|
import * as openidClient from 'openid-client';
|
|
@@ -2,10 +2,9 @@ import * as asyncHooks from 'node:async_hooks';
|
|
|
2
2
|
import * as crypto from 'node:crypto';
|
|
3
3
|
export { asyncHooks, crypto };
|
|
4
4
|
import * as typedrequest from '@api.global/typedrequest';
|
|
5
|
-
|
|
6
|
-
export { typedrequest, typedsocket };
|
|
5
|
+
export { typedrequest };
|
|
7
6
|
import * as nosqldb from '@lossless.org/client/nosqldb';
|
|
8
7
|
export { nosqldb };
|
|
9
8
|
import * as openidClient from 'openid-client';
|
|
10
9
|
export { openidClient };
|
|
11
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
10
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGx1Z2lucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3RzX3JlbHlpbmdwYXJ0eS9wbHVnaW5zLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxVQUFVLE1BQU0sa0JBQWtCLENBQUM7QUFDL0MsT0FBTyxLQUFLLE1BQU0sTUFBTSxhQUFhLENBQUM7QUFFdEMsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsQ0FBQztBQUU5QixPQUFPLEtBQUssWUFBWSxNQUFNLDBCQUEwQixDQUFDO0FBRXpELE9BQU8sRUFBRSxZQUFZLEVBQUUsQ0FBQztBQUV4QixPQUFPLEtBQUssT0FBTyxNQUFNLDhCQUE4QixDQUFDO0FBRXhELE9BQU8sRUFBRSxPQUFPLEVBQUUsQ0FBQztBQUVuQixPQUFPLEtBQUssWUFBWSxNQUFNLGVBQWUsQ0FBQztBQUU5QyxPQUFPLEVBQUUsWUFBWSxFQUFFLENBQUMifQ==
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@idp.global/sdk",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "19.0.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Reusable browser and server SDK for idp.global authentication.",
|
|
6
6
|
"type": "module",
|
|
@@ -34,13 +34,13 @@
|
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
36
|
"@api.global/typedserver": "^11.4.0",
|
|
37
|
-
"@git.zone/tsbuild": "^5.
|
|
38
|
-
"@git.zone/tsdoc": "^3.0.
|
|
37
|
+
"@git.zone/tsbuild": "^5.1.2",
|
|
38
|
+
"@git.zone/tsdoc": "^3.0.2",
|
|
39
39
|
"@git.zone/tsrun": "^3.0.2",
|
|
40
|
-
"@git.zone/tstest": "^
|
|
40
|
+
"@git.zone/tstest": "^7.2.0",
|
|
41
41
|
"@lossless.org/client": "^1.0.0",
|
|
42
42
|
"@lossless.org/nosqldb": "10.5.0",
|
|
43
|
-
"@types/node": "26.6.
|
|
43
|
+
"@types/node": "26.6.3"
|
|
44
44
|
},
|
|
45
45
|
"files": [
|
|
46
46
|
"ts/**/*",
|
package/readme.md
CHANGED
|
@@ -660,7 +660,24 @@ then the application's. The two options are not combined.
|
|
|
660
660
|
|
|
661
661
|
**Socket peers.** `RelyingPartySocketBinding.tagConnection` and `upgradeOf` take
|
|
662
662
|
the connection wrapper or the bare SmartServe peer (`TRelyingPartySocketPeer`),
|
|
663
|
-
the two forms `TypedSocket.setServerTag` accepts.
|
|
663
|
+
the two forms `TypedSocket.setServerTag` accepts. The binding names no
|
|
664
|
+
TypedSocket or SmartServe version: its transport, connection and peer types are
|
|
665
|
+
only what it reads (`setServerTag`, `findAllTargetConnectionsByTag`, a peer's
|
|
666
|
+
upgrade headers), so the application's own server `TypedSocket` fits whichever
|
|
667
|
+
major it runs. Name the application's connection type as the second type
|
|
668
|
+
parameter and `connectionsOfSession` answers it:
|
|
669
|
+
|
|
670
|
+
```ts
|
|
671
|
+
import type { ISmartServeConnectionWrapper } from '@api.global/typedsocket';
|
|
672
|
+
|
|
673
|
+
const binding = new RelyingPartySocketBinding<IUser, ISmartServeConnectionWrapper>({
|
|
674
|
+
sessions,
|
|
675
|
+
transport: () => typedserver.typedsocket,
|
|
676
|
+
});
|
|
677
|
+
for (const connection of await binding.connectionsOfSession(sessionId)) {
|
|
678
|
+
typedserver.removeServerTag(connection, binding.tagOf(sessionId));
|
|
679
|
+
}
|
|
680
|
+
```
|
|
664
681
|
|
|
665
682
|
### Relying-Party API Surface
|
|
666
683
|
|
package/ts/00_commitinfo_data.ts
CHANGED
|
@@ -1,21 +1,35 @@
|
|
|
1
|
-
import * as plugins from './plugins.js';
|
|
2
1
|
import type { RelyingPartySessions } from './classes.relyingpartysessions.js';
|
|
3
2
|
import { sha256, timingSafeEqualString } from './helpers.crypto.js';
|
|
4
3
|
import type { IRelyingPartySession } from './interfaces.js';
|
|
5
4
|
|
|
6
|
-
/**
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
5
|
+
/**
|
|
6
|
+
* The WebSocket peer underneath a connection, as far as the binding reads it:
|
|
7
|
+
* the headers its upgrade arrived with. A SmartServe peer of any major fits.
|
|
8
|
+
*/
|
|
9
|
+
export type TRelyingPartySocketPeer = {
|
|
10
|
+
context: { headers: { get(nameArg: string): string | null } };
|
|
11
|
+
};
|
|
11
12
|
|
|
12
|
-
|
|
13
|
+
/** A server connection as the binding reads it: its peer. A TypedSocket connection wrapper of any major fits. */
|
|
14
|
+
export type TRelyingPartySocketConnection = {
|
|
15
|
+
peer: TRelyingPartySocketPeer;
|
|
16
|
+
};
|
|
13
17
|
|
|
14
|
-
/**
|
|
15
|
-
export type
|
|
18
|
+
/** A connection or its peer; `TypedSocket.setServerTag` takes either. */
|
|
19
|
+
export type TRelyingPartySocketTarget<TConnection extends TRelyingPartySocketConnection = TRelyingPartySocketConnection> =
|
|
20
|
+
| TConnection
|
|
21
|
+
| TConnection['peer'];
|
|
16
22
|
|
|
17
|
-
/**
|
|
18
|
-
|
|
23
|
+
/**
|
|
24
|
+
* The part of the application's server `TypedSocket` the binding uses. The
|
|
25
|
+
* binding names no TypedSocket or SmartServe version: the application's own
|
|
26
|
+
* transport fits whichever major it runs, and `connectionsOfSession` answers
|
|
27
|
+
* its own connection type.
|
|
28
|
+
*/
|
|
29
|
+
export type TRelyingPartySocketTransport<TConnection extends TRelyingPartySocketConnection = TRelyingPartySocketConnection> = {
|
|
30
|
+
setServerTag(targetArg: TRelyingPartySocketTarget<TConnection>, nameArg: string): void;
|
|
31
|
+
findAllTargetConnectionsByTag(nameArg: string): Promise<TConnection[]>;
|
|
32
|
+
};
|
|
19
33
|
|
|
20
34
|
const peerOf = (targetArg: TRelyingPartySocketTarget): TRelyingPartySocketPeer =>
|
|
21
35
|
'peer' in targetArg ? targetArg.peer : targetArg;
|
|
@@ -37,10 +51,13 @@ export type TRelyingPartySocketRegistration =
|
|
|
37
51
|
| { registered: true; pinned: IRelyingPartyPinnedSession; expiresAt: number }
|
|
38
52
|
| { registered: false; refusal: IRelyingPartySocketRefusal };
|
|
39
53
|
|
|
40
|
-
export interface IRelyingPartySocketBindingOptions<
|
|
54
|
+
export interface IRelyingPartySocketBindingOptions<
|
|
55
|
+
TPrincipal extends object | undefined = undefined,
|
|
56
|
+
TConnection extends TRelyingPartySocketConnection = TRelyingPartySocketConnection,
|
|
57
|
+
> {
|
|
41
58
|
sessions: RelyingPartySessions<TPrincipal>;
|
|
42
59
|
/** the transport typedserver created; `undefined` before the server runs */
|
|
43
|
-
transport: () => TRelyingPartySocketTransport | undefined;
|
|
60
|
+
transport: () => TRelyingPartySocketTransport<TConnection> | undefined;
|
|
44
61
|
/** the server-owned tag prefix that finds the connections of a session */
|
|
45
62
|
tagPrefix?: string;
|
|
46
63
|
}
|
|
@@ -54,12 +71,15 @@ export interface IRelyingPartySocketBindingOptions<TPrincipal extends object | u
|
|
|
54
71
|
* request. Connection limits, rate limits and sweeps belong to the
|
|
55
72
|
* application's socket gate.
|
|
56
73
|
*/
|
|
57
|
-
export class RelyingPartySocketBinding<
|
|
74
|
+
export class RelyingPartySocketBinding<
|
|
75
|
+
TPrincipal extends object | undefined = undefined,
|
|
76
|
+
TConnection extends TRelyingPartySocketConnection = TRelyingPartySocketConnection,
|
|
77
|
+
> {
|
|
58
78
|
readonly #sessions: RelyingPartySessions<TPrincipal>;
|
|
59
|
-
readonly #transport: () => TRelyingPartySocketTransport | undefined;
|
|
79
|
+
readonly #transport: () => TRelyingPartySocketTransport<TConnection> | undefined;
|
|
60
80
|
public readonly tagPrefix: string;
|
|
61
81
|
|
|
62
|
-
constructor(optionsArg: IRelyingPartySocketBindingOptions<TPrincipal>) {
|
|
82
|
+
constructor(optionsArg: IRelyingPartySocketBindingOptions<TPrincipal, TConnection>) {
|
|
63
83
|
this.#sessions = optionsArg.sessions;
|
|
64
84
|
this.#transport = optionsArg.transport;
|
|
65
85
|
this.tagPrefix = optionsArg.tagPrefix ?? 'idp_rp_session:';
|
|
@@ -112,7 +132,7 @@ export class RelyingPartySocketBinding<TPrincipal extends object | undefined = u
|
|
|
112
132
|
* Tags a connection — its wrapper or its peer — with its session; throws
|
|
113
133
|
* when the transport is not running or the connection is gone.
|
|
114
134
|
*/
|
|
115
|
-
public tagConnection(targetArg: TRelyingPartySocketTarget
|
|
135
|
+
public tagConnection(targetArg: TRelyingPartySocketTarget<TConnection>, sessionIdArg: string): void {
|
|
116
136
|
const transport = this.#transport();
|
|
117
137
|
if (!transport) {
|
|
118
138
|
throw new Error('The socket transport is not running');
|
|
@@ -146,7 +166,7 @@ export class RelyingPartySocketBinding<TPrincipal extends object | undefined = u
|
|
|
146
166
|
}
|
|
147
167
|
|
|
148
168
|
/** The live connections of one session, for closing them when it ends. */
|
|
149
|
-
public async connectionsOfSession(sessionIdArg: string): Promise<readonly
|
|
169
|
+
public async connectionsOfSession(sessionIdArg: string): Promise<readonly TConnection[]> {
|
|
150
170
|
const transport = this.#transport();
|
|
151
171
|
if (!transport) {
|
|
152
172
|
return [];
|
|
@@ -4,9 +4,8 @@ import * as crypto from 'node:crypto';
|
|
|
4
4
|
export { asyncHooks, crypto };
|
|
5
5
|
|
|
6
6
|
import * as typedrequest from '@api.global/typedrequest';
|
|
7
|
-
import * as typedsocket from '@api.global/typedsocket';
|
|
8
7
|
|
|
9
|
-
export { typedrequest
|
|
8
|
+
export { typedrequest };
|
|
10
9
|
|
|
11
10
|
import * as nosqldb from '@lossless.org/client/nosqldb';
|
|
12
11
|
|