@insureco/bio 0.6.0 → 0.9.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/dist/{chunk-PLN6QPED.mjs → chunk-CKHMGUDP.mjs} +41 -0
- package/dist/chunk-UBURAGWI.mjs +154 -0
- package/dist/graph.d.mts +73 -1
- package/dist/graph.d.ts +73 -1
- package/dist/graph.js +41 -0
- package/dist/graph.mjs +1 -1
- package/dist/index.d.mts +14 -4
- package/dist/index.d.ts +14 -4
- package/dist/index.js +217 -5
- package/dist/index.mjs +28 -6
- package/dist/passport-react.d.mts +27 -0
- package/dist/passport-react.d.ts +27 -0
- package/dist/passport-react.js +115 -0
- package/dist/passport-react.mjs +90 -0
- package/dist/passport-types-bPgjNxv-.d.mts +79 -0
- package/dist/passport-types-bPgjNxv-.d.ts +79 -0
- package/dist/passport.d.mts +70 -0
- package/dist/passport.d.ts +70 -0
- package/dist/passport.js +180 -0
- package/dist/passport.mjs +6 -0
- package/dist/{types-CJe1FP61.d.mts → types-Cm0uZYaQ.d.mts} +29 -3
- package/dist/{types-CJe1FP61.d.ts → types-Cm0uZYaQ.d.ts} +29 -3
- package/dist/users.d.mts +1 -1
- package/dist/users.d.ts +1 -1
- package/dist/users.js +1 -0
- package/dist/users.mjs +1 -0
- package/package.json +24 -2
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/** The full Passport identity object pushed via WebSocket */
|
|
2
|
+
interface Passport {
|
|
3
|
+
bioId: string;
|
|
4
|
+
email: string;
|
|
5
|
+
firstName: string;
|
|
6
|
+
lastName: string;
|
|
7
|
+
orgSlug: string;
|
|
8
|
+
orgId: string;
|
|
9
|
+
roles: string[];
|
|
10
|
+
villages: PassportVillage[];
|
|
11
|
+
serviceGrants: PassportServiceGrant[];
|
|
12
|
+
crossOrgPermissions: PassportCrossOrgPermission[];
|
|
13
|
+
session: PassportSession;
|
|
14
|
+
}
|
|
15
|
+
interface PassportVillage {
|
|
16
|
+
slug: string;
|
|
17
|
+
name: string;
|
|
18
|
+
role: 'member' | 'admin' | 'owner';
|
|
19
|
+
}
|
|
20
|
+
interface PassportServiceGrant {
|
|
21
|
+
service: string;
|
|
22
|
+
scopes: string[];
|
|
23
|
+
grantedAt: string;
|
|
24
|
+
}
|
|
25
|
+
interface PassportCrossOrgPermission {
|
|
26
|
+
targetOrgSlug: string;
|
|
27
|
+
modules: string[];
|
|
28
|
+
}
|
|
29
|
+
interface PassportSession {
|
|
30
|
+
issuedAt: string;
|
|
31
|
+
lastSeen: string;
|
|
32
|
+
connectedServices: string[];
|
|
33
|
+
}
|
|
34
|
+
/** Interface for token refresh — accepts any object with a refreshToken method */
|
|
35
|
+
interface PassportTokenRefresher {
|
|
36
|
+
refreshToken: (refreshToken: string) => Promise<{
|
|
37
|
+
access_token: string;
|
|
38
|
+
refresh_token?: string;
|
|
39
|
+
}>;
|
|
40
|
+
}
|
|
41
|
+
/** Configuration for PassportClient */
|
|
42
|
+
interface PassportClientConfig {
|
|
43
|
+
/** Bio-ID base URL (e.g. https://bio.insureco.io) */
|
|
44
|
+
bioIdUrl: string;
|
|
45
|
+
/** Access token for authentication */
|
|
46
|
+
accessToken: string;
|
|
47
|
+
/** Service name sent as ?service= query param */
|
|
48
|
+
service?: string;
|
|
49
|
+
/** Auto-reconnect on disconnect (default: true) */
|
|
50
|
+
autoReconnect?: boolean;
|
|
51
|
+
/** Max reconnect delay in ms (default: 30000) */
|
|
52
|
+
maxReconnectDelay?: number;
|
|
53
|
+
/** Optional refresh token for auto-refresh on 4003 close */
|
|
54
|
+
refreshToken?: string;
|
|
55
|
+
/** Callback when tokens are refreshed (so app can persist new tokens) */
|
|
56
|
+
onTokenRefresh?: (tokens: {
|
|
57
|
+
access_token: string;
|
|
58
|
+
refresh_token?: string;
|
|
59
|
+
}) => void;
|
|
60
|
+
/** Token refresher (e.g. BioAuth instance) — required if refreshToken is set */
|
|
61
|
+
bioAuth?: PassportTokenRefresher;
|
|
62
|
+
}
|
|
63
|
+
/** Events emitted by the passport socket */
|
|
64
|
+
type PassportEventType = 'identity' | 'passport_updated' | 'revoked';
|
|
65
|
+
/** Message received from the passport WebSocket */
|
|
66
|
+
interface PassportMessage {
|
|
67
|
+
type: PassportEventType;
|
|
68
|
+
passport?: Passport;
|
|
69
|
+
}
|
|
70
|
+
/** Status of the passport connection */
|
|
71
|
+
type PassportStatus = 'connecting' | 'connected' | 'disconnected' | 'error';
|
|
72
|
+
/** Branding config from passport (optional) */
|
|
73
|
+
interface PassportBranding {
|
|
74
|
+
logoUrl?: string;
|
|
75
|
+
primaryColor?: string;
|
|
76
|
+
appName?: string;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export type { Passport as P, PassportStatus as a, PassportBranding as b, PassportClientConfig as c, PassportCrossOrgPermission as d, PassportEventType as e, PassportMessage as f, PassportServiceGrant as g, PassportSession as h, PassportTokenRefresher as i, PassportVillage as j };
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { c as PassportClientConfig, P as Passport, a as PassportStatus } from './passport-types-bPgjNxv-.mjs';
|
|
2
|
+
export { b as PassportBranding, d as PassportCrossOrgPermission, e as PassportEventType, f as PassportMessage, g as PassportServiceGrant, h as PassportSession, i as PassportTokenRefresher, j as PassportVillage } from './passport-types-bPgjNxv-.mjs';
|
|
3
|
+
|
|
4
|
+
type PassportEventHandler = (passport: Passport | null) => void;
|
|
5
|
+
type StatusEventHandler = (status: PassportStatus) => void;
|
|
6
|
+
type ErrorEventHandler = (error: Error) => void;
|
|
7
|
+
interface PassportEventMap {
|
|
8
|
+
identity: PassportEventHandler;
|
|
9
|
+
passport_updated: PassportEventHandler;
|
|
10
|
+
revoked: () => void;
|
|
11
|
+
connected: StatusEventHandler;
|
|
12
|
+
disconnected: StatusEventHandler;
|
|
13
|
+
error: ErrorEventHandler;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Client for the Bio-ID passport WebSocket.
|
|
17
|
+
*
|
|
18
|
+
* Connects to the passport endpoint and emits events when the user's
|
|
19
|
+
* identity, permissions, or session change in real time.
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* import { PassportClient } from '@insureco/bio/passport'
|
|
23
|
+
*
|
|
24
|
+
* const client = new PassportClient({
|
|
25
|
+
* bioIdUrl: 'https://bio.insureco.io',
|
|
26
|
+
* accessToken: userToken,
|
|
27
|
+
* service: 'my-service',
|
|
28
|
+
* })
|
|
29
|
+
*
|
|
30
|
+
* client.on('identity', (passport) => {
|
|
31
|
+
* console.log('Logged in as', passport?.firstName)
|
|
32
|
+
* })
|
|
33
|
+
*
|
|
34
|
+
* client.on('passport_updated', (passport) => {
|
|
35
|
+
* console.log('Passport updated', passport?.roles)
|
|
36
|
+
* })
|
|
37
|
+
*
|
|
38
|
+
* client.connect()
|
|
39
|
+
*/
|
|
40
|
+
declare class PassportClient {
|
|
41
|
+
private readonly config;
|
|
42
|
+
private ws;
|
|
43
|
+
private _passport;
|
|
44
|
+
private _status;
|
|
45
|
+
private reconnectAttempt;
|
|
46
|
+
private reconnectTimer;
|
|
47
|
+
private listeners;
|
|
48
|
+
private closed;
|
|
49
|
+
constructor(config: PassportClientConfig);
|
|
50
|
+
/** Current passport object (null until first identity message) */
|
|
51
|
+
get passport(): Passport | null;
|
|
52
|
+
/** Current connection status */
|
|
53
|
+
get status(): PassportStatus;
|
|
54
|
+
/** Connect to the passport WebSocket */
|
|
55
|
+
connect(): void;
|
|
56
|
+
/** Subscribe to an event */
|
|
57
|
+
on<K extends keyof PassportEventMap>(event: K, handler: PassportEventMap[K]): void;
|
|
58
|
+
/** Unsubscribe from an event */
|
|
59
|
+
off<K extends keyof PassportEventMap>(event: K, handler: PassportEventMap[K]): void;
|
|
60
|
+
/** Disconnect and stop reconnecting */
|
|
61
|
+
close(): void;
|
|
62
|
+
/** Update access token (e.g. after refresh) and reconnect */
|
|
63
|
+
updateToken(accessToken: string): void;
|
|
64
|
+
private handleTokenRefresh;
|
|
65
|
+
private setStatus;
|
|
66
|
+
private emit;
|
|
67
|
+
private scheduleReconnect;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export { Passport, PassportClient, PassportClientConfig, PassportStatus };
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { c as PassportClientConfig, P as Passport, a as PassportStatus } from './passport-types-bPgjNxv-.js';
|
|
2
|
+
export { b as PassportBranding, d as PassportCrossOrgPermission, e as PassportEventType, f as PassportMessage, g as PassportServiceGrant, h as PassportSession, i as PassportTokenRefresher, j as PassportVillage } from './passport-types-bPgjNxv-.js';
|
|
3
|
+
|
|
4
|
+
type PassportEventHandler = (passport: Passport | null) => void;
|
|
5
|
+
type StatusEventHandler = (status: PassportStatus) => void;
|
|
6
|
+
type ErrorEventHandler = (error: Error) => void;
|
|
7
|
+
interface PassportEventMap {
|
|
8
|
+
identity: PassportEventHandler;
|
|
9
|
+
passport_updated: PassportEventHandler;
|
|
10
|
+
revoked: () => void;
|
|
11
|
+
connected: StatusEventHandler;
|
|
12
|
+
disconnected: StatusEventHandler;
|
|
13
|
+
error: ErrorEventHandler;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Client for the Bio-ID passport WebSocket.
|
|
17
|
+
*
|
|
18
|
+
* Connects to the passport endpoint and emits events when the user's
|
|
19
|
+
* identity, permissions, or session change in real time.
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* import { PassportClient } from '@insureco/bio/passport'
|
|
23
|
+
*
|
|
24
|
+
* const client = new PassportClient({
|
|
25
|
+
* bioIdUrl: 'https://bio.insureco.io',
|
|
26
|
+
* accessToken: userToken,
|
|
27
|
+
* service: 'my-service',
|
|
28
|
+
* })
|
|
29
|
+
*
|
|
30
|
+
* client.on('identity', (passport) => {
|
|
31
|
+
* console.log('Logged in as', passport?.firstName)
|
|
32
|
+
* })
|
|
33
|
+
*
|
|
34
|
+
* client.on('passport_updated', (passport) => {
|
|
35
|
+
* console.log('Passport updated', passport?.roles)
|
|
36
|
+
* })
|
|
37
|
+
*
|
|
38
|
+
* client.connect()
|
|
39
|
+
*/
|
|
40
|
+
declare class PassportClient {
|
|
41
|
+
private readonly config;
|
|
42
|
+
private ws;
|
|
43
|
+
private _passport;
|
|
44
|
+
private _status;
|
|
45
|
+
private reconnectAttempt;
|
|
46
|
+
private reconnectTimer;
|
|
47
|
+
private listeners;
|
|
48
|
+
private closed;
|
|
49
|
+
constructor(config: PassportClientConfig);
|
|
50
|
+
/** Current passport object (null until first identity message) */
|
|
51
|
+
get passport(): Passport | null;
|
|
52
|
+
/** Current connection status */
|
|
53
|
+
get status(): PassportStatus;
|
|
54
|
+
/** Connect to the passport WebSocket */
|
|
55
|
+
connect(): void;
|
|
56
|
+
/** Subscribe to an event */
|
|
57
|
+
on<K extends keyof PassportEventMap>(event: K, handler: PassportEventMap[K]): void;
|
|
58
|
+
/** Unsubscribe from an event */
|
|
59
|
+
off<K extends keyof PassportEventMap>(event: K, handler: PassportEventMap[K]): void;
|
|
60
|
+
/** Disconnect and stop reconnecting */
|
|
61
|
+
close(): void;
|
|
62
|
+
/** Update access token (e.g. after refresh) and reconnect */
|
|
63
|
+
updateToken(accessToken: string): void;
|
|
64
|
+
private handleTokenRefresh;
|
|
65
|
+
private setStatus;
|
|
66
|
+
private emit;
|
|
67
|
+
private scheduleReconnect;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export { Passport, PassportClient, PassportClientConfig, PassportStatus };
|
package/dist/passport.js
ADDED
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/passport.ts
|
|
21
|
+
var passport_exports = {};
|
|
22
|
+
__export(passport_exports, {
|
|
23
|
+
PassportClient: () => PassportClient
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(passport_exports);
|
|
26
|
+
|
|
27
|
+
// src/passport-client.ts
|
|
28
|
+
var PassportClient = class {
|
|
29
|
+
config;
|
|
30
|
+
ws = null;
|
|
31
|
+
_passport = null;
|
|
32
|
+
_status = "disconnected";
|
|
33
|
+
reconnectAttempt = 0;
|
|
34
|
+
reconnectTimer = null;
|
|
35
|
+
listeners = /* @__PURE__ */ new Map();
|
|
36
|
+
closed = false;
|
|
37
|
+
constructor(config) {
|
|
38
|
+
this.config = {
|
|
39
|
+
autoReconnect: true,
|
|
40
|
+
maxReconnectDelay: 3e4,
|
|
41
|
+
...config
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
/** Current passport object (null until first identity message) */
|
|
45
|
+
get passport() {
|
|
46
|
+
return this._passport;
|
|
47
|
+
}
|
|
48
|
+
/** Current connection status */
|
|
49
|
+
get status() {
|
|
50
|
+
return this._status;
|
|
51
|
+
}
|
|
52
|
+
/** Connect to the passport WebSocket */
|
|
53
|
+
connect() {
|
|
54
|
+
if (this.closed) return;
|
|
55
|
+
this.setStatus("connecting");
|
|
56
|
+
const url = new URL("/passport", this.config.bioIdUrl.replace(/^http/, "ws"));
|
|
57
|
+
url.searchParams.set("token", this.config.accessToken);
|
|
58
|
+
url.searchParams.set("version", "1");
|
|
59
|
+
if (this.config.service) {
|
|
60
|
+
url.searchParams.set("service", this.config.service);
|
|
61
|
+
}
|
|
62
|
+
this.ws = new WebSocket(url.toString());
|
|
63
|
+
this.ws.onopen = () => {
|
|
64
|
+
this.reconnectAttempt = 0;
|
|
65
|
+
this.setStatus("connected");
|
|
66
|
+
this.emit("connected", this._status);
|
|
67
|
+
};
|
|
68
|
+
this.ws.onmessage = (event) => {
|
|
69
|
+
try {
|
|
70
|
+
const data = JSON.parse(
|
|
71
|
+
typeof event.data === "string" ? event.data : ""
|
|
72
|
+
);
|
|
73
|
+
if (data.type === "identity" || data.type === "passport_updated") {
|
|
74
|
+
this._passport = data.passport ?? null;
|
|
75
|
+
this.emit(data.type, this._passport);
|
|
76
|
+
} else if (data.type === "revoked") {
|
|
77
|
+
this._passport = null;
|
|
78
|
+
this.emit("revoked");
|
|
79
|
+
}
|
|
80
|
+
} catch {
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
this.ws.onclose = (event) => {
|
|
84
|
+
this.setStatus("disconnected");
|
|
85
|
+
this.emit("disconnected", this._status);
|
|
86
|
+
if (event?.code === 4003 && this.config.refreshToken && this.config.bioAuth) {
|
|
87
|
+
this.handleTokenRefresh();
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
this.scheduleReconnect();
|
|
91
|
+
};
|
|
92
|
+
this.ws.onerror = () => {
|
|
93
|
+
const error = new Error("Passport WebSocket error");
|
|
94
|
+
this.emit("error", error);
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
/** Subscribe to an event */
|
|
98
|
+
on(event, handler) {
|
|
99
|
+
if (!this.listeners.has(event)) {
|
|
100
|
+
this.listeners.set(event, /* @__PURE__ */ new Set());
|
|
101
|
+
}
|
|
102
|
+
this.listeners.get(event).add(handler);
|
|
103
|
+
}
|
|
104
|
+
/** Unsubscribe from an event */
|
|
105
|
+
off(event, handler) {
|
|
106
|
+
this.listeners.get(event)?.delete(handler);
|
|
107
|
+
}
|
|
108
|
+
/** Disconnect and stop reconnecting */
|
|
109
|
+
close() {
|
|
110
|
+
this.closed = true;
|
|
111
|
+
if (this.reconnectTimer) {
|
|
112
|
+
clearTimeout(this.reconnectTimer);
|
|
113
|
+
this.reconnectTimer = null;
|
|
114
|
+
}
|
|
115
|
+
if (this.ws) {
|
|
116
|
+
this.ws.onclose = null;
|
|
117
|
+
this.ws.close();
|
|
118
|
+
this.ws = null;
|
|
119
|
+
}
|
|
120
|
+
this.setStatus("disconnected");
|
|
121
|
+
}
|
|
122
|
+
/** Update access token (e.g. after refresh) and reconnect */
|
|
123
|
+
updateToken(accessToken) {
|
|
124
|
+
this.config.accessToken = accessToken;
|
|
125
|
+
if (this.ws) {
|
|
126
|
+
this.ws.onclose = null;
|
|
127
|
+
this.ws.close();
|
|
128
|
+
this.ws = null;
|
|
129
|
+
}
|
|
130
|
+
this.reconnectAttempt = 0;
|
|
131
|
+
this.connect();
|
|
132
|
+
}
|
|
133
|
+
async handleTokenRefresh() {
|
|
134
|
+
if (!this.config.refreshToken || !this.config.bioAuth) return;
|
|
135
|
+
try {
|
|
136
|
+
const tokens = await this.config.bioAuth.refreshToken(this.config.refreshToken);
|
|
137
|
+
this.config.accessToken = tokens.access_token;
|
|
138
|
+
if (tokens.refresh_token) {
|
|
139
|
+
this.config.refreshToken = tokens.refresh_token;
|
|
140
|
+
}
|
|
141
|
+
if (this.config.onTokenRefresh) {
|
|
142
|
+
this.config.onTokenRefresh(tokens);
|
|
143
|
+
}
|
|
144
|
+
this.reconnectAttempt = 0;
|
|
145
|
+
this.connect();
|
|
146
|
+
} catch {
|
|
147
|
+
this.emit("error", new Error("Token refresh failed"));
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
setStatus(status) {
|
|
151
|
+
this._status = status;
|
|
152
|
+
}
|
|
153
|
+
emit(event, ...args) {
|
|
154
|
+
const handlers = this.listeners.get(event);
|
|
155
|
+
if (handlers) {
|
|
156
|
+
for (const handler of handlers) {
|
|
157
|
+
try {
|
|
158
|
+
handler(...args);
|
|
159
|
+
} catch {
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
scheduleReconnect() {
|
|
165
|
+
if (this.closed || !this.config.autoReconnect) return;
|
|
166
|
+
const delay = Math.min(
|
|
167
|
+
1e3 * Math.pow(2, this.reconnectAttempt),
|
|
168
|
+
this.config.maxReconnectDelay ?? 3e4
|
|
169
|
+
);
|
|
170
|
+
this.reconnectAttempt++;
|
|
171
|
+
this.reconnectTimer = setTimeout(() => {
|
|
172
|
+
this.reconnectTimer = null;
|
|
173
|
+
this.connect();
|
|
174
|
+
}, delay);
|
|
175
|
+
}
|
|
176
|
+
};
|
|
177
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
178
|
+
0 && (module.exports = {
|
|
179
|
+
PassportClient
|
|
180
|
+
});
|
|
@@ -35,6 +35,15 @@ interface AuthorizeOptions {
|
|
|
35
35
|
/** Optional org slug to pre-select during authorization (for multi-org users) */
|
|
36
36
|
organization?: string;
|
|
37
37
|
}
|
|
38
|
+
/** Options for silent authentication (prompt=none) */
|
|
39
|
+
interface SilentAuthOptions {
|
|
40
|
+
/** Callback URL where Bio-ID redirects after silent auth */
|
|
41
|
+
redirectUri: string;
|
|
42
|
+
/** OAuth scopes to request (default: ['openid', 'profile', 'email']) */
|
|
43
|
+
scopes?: string[];
|
|
44
|
+
/** CSRF state parameter (auto-generated if not provided) */
|
|
45
|
+
state?: string;
|
|
46
|
+
}
|
|
38
47
|
/** Result from getAuthorizationUrl() */
|
|
39
48
|
interface AuthorizeResult {
|
|
40
49
|
/** Full authorization URL to redirect the user to */
|
|
@@ -266,19 +275,32 @@ interface OrgMemberFilters {
|
|
|
266
275
|
modules?: string[];
|
|
267
276
|
/** Only return members with these roles */
|
|
268
277
|
roles?: string[];
|
|
278
|
+
/** Service ID for role-taxonomy resolution (e.g. 'iifs-collections') */
|
|
279
|
+
service?: string;
|
|
269
280
|
/** Max results (default: 50) */
|
|
270
281
|
limit?: number;
|
|
271
282
|
/** Page number for pagination (default: 1) */
|
|
272
283
|
page?: number;
|
|
273
284
|
}
|
|
285
|
+
/** A role within a service's taxonomy, resolved when querying with `service` filter */
|
|
286
|
+
interface ServiceRole {
|
|
287
|
+
/** Role ID within the service taxonomy (e.g. 'collections:manager') */
|
|
288
|
+
id: string;
|
|
289
|
+
/** Human-readable label (e.g. 'Collections Manager') */
|
|
290
|
+
label: string;
|
|
291
|
+
}
|
|
274
292
|
/** A member as returned by GET /api/v2/users or GET /api/orgs/[slug]/members */
|
|
275
293
|
interface OrgMember {
|
|
276
294
|
bioId: string;
|
|
277
295
|
email: string;
|
|
278
296
|
name: string;
|
|
297
|
+
/** Which org this user belongs to */
|
|
298
|
+
orgSlug?: string;
|
|
279
299
|
jobTitle?: string;
|
|
280
300
|
enabled_modules: string[];
|
|
281
301
|
roles?: string[];
|
|
302
|
+
/** Roles within the querying service's taxonomy (present when `service` filter is used) */
|
|
303
|
+
serviceRoles?: ServiceRole[];
|
|
282
304
|
}
|
|
283
305
|
/** Paginated response from the user access endpoints */
|
|
284
306
|
interface OrgMembersResult {
|
|
@@ -324,8 +346,12 @@ interface EmbedSignupParams {
|
|
|
324
346
|
email: string;
|
|
325
347
|
/** User password */
|
|
326
348
|
password: string;
|
|
327
|
-
/**
|
|
328
|
-
|
|
349
|
+
/** First name */
|
|
350
|
+
firstName: string;
|
|
351
|
+
/** Last name */
|
|
352
|
+
lastName: string;
|
|
353
|
+
/** Optional org slug to pre-assign the user to an existing org */
|
|
354
|
+
orgSlug?: string;
|
|
329
355
|
/** Optional invite token for org-scoped signups */
|
|
330
356
|
inviteToken?: string;
|
|
331
357
|
}
|
|
@@ -393,4 +419,4 @@ interface EmbedAuthResult {
|
|
|
393
419
|
branding?: EmbedBranding;
|
|
394
420
|
}
|
|
395
421
|
|
|
396
|
-
export type { AuthorizeOptions as A,
|
|
422
|
+
export type { AuthorizeOptions as A, BioUsersConfig as B, CreateDepartmentData as C, ServiceRole as D, EmbedClientConfig as E, IntrospectResult as I, JWKSVerifyOptions as J, OrgMemberFilters as O, SilentAuthOptions as S, TokenResponse as T, UserFilters as U, VerifyOptions as V, OrgMembersResult as a, BioAuthConfig as b, AuthorizeResult as c, BioUser as d, BioAdminConfig as e, UpdateUserData as f, BioDepartment as g, BioRole as h, CreateRoleData as i, BioOAuthClient as j, CreateClientData as k, EmbedLoginParams as l, EmbedAuthResult as m, EmbedSignupParams as n, EmbedMagicLinkParams as o, EmbedVerifyParams as p, EmbedRefreshParams as q, EmbedLogoutParams as r, BioTokenPayload as s, AdminResponse as t, BioAddress as u, BioClientTokenPayload as v, BioMessaging as w, EmbedBranding as x, EmbedUser as y, OrgMember as z };
|
|
@@ -35,6 +35,15 @@ interface AuthorizeOptions {
|
|
|
35
35
|
/** Optional org slug to pre-select during authorization (for multi-org users) */
|
|
36
36
|
organization?: string;
|
|
37
37
|
}
|
|
38
|
+
/** Options for silent authentication (prompt=none) */
|
|
39
|
+
interface SilentAuthOptions {
|
|
40
|
+
/** Callback URL where Bio-ID redirects after silent auth */
|
|
41
|
+
redirectUri: string;
|
|
42
|
+
/** OAuth scopes to request (default: ['openid', 'profile', 'email']) */
|
|
43
|
+
scopes?: string[];
|
|
44
|
+
/** CSRF state parameter (auto-generated if not provided) */
|
|
45
|
+
state?: string;
|
|
46
|
+
}
|
|
38
47
|
/** Result from getAuthorizationUrl() */
|
|
39
48
|
interface AuthorizeResult {
|
|
40
49
|
/** Full authorization URL to redirect the user to */
|
|
@@ -266,19 +275,32 @@ interface OrgMemberFilters {
|
|
|
266
275
|
modules?: string[];
|
|
267
276
|
/** Only return members with these roles */
|
|
268
277
|
roles?: string[];
|
|
278
|
+
/** Service ID for role-taxonomy resolution (e.g. 'iifs-collections') */
|
|
279
|
+
service?: string;
|
|
269
280
|
/** Max results (default: 50) */
|
|
270
281
|
limit?: number;
|
|
271
282
|
/** Page number for pagination (default: 1) */
|
|
272
283
|
page?: number;
|
|
273
284
|
}
|
|
285
|
+
/** A role within a service's taxonomy, resolved when querying with `service` filter */
|
|
286
|
+
interface ServiceRole {
|
|
287
|
+
/** Role ID within the service taxonomy (e.g. 'collections:manager') */
|
|
288
|
+
id: string;
|
|
289
|
+
/** Human-readable label (e.g. 'Collections Manager') */
|
|
290
|
+
label: string;
|
|
291
|
+
}
|
|
274
292
|
/** A member as returned by GET /api/v2/users or GET /api/orgs/[slug]/members */
|
|
275
293
|
interface OrgMember {
|
|
276
294
|
bioId: string;
|
|
277
295
|
email: string;
|
|
278
296
|
name: string;
|
|
297
|
+
/** Which org this user belongs to */
|
|
298
|
+
orgSlug?: string;
|
|
279
299
|
jobTitle?: string;
|
|
280
300
|
enabled_modules: string[];
|
|
281
301
|
roles?: string[];
|
|
302
|
+
/** Roles within the querying service's taxonomy (present when `service` filter is used) */
|
|
303
|
+
serviceRoles?: ServiceRole[];
|
|
282
304
|
}
|
|
283
305
|
/** Paginated response from the user access endpoints */
|
|
284
306
|
interface OrgMembersResult {
|
|
@@ -324,8 +346,12 @@ interface EmbedSignupParams {
|
|
|
324
346
|
email: string;
|
|
325
347
|
/** User password */
|
|
326
348
|
password: string;
|
|
327
|
-
/**
|
|
328
|
-
|
|
349
|
+
/** First name */
|
|
350
|
+
firstName: string;
|
|
351
|
+
/** Last name */
|
|
352
|
+
lastName: string;
|
|
353
|
+
/** Optional org slug to pre-assign the user to an existing org */
|
|
354
|
+
orgSlug?: string;
|
|
329
355
|
/** Optional invite token for org-scoped signups */
|
|
330
356
|
inviteToken?: string;
|
|
331
357
|
}
|
|
@@ -393,4 +419,4 @@ interface EmbedAuthResult {
|
|
|
393
419
|
branding?: EmbedBranding;
|
|
394
420
|
}
|
|
395
421
|
|
|
396
|
-
export type { AuthorizeOptions as A,
|
|
422
|
+
export type { AuthorizeOptions as A, BioUsersConfig as B, CreateDepartmentData as C, ServiceRole as D, EmbedClientConfig as E, IntrospectResult as I, JWKSVerifyOptions as J, OrgMemberFilters as O, SilentAuthOptions as S, TokenResponse as T, UserFilters as U, VerifyOptions as V, OrgMembersResult as a, BioAuthConfig as b, AuthorizeResult as c, BioUser as d, BioAdminConfig as e, UpdateUserData as f, BioDepartment as g, BioRole as h, CreateRoleData as i, BioOAuthClient as j, CreateClientData as k, EmbedLoginParams as l, EmbedAuthResult as m, EmbedSignupParams as n, EmbedMagicLinkParams as o, EmbedVerifyParams as p, EmbedRefreshParams as q, EmbedLogoutParams as r, BioTokenPayload as s, AdminResponse as t, BioAddress as u, BioClientTokenPayload as v, BioMessaging as w, EmbedBranding as x, EmbedUser as y, OrgMember as z };
|
package/dist/users.d.mts
CHANGED
package/dist/users.d.ts
CHANGED
package/dist/users.js
CHANGED
|
@@ -175,6 +175,7 @@ function buildParams(filters) {
|
|
|
175
175
|
if (filters.orgSlug) params.set("orgSlug", filters.orgSlug);
|
|
176
176
|
if (filters.modules?.length) params.set("modules", filters.modules.join(","));
|
|
177
177
|
if (filters.roles?.length) params.set("roles", filters.roles.join(","));
|
|
178
|
+
if (filters.service) params.set("service", filters.service);
|
|
178
179
|
if (filters.limit) params.set("limit", String(filters.limit));
|
|
179
180
|
if (filters.page) params.set("page", String(filters.page));
|
|
180
181
|
return params;
|
package/dist/users.mjs
CHANGED
|
@@ -119,6 +119,7 @@ function buildParams(filters) {
|
|
|
119
119
|
if (filters.orgSlug) params.set("orgSlug", filters.orgSlug);
|
|
120
120
|
if (filters.modules?.length) params.set("modules", filters.modules.join(","));
|
|
121
121
|
if (filters.roles?.length) params.set("roles", filters.roles.join(","));
|
|
122
|
+
if (filters.service) params.set("service", filters.service);
|
|
122
123
|
if (filters.limit) params.set("limit", String(filters.limit));
|
|
123
124
|
if (filters.page) params.set("page", String(filters.page));
|
|
124
125
|
return params;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@insureco/bio",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"description": "SDK for Bio-ID SSO integration on the Tawa platform",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -20,13 +20,23 @@
|
|
|
20
20
|
"types": "./dist/graph.d.ts",
|
|
21
21
|
"import": "./dist/graph.mjs",
|
|
22
22
|
"require": "./dist/graph.js"
|
|
23
|
+
},
|
|
24
|
+
"./passport": {
|
|
25
|
+
"types": "./dist/passport.d.ts",
|
|
26
|
+
"import": "./dist/passport.mjs",
|
|
27
|
+
"require": "./dist/passport.js"
|
|
28
|
+
},
|
|
29
|
+
"./passport/react": {
|
|
30
|
+
"types": "./dist/passport-react.d.ts",
|
|
31
|
+
"import": "./dist/passport-react.mjs",
|
|
32
|
+
"require": "./dist/passport-react.js"
|
|
23
33
|
}
|
|
24
34
|
},
|
|
25
35
|
"files": [
|
|
26
36
|
"dist"
|
|
27
37
|
],
|
|
28
38
|
"scripts": {
|
|
29
|
-
"build": "tsup src/index.ts src/users.ts src/graph.ts --format cjs,esm --dts --clean",
|
|
39
|
+
"build": "tsup src/index.ts src/users.ts src/graph.ts src/passport.ts src/passport-react.ts --format cjs,esm --dts --clean",
|
|
30
40
|
"test": "vitest run",
|
|
31
41
|
"test:watch": "vitest",
|
|
32
42
|
"lint": "tsc --noEmit",
|
|
@@ -47,11 +57,23 @@
|
|
|
47
57
|
"access": "public"
|
|
48
58
|
},
|
|
49
59
|
"devDependencies": {
|
|
60
|
+
"@testing-library/dom": "^10.4.1",
|
|
61
|
+
"@testing-library/react": "^16.3.2",
|
|
50
62
|
"@types/node": "^22.0.0",
|
|
63
|
+
"@types/react": "^18.0.0",
|
|
64
|
+
"jsdom": "^28.1.0",
|
|
51
65
|
"tsup": "^8.0.0",
|
|
52
66
|
"typescript": "^5.4.0",
|
|
53
67
|
"vitest": "^2.0.0"
|
|
54
68
|
},
|
|
69
|
+
"peerDependencies": {
|
|
70
|
+
"react": ">=18.0.0"
|
|
71
|
+
},
|
|
72
|
+
"peerDependenciesMeta": {
|
|
73
|
+
"react": {
|
|
74
|
+
"optional": true
|
|
75
|
+
}
|
|
76
|
+
},
|
|
55
77
|
"engines": {
|
|
56
78
|
"node": ">=18.0.0"
|
|
57
79
|
}
|