@insureco/bio 0.2.0 → 0.4.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-NK5VXXWF.mjs +43 -0
- package/dist/index.d.mts +3 -257
- package/dist/index.d.ts +3 -257
- package/dist/index.js +13 -4
- package/dist/index.mjs +20 -41
- package/dist/types-Dkb-drHZ.d.mts +302 -0
- package/dist/types-Dkb-drHZ.d.ts +302 -0
- package/dist/users.d.mts +45 -0
- package/dist/users.d.ts +45 -0
- package/dist/users.js +185 -0
- package/dist/users.mjs +128 -0
- package/package.json +13 -9
package/dist/index.mjs
CHANGED
|
@@ -1,23 +1,13 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BioError,
|
|
3
|
+
parseJsonResponse,
|
|
4
|
+
retryDelay,
|
|
5
|
+
sleep
|
|
6
|
+
} from "./chunk-NK5VXXWF.mjs";
|
|
7
|
+
|
|
1
8
|
// src/auth.ts
|
|
2
9
|
import crypto2 from "crypto";
|
|
3
10
|
|
|
4
|
-
// src/errors.ts
|
|
5
|
-
var BioError = class extends Error {
|
|
6
|
-
/** HTTP status code (if from an API response) */
|
|
7
|
-
statusCode;
|
|
8
|
-
/** Machine-readable error code (e.g. 'invalid_grant', 'token_expired') */
|
|
9
|
-
code;
|
|
10
|
-
/** Additional error details from the API */
|
|
11
|
-
details;
|
|
12
|
-
constructor(message, code, statusCode, details) {
|
|
13
|
-
super(message);
|
|
14
|
-
this.name = "BioError";
|
|
15
|
-
this.code = code;
|
|
16
|
-
this.statusCode = statusCode;
|
|
17
|
-
this.details = details;
|
|
18
|
-
}
|
|
19
|
-
};
|
|
20
|
-
|
|
21
11
|
// src/pkce.ts
|
|
22
12
|
import crypto from "crypto";
|
|
23
13
|
function generatePKCE() {
|
|
@@ -26,28 +16,8 @@ function generatePKCE() {
|
|
|
26
16
|
return { codeVerifier, codeChallenge };
|
|
27
17
|
}
|
|
28
18
|
|
|
29
|
-
// src/utils.ts
|
|
30
|
-
function retryDelay(attempt) {
|
|
31
|
-
const baseDelay = Math.min(1e3 * 2 ** attempt, 5e3);
|
|
32
|
-
return baseDelay * (0.5 + Math.random() * 0.5);
|
|
33
|
-
}
|
|
34
|
-
function sleep(ms) {
|
|
35
|
-
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
36
|
-
}
|
|
37
|
-
async function parseJsonResponse(response) {
|
|
38
|
-
try {
|
|
39
|
-
return await response.json();
|
|
40
|
-
} catch {
|
|
41
|
-
throw new BioError(
|
|
42
|
-
`Bio-ID returned ${response.status} with non-JSON body`,
|
|
43
|
-
"parse_error",
|
|
44
|
-
response.status
|
|
45
|
-
);
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
19
|
// src/auth.ts
|
|
50
|
-
var DEFAULT_ISSUER = "https://bio.tawa.
|
|
20
|
+
var DEFAULT_ISSUER = "https://bio.tawa.pro";
|
|
51
21
|
var DEFAULT_SCOPES = ["openid", "profile", "email"];
|
|
52
22
|
var DEFAULT_TIMEOUT_MS = 1e4;
|
|
53
23
|
var BioAuth = class _BioAuth {
|
|
@@ -117,6 +87,9 @@ var BioAuth = class _BioAuth {
|
|
|
117
87
|
code_challenge: codeChallenge,
|
|
118
88
|
code_challenge_method: "S256"
|
|
119
89
|
});
|
|
90
|
+
if (opts.organization) {
|
|
91
|
+
params.set("organization", opts.organization);
|
|
92
|
+
}
|
|
120
93
|
return {
|
|
121
94
|
url: `${this.issuer}/oauth/authorize?${params.toString()}`,
|
|
122
95
|
state,
|
|
@@ -338,7 +311,7 @@ function mapIntrospectResponse(raw) {
|
|
|
338
311
|
}
|
|
339
312
|
|
|
340
313
|
// src/admin.ts
|
|
341
|
-
var DEFAULT_BASE_URL = "https://bio.tawa.
|
|
314
|
+
var DEFAULT_BASE_URL = "https://bio.tawa.pro";
|
|
342
315
|
var DEFAULT_TIMEOUT_MS2 = 1e4;
|
|
343
316
|
var BioAdmin = class _BioAdmin {
|
|
344
317
|
baseUrl;
|
|
@@ -544,9 +517,10 @@ import crypto3 from "crypto";
|
|
|
544
517
|
var DEFAULT_ISSUERS = [
|
|
545
518
|
"https://bio.insureco.io",
|
|
546
519
|
"https://bio.tawa.insureco.io",
|
|
520
|
+
"https://bio.tawa.pro",
|
|
547
521
|
"http://localhost:6100"
|
|
548
522
|
];
|
|
549
|
-
var DEFAULT_JWKS_URI = "https://bio.tawa.
|
|
523
|
+
var DEFAULT_JWKS_URI = "https://bio.tawa.pro/.well-known/jwks.json";
|
|
550
524
|
var JWKS_CACHE_TTL_MS = 24 * 60 * 60 * 1e3;
|
|
551
525
|
var jwksCache = /* @__PURE__ */ new Map();
|
|
552
526
|
async function fetchJWKS(uri) {
|
|
@@ -663,7 +637,12 @@ async function verifyTokenJWKS(token, options) {
|
|
|
663
637
|
throw new BioError("Malformed JWT: expected 3 parts", "invalid_token");
|
|
664
638
|
}
|
|
665
639
|
const [headerB64, payloadB64, signatureB64] = parts;
|
|
666
|
-
|
|
640
|
+
let header;
|
|
641
|
+
try {
|
|
642
|
+
header = JSON.parse(base64UrlDecode(headerB64));
|
|
643
|
+
} catch {
|
|
644
|
+
throw new BioError("Malformed JWT: invalid header encoding", "invalid_token");
|
|
645
|
+
}
|
|
667
646
|
if (header.alg !== "RS256") {
|
|
668
647
|
throw new BioError(
|
|
669
648
|
`Expected RS256 token, got ${header.alg}. Use verifyToken() for HS256.`,
|
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
/** Configuration for BioAuth (OAuth flow client) */
|
|
2
|
+
interface BioAuthConfig {
|
|
3
|
+
/** OAuth client ID (env: BIO_CLIENT_ID) */
|
|
4
|
+
clientId: string;
|
|
5
|
+
/** OAuth client secret (env: BIO_CLIENT_SECRET) */
|
|
6
|
+
clientSecret: string;
|
|
7
|
+
/** Bio-ID issuer URL (env: BIO_ID_URL, default: https://bio.tawa.pro) */
|
|
8
|
+
issuer?: string;
|
|
9
|
+
/** Number of retry attempts on transient failures (default: 2) */
|
|
10
|
+
retries?: number;
|
|
11
|
+
/** Request timeout in milliseconds (default: 10000) */
|
|
12
|
+
timeoutMs?: number;
|
|
13
|
+
}
|
|
14
|
+
/** Configuration for BioAdmin (admin API client) */
|
|
15
|
+
interface BioAdminConfig {
|
|
16
|
+
/** Bio-ID base URL (env: BIO_ID_URL, default: https://bio.tawa.pro) */
|
|
17
|
+
baseUrl?: string;
|
|
18
|
+
/** Internal API key for service-to-service auth (env: INTERNAL_API_KEY) */
|
|
19
|
+
internalKey?: string;
|
|
20
|
+
/** Async function returning a Bearer token (alternative to internalKey) */
|
|
21
|
+
accessTokenFn?: () => Promise<string>;
|
|
22
|
+
/** Number of retry attempts on transient failures (default: 2) */
|
|
23
|
+
retries?: number;
|
|
24
|
+
/** Request timeout in milliseconds (default: 10000) */
|
|
25
|
+
timeoutMs?: number;
|
|
26
|
+
}
|
|
27
|
+
/** Options for building an authorization URL */
|
|
28
|
+
interface AuthorizeOptions {
|
|
29
|
+
/** Callback URL where Bio-ID redirects after authorization */
|
|
30
|
+
redirectUri: string;
|
|
31
|
+
/** OAuth scopes to request (default: ['openid', 'profile', 'email']) */
|
|
32
|
+
scopes?: string[];
|
|
33
|
+
/** CSRF state parameter (auto-generated if not provided) */
|
|
34
|
+
state?: string;
|
|
35
|
+
/** Optional org slug to pre-select during authorization (for multi-org users) */
|
|
36
|
+
organization?: string;
|
|
37
|
+
}
|
|
38
|
+
/** Result from getAuthorizationUrl() */
|
|
39
|
+
interface AuthorizeResult {
|
|
40
|
+
/** Full authorization URL to redirect the user to */
|
|
41
|
+
url: string;
|
|
42
|
+
/** State parameter (for CSRF validation on callback) */
|
|
43
|
+
state: string;
|
|
44
|
+
/** PKCE code verifier (store securely, send during token exchange) */
|
|
45
|
+
codeVerifier: string;
|
|
46
|
+
/** PKCE code challenge (included in the URL) */
|
|
47
|
+
codeChallenge: string;
|
|
48
|
+
}
|
|
49
|
+
/** Response from the /api/oauth/token endpoint */
|
|
50
|
+
interface TokenResponse {
|
|
51
|
+
access_token: string;
|
|
52
|
+
token_type: 'Bearer';
|
|
53
|
+
expires_in: number;
|
|
54
|
+
refresh_token?: string;
|
|
55
|
+
scope: string;
|
|
56
|
+
id_token?: string;
|
|
57
|
+
}
|
|
58
|
+
/** Response from the /api/auth/introspect endpoint */
|
|
59
|
+
interface IntrospectResult {
|
|
60
|
+
active: boolean;
|
|
61
|
+
user?: {
|
|
62
|
+
id: string;
|
|
63
|
+
email: string;
|
|
64
|
+
name: string;
|
|
65
|
+
org: string;
|
|
66
|
+
roles: string[];
|
|
67
|
+
};
|
|
68
|
+
tokenType?: 'client_credentials';
|
|
69
|
+
clientId?: string;
|
|
70
|
+
scopes?: string[];
|
|
71
|
+
orgId?: string;
|
|
72
|
+
orgSlug?: string;
|
|
73
|
+
organizationName?: string;
|
|
74
|
+
}
|
|
75
|
+
/** Decoded access token payload (user auth) */
|
|
76
|
+
interface BioTokenPayload {
|
|
77
|
+
iss: string;
|
|
78
|
+
sub: string;
|
|
79
|
+
aud: string;
|
|
80
|
+
exp: number;
|
|
81
|
+
iat: number;
|
|
82
|
+
bioId: string;
|
|
83
|
+
email: string;
|
|
84
|
+
name: string;
|
|
85
|
+
userType: string;
|
|
86
|
+
roles: string[];
|
|
87
|
+
permissions: string[];
|
|
88
|
+
orgId?: string;
|
|
89
|
+
orgSlug?: string;
|
|
90
|
+
/** Org-specific role slugs within the user's active org (from OrgMembership) */
|
|
91
|
+
orgRoles?: string[];
|
|
92
|
+
/** Job title at the active org (from OrgMembership.jobTitle) */
|
|
93
|
+
orgTitle?: string;
|
|
94
|
+
/** Additional modules granted by the org specifically (from OrgMembership.enabled_modules) */
|
|
95
|
+
orgModules?: string[];
|
|
96
|
+
client_id: string;
|
|
97
|
+
scope: string;
|
|
98
|
+
enabled_modules?: string[];
|
|
99
|
+
onboarding?: {
|
|
100
|
+
platform: boolean;
|
|
101
|
+
modules: Record<string, {
|
|
102
|
+
completed: string[];
|
|
103
|
+
due: string[];
|
|
104
|
+
}>;
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
/** Decoded client credentials token payload (service-to-service) */
|
|
108
|
+
interface BioClientTokenPayload {
|
|
109
|
+
iss: string;
|
|
110
|
+
exp: number;
|
|
111
|
+
iat: number;
|
|
112
|
+
client_id: string;
|
|
113
|
+
scope: string;
|
|
114
|
+
token_type: 'client_credentials';
|
|
115
|
+
orgId?: string;
|
|
116
|
+
orgSlug?: string;
|
|
117
|
+
}
|
|
118
|
+
/** Options for local JWT verification (HS256) */
|
|
119
|
+
interface VerifyOptions {
|
|
120
|
+
/** Expected issuer (default: config issuer) */
|
|
121
|
+
issuer?: string;
|
|
122
|
+
/** Expected audience (client_id) */
|
|
123
|
+
audience?: string;
|
|
124
|
+
}
|
|
125
|
+
/** Options for JWKS-based JWT verification (RS256) */
|
|
126
|
+
interface JWKSVerifyOptions {
|
|
127
|
+
/** JWKS endpoint URL (default: https://bio.tawa.pro/.well-known/jwks.json) */
|
|
128
|
+
jwksUri?: string;
|
|
129
|
+
/** Expected issuer — defaults to accepting bio.insureco.io, bio.tawa.insureco.io, and bio.tawa.pro */
|
|
130
|
+
issuer?: string;
|
|
131
|
+
/** Expected audience (client_id) */
|
|
132
|
+
audience?: string;
|
|
133
|
+
}
|
|
134
|
+
/** User profile from /api/oauth/userinfo or admin API */
|
|
135
|
+
interface BioUser {
|
|
136
|
+
sub: string;
|
|
137
|
+
bioId: string;
|
|
138
|
+
email: string;
|
|
139
|
+
emailVerified: boolean;
|
|
140
|
+
name: string;
|
|
141
|
+
firstName?: string;
|
|
142
|
+
lastName?: string;
|
|
143
|
+
userType: string;
|
|
144
|
+
roles: string[];
|
|
145
|
+
permissions: string[];
|
|
146
|
+
status: string;
|
|
147
|
+
orgId?: string;
|
|
148
|
+
orgSlug?: string;
|
|
149
|
+
organizationId?: string;
|
|
150
|
+
organizationName?: string;
|
|
151
|
+
departmentId?: string;
|
|
152
|
+
departmentName?: string;
|
|
153
|
+
managerId?: string;
|
|
154
|
+
enabledModules?: string[];
|
|
155
|
+
jobTitle?: string;
|
|
156
|
+
phoneHome?: string;
|
|
157
|
+
phoneWork?: string;
|
|
158
|
+
phoneCell?: string;
|
|
159
|
+
phone?: string;
|
|
160
|
+
addressHome?: BioAddress;
|
|
161
|
+
addressWork?: BioAddress;
|
|
162
|
+
messaging?: BioMessaging;
|
|
163
|
+
preferences?: Record<string, unknown>;
|
|
164
|
+
lastLoginAt?: number;
|
|
165
|
+
}
|
|
166
|
+
interface BioAddress {
|
|
167
|
+
street?: string;
|
|
168
|
+
city?: string;
|
|
169
|
+
state?: string;
|
|
170
|
+
zip?: string;
|
|
171
|
+
country?: string;
|
|
172
|
+
}
|
|
173
|
+
interface BioMessaging {
|
|
174
|
+
slack?: string;
|
|
175
|
+
teams?: string;
|
|
176
|
+
skype?: string;
|
|
177
|
+
whatsapp?: string;
|
|
178
|
+
}
|
|
179
|
+
/** Filters for listing users */
|
|
180
|
+
interface UserFilters {
|
|
181
|
+
search?: string;
|
|
182
|
+
status?: string;
|
|
183
|
+
userType?: string;
|
|
184
|
+
organizationId?: string;
|
|
185
|
+
page?: number;
|
|
186
|
+
limit?: number;
|
|
187
|
+
}
|
|
188
|
+
/** Data for updating a user */
|
|
189
|
+
interface UpdateUserData {
|
|
190
|
+
firstName?: string;
|
|
191
|
+
lastName?: string;
|
|
192
|
+
displayName?: string;
|
|
193
|
+
roles?: string[];
|
|
194
|
+
status?: string;
|
|
195
|
+
userType?: string;
|
|
196
|
+
departmentId?: string;
|
|
197
|
+
jobTitle?: string;
|
|
198
|
+
permissions?: string[];
|
|
199
|
+
enabled_modules?: string[];
|
|
200
|
+
}
|
|
201
|
+
/** Department from admin API */
|
|
202
|
+
interface BioDepartment {
|
|
203
|
+
id: string;
|
|
204
|
+
name: string;
|
|
205
|
+
description?: string;
|
|
206
|
+
organizationId: string;
|
|
207
|
+
headId?: string;
|
|
208
|
+
parentId?: string;
|
|
209
|
+
memberCount?: number;
|
|
210
|
+
}
|
|
211
|
+
/** Data for creating a department */
|
|
212
|
+
interface CreateDepartmentData {
|
|
213
|
+
name: string;
|
|
214
|
+
description?: string;
|
|
215
|
+
headId?: string;
|
|
216
|
+
parentId?: string;
|
|
217
|
+
}
|
|
218
|
+
/** Role from admin API */
|
|
219
|
+
interface BioRole {
|
|
220
|
+
id: string;
|
|
221
|
+
name: string;
|
|
222
|
+
description?: string;
|
|
223
|
+
permissions: string[];
|
|
224
|
+
isSystem?: boolean;
|
|
225
|
+
}
|
|
226
|
+
/** Data for creating a role */
|
|
227
|
+
interface CreateRoleData {
|
|
228
|
+
name: string;
|
|
229
|
+
description?: string;
|
|
230
|
+
permissions: string[];
|
|
231
|
+
}
|
|
232
|
+
/** OAuth client from admin API */
|
|
233
|
+
interface BioOAuthClient {
|
|
234
|
+
clientId: string;
|
|
235
|
+
name: string;
|
|
236
|
+
description?: string;
|
|
237
|
+
redirectUris: string[];
|
|
238
|
+
allowedScopes: string[];
|
|
239
|
+
allowedGrantTypes: string[];
|
|
240
|
+
isActive: boolean;
|
|
241
|
+
orgId?: string;
|
|
242
|
+
orgSlug?: string;
|
|
243
|
+
accessTokenTtl?: number;
|
|
244
|
+
refreshTokenTtl?: number;
|
|
245
|
+
}
|
|
246
|
+
/** Data for creating an OAuth client */
|
|
247
|
+
interface CreateClientData {
|
|
248
|
+
name: string;
|
|
249
|
+
description?: string;
|
|
250
|
+
redirectUris: string[];
|
|
251
|
+
allowedScopes?: string[];
|
|
252
|
+
allowedGrantTypes?: string[];
|
|
253
|
+
}
|
|
254
|
+
/** Configuration for BioUsers client */
|
|
255
|
+
interface BioUsersConfig {
|
|
256
|
+
/** Bio users URL (env: BIO_USERS_URL) */
|
|
257
|
+
usersUrl: string;
|
|
258
|
+
/** Service API key (env: BIO_SERVICE_KEY) */
|
|
259
|
+
serviceKey: string;
|
|
260
|
+
/** Request timeout in milliseconds (default: 10000) */
|
|
261
|
+
timeoutMs?: number;
|
|
262
|
+
}
|
|
263
|
+
/** Filters for querying org members via /api/v2/users or /api/orgs/[slug]/members */
|
|
264
|
+
interface OrgMemberFilters {
|
|
265
|
+
/** Only return members with these modules enabled */
|
|
266
|
+
modules?: string[];
|
|
267
|
+
/** Only return members with these roles */
|
|
268
|
+
roles?: string[];
|
|
269
|
+
/** Max results (default: 50) */
|
|
270
|
+
limit?: number;
|
|
271
|
+
/** Page number for pagination (default: 1) */
|
|
272
|
+
page?: number;
|
|
273
|
+
}
|
|
274
|
+
/** A member as returned by GET /api/v2/users or GET /api/orgs/[slug]/members */
|
|
275
|
+
interface OrgMember {
|
|
276
|
+
bioId: string;
|
|
277
|
+
email: string;
|
|
278
|
+
name: string;
|
|
279
|
+
jobTitle?: string;
|
|
280
|
+
enabled_modules: string[];
|
|
281
|
+
roles?: string[];
|
|
282
|
+
}
|
|
283
|
+
/** Paginated response from the user access endpoints */
|
|
284
|
+
interface OrgMembersResult {
|
|
285
|
+
members: OrgMember[];
|
|
286
|
+
total: number;
|
|
287
|
+
page: number;
|
|
288
|
+
limit: number;
|
|
289
|
+
}
|
|
290
|
+
/** Admin API response wrapper */
|
|
291
|
+
interface AdminResponse<T> {
|
|
292
|
+
success: boolean;
|
|
293
|
+
data?: T;
|
|
294
|
+
error?: string;
|
|
295
|
+
meta?: {
|
|
296
|
+
total: number;
|
|
297
|
+
page: number;
|
|
298
|
+
limit: number;
|
|
299
|
+
};
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
export type { AuthorizeOptions as A, BioAuthConfig as B, CreateDepartmentData as C, IntrospectResult as I, JWKSVerifyOptions as J, OrgMember as O, TokenResponse as T, UserFilters as U, VerifyOptions as V, AuthorizeResult as a, BioUser as b, BioAdminConfig as c, UpdateUserData as d, BioDepartment as e, BioRole as f, CreateRoleData as g, BioOAuthClient as h, CreateClientData as i, BioTokenPayload as j, AdminResponse as k, BioAddress as l, BioClientTokenPayload as m, BioMessaging as n, BioUsersConfig as o, OrgMemberFilters as p, OrgMembersResult as q };
|
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
/** Configuration for BioAuth (OAuth flow client) */
|
|
2
|
+
interface BioAuthConfig {
|
|
3
|
+
/** OAuth client ID (env: BIO_CLIENT_ID) */
|
|
4
|
+
clientId: string;
|
|
5
|
+
/** OAuth client secret (env: BIO_CLIENT_SECRET) */
|
|
6
|
+
clientSecret: string;
|
|
7
|
+
/** Bio-ID issuer URL (env: BIO_ID_URL, default: https://bio.tawa.pro) */
|
|
8
|
+
issuer?: string;
|
|
9
|
+
/** Number of retry attempts on transient failures (default: 2) */
|
|
10
|
+
retries?: number;
|
|
11
|
+
/** Request timeout in milliseconds (default: 10000) */
|
|
12
|
+
timeoutMs?: number;
|
|
13
|
+
}
|
|
14
|
+
/** Configuration for BioAdmin (admin API client) */
|
|
15
|
+
interface BioAdminConfig {
|
|
16
|
+
/** Bio-ID base URL (env: BIO_ID_URL, default: https://bio.tawa.pro) */
|
|
17
|
+
baseUrl?: string;
|
|
18
|
+
/** Internal API key for service-to-service auth (env: INTERNAL_API_KEY) */
|
|
19
|
+
internalKey?: string;
|
|
20
|
+
/** Async function returning a Bearer token (alternative to internalKey) */
|
|
21
|
+
accessTokenFn?: () => Promise<string>;
|
|
22
|
+
/** Number of retry attempts on transient failures (default: 2) */
|
|
23
|
+
retries?: number;
|
|
24
|
+
/** Request timeout in milliseconds (default: 10000) */
|
|
25
|
+
timeoutMs?: number;
|
|
26
|
+
}
|
|
27
|
+
/** Options for building an authorization URL */
|
|
28
|
+
interface AuthorizeOptions {
|
|
29
|
+
/** Callback URL where Bio-ID redirects after authorization */
|
|
30
|
+
redirectUri: string;
|
|
31
|
+
/** OAuth scopes to request (default: ['openid', 'profile', 'email']) */
|
|
32
|
+
scopes?: string[];
|
|
33
|
+
/** CSRF state parameter (auto-generated if not provided) */
|
|
34
|
+
state?: string;
|
|
35
|
+
/** Optional org slug to pre-select during authorization (for multi-org users) */
|
|
36
|
+
organization?: string;
|
|
37
|
+
}
|
|
38
|
+
/** Result from getAuthorizationUrl() */
|
|
39
|
+
interface AuthorizeResult {
|
|
40
|
+
/** Full authorization URL to redirect the user to */
|
|
41
|
+
url: string;
|
|
42
|
+
/** State parameter (for CSRF validation on callback) */
|
|
43
|
+
state: string;
|
|
44
|
+
/** PKCE code verifier (store securely, send during token exchange) */
|
|
45
|
+
codeVerifier: string;
|
|
46
|
+
/** PKCE code challenge (included in the URL) */
|
|
47
|
+
codeChallenge: string;
|
|
48
|
+
}
|
|
49
|
+
/** Response from the /api/oauth/token endpoint */
|
|
50
|
+
interface TokenResponse {
|
|
51
|
+
access_token: string;
|
|
52
|
+
token_type: 'Bearer';
|
|
53
|
+
expires_in: number;
|
|
54
|
+
refresh_token?: string;
|
|
55
|
+
scope: string;
|
|
56
|
+
id_token?: string;
|
|
57
|
+
}
|
|
58
|
+
/** Response from the /api/auth/introspect endpoint */
|
|
59
|
+
interface IntrospectResult {
|
|
60
|
+
active: boolean;
|
|
61
|
+
user?: {
|
|
62
|
+
id: string;
|
|
63
|
+
email: string;
|
|
64
|
+
name: string;
|
|
65
|
+
org: string;
|
|
66
|
+
roles: string[];
|
|
67
|
+
};
|
|
68
|
+
tokenType?: 'client_credentials';
|
|
69
|
+
clientId?: string;
|
|
70
|
+
scopes?: string[];
|
|
71
|
+
orgId?: string;
|
|
72
|
+
orgSlug?: string;
|
|
73
|
+
organizationName?: string;
|
|
74
|
+
}
|
|
75
|
+
/** Decoded access token payload (user auth) */
|
|
76
|
+
interface BioTokenPayload {
|
|
77
|
+
iss: string;
|
|
78
|
+
sub: string;
|
|
79
|
+
aud: string;
|
|
80
|
+
exp: number;
|
|
81
|
+
iat: number;
|
|
82
|
+
bioId: string;
|
|
83
|
+
email: string;
|
|
84
|
+
name: string;
|
|
85
|
+
userType: string;
|
|
86
|
+
roles: string[];
|
|
87
|
+
permissions: string[];
|
|
88
|
+
orgId?: string;
|
|
89
|
+
orgSlug?: string;
|
|
90
|
+
/** Org-specific role slugs within the user's active org (from OrgMembership) */
|
|
91
|
+
orgRoles?: string[];
|
|
92
|
+
/** Job title at the active org (from OrgMembership.jobTitle) */
|
|
93
|
+
orgTitle?: string;
|
|
94
|
+
/** Additional modules granted by the org specifically (from OrgMembership.enabled_modules) */
|
|
95
|
+
orgModules?: string[];
|
|
96
|
+
client_id: string;
|
|
97
|
+
scope: string;
|
|
98
|
+
enabled_modules?: string[];
|
|
99
|
+
onboarding?: {
|
|
100
|
+
platform: boolean;
|
|
101
|
+
modules: Record<string, {
|
|
102
|
+
completed: string[];
|
|
103
|
+
due: string[];
|
|
104
|
+
}>;
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
/** Decoded client credentials token payload (service-to-service) */
|
|
108
|
+
interface BioClientTokenPayload {
|
|
109
|
+
iss: string;
|
|
110
|
+
exp: number;
|
|
111
|
+
iat: number;
|
|
112
|
+
client_id: string;
|
|
113
|
+
scope: string;
|
|
114
|
+
token_type: 'client_credentials';
|
|
115
|
+
orgId?: string;
|
|
116
|
+
orgSlug?: string;
|
|
117
|
+
}
|
|
118
|
+
/** Options for local JWT verification (HS256) */
|
|
119
|
+
interface VerifyOptions {
|
|
120
|
+
/** Expected issuer (default: config issuer) */
|
|
121
|
+
issuer?: string;
|
|
122
|
+
/** Expected audience (client_id) */
|
|
123
|
+
audience?: string;
|
|
124
|
+
}
|
|
125
|
+
/** Options for JWKS-based JWT verification (RS256) */
|
|
126
|
+
interface JWKSVerifyOptions {
|
|
127
|
+
/** JWKS endpoint URL (default: https://bio.tawa.pro/.well-known/jwks.json) */
|
|
128
|
+
jwksUri?: string;
|
|
129
|
+
/** Expected issuer — defaults to accepting bio.insureco.io, bio.tawa.insureco.io, and bio.tawa.pro */
|
|
130
|
+
issuer?: string;
|
|
131
|
+
/** Expected audience (client_id) */
|
|
132
|
+
audience?: string;
|
|
133
|
+
}
|
|
134
|
+
/** User profile from /api/oauth/userinfo or admin API */
|
|
135
|
+
interface BioUser {
|
|
136
|
+
sub: string;
|
|
137
|
+
bioId: string;
|
|
138
|
+
email: string;
|
|
139
|
+
emailVerified: boolean;
|
|
140
|
+
name: string;
|
|
141
|
+
firstName?: string;
|
|
142
|
+
lastName?: string;
|
|
143
|
+
userType: string;
|
|
144
|
+
roles: string[];
|
|
145
|
+
permissions: string[];
|
|
146
|
+
status: string;
|
|
147
|
+
orgId?: string;
|
|
148
|
+
orgSlug?: string;
|
|
149
|
+
organizationId?: string;
|
|
150
|
+
organizationName?: string;
|
|
151
|
+
departmentId?: string;
|
|
152
|
+
departmentName?: string;
|
|
153
|
+
managerId?: string;
|
|
154
|
+
enabledModules?: string[];
|
|
155
|
+
jobTitle?: string;
|
|
156
|
+
phoneHome?: string;
|
|
157
|
+
phoneWork?: string;
|
|
158
|
+
phoneCell?: string;
|
|
159
|
+
phone?: string;
|
|
160
|
+
addressHome?: BioAddress;
|
|
161
|
+
addressWork?: BioAddress;
|
|
162
|
+
messaging?: BioMessaging;
|
|
163
|
+
preferences?: Record<string, unknown>;
|
|
164
|
+
lastLoginAt?: number;
|
|
165
|
+
}
|
|
166
|
+
interface BioAddress {
|
|
167
|
+
street?: string;
|
|
168
|
+
city?: string;
|
|
169
|
+
state?: string;
|
|
170
|
+
zip?: string;
|
|
171
|
+
country?: string;
|
|
172
|
+
}
|
|
173
|
+
interface BioMessaging {
|
|
174
|
+
slack?: string;
|
|
175
|
+
teams?: string;
|
|
176
|
+
skype?: string;
|
|
177
|
+
whatsapp?: string;
|
|
178
|
+
}
|
|
179
|
+
/** Filters for listing users */
|
|
180
|
+
interface UserFilters {
|
|
181
|
+
search?: string;
|
|
182
|
+
status?: string;
|
|
183
|
+
userType?: string;
|
|
184
|
+
organizationId?: string;
|
|
185
|
+
page?: number;
|
|
186
|
+
limit?: number;
|
|
187
|
+
}
|
|
188
|
+
/** Data for updating a user */
|
|
189
|
+
interface UpdateUserData {
|
|
190
|
+
firstName?: string;
|
|
191
|
+
lastName?: string;
|
|
192
|
+
displayName?: string;
|
|
193
|
+
roles?: string[];
|
|
194
|
+
status?: string;
|
|
195
|
+
userType?: string;
|
|
196
|
+
departmentId?: string;
|
|
197
|
+
jobTitle?: string;
|
|
198
|
+
permissions?: string[];
|
|
199
|
+
enabled_modules?: string[];
|
|
200
|
+
}
|
|
201
|
+
/** Department from admin API */
|
|
202
|
+
interface BioDepartment {
|
|
203
|
+
id: string;
|
|
204
|
+
name: string;
|
|
205
|
+
description?: string;
|
|
206
|
+
organizationId: string;
|
|
207
|
+
headId?: string;
|
|
208
|
+
parentId?: string;
|
|
209
|
+
memberCount?: number;
|
|
210
|
+
}
|
|
211
|
+
/** Data for creating a department */
|
|
212
|
+
interface CreateDepartmentData {
|
|
213
|
+
name: string;
|
|
214
|
+
description?: string;
|
|
215
|
+
headId?: string;
|
|
216
|
+
parentId?: string;
|
|
217
|
+
}
|
|
218
|
+
/** Role from admin API */
|
|
219
|
+
interface BioRole {
|
|
220
|
+
id: string;
|
|
221
|
+
name: string;
|
|
222
|
+
description?: string;
|
|
223
|
+
permissions: string[];
|
|
224
|
+
isSystem?: boolean;
|
|
225
|
+
}
|
|
226
|
+
/** Data for creating a role */
|
|
227
|
+
interface CreateRoleData {
|
|
228
|
+
name: string;
|
|
229
|
+
description?: string;
|
|
230
|
+
permissions: string[];
|
|
231
|
+
}
|
|
232
|
+
/** OAuth client from admin API */
|
|
233
|
+
interface BioOAuthClient {
|
|
234
|
+
clientId: string;
|
|
235
|
+
name: string;
|
|
236
|
+
description?: string;
|
|
237
|
+
redirectUris: string[];
|
|
238
|
+
allowedScopes: string[];
|
|
239
|
+
allowedGrantTypes: string[];
|
|
240
|
+
isActive: boolean;
|
|
241
|
+
orgId?: string;
|
|
242
|
+
orgSlug?: string;
|
|
243
|
+
accessTokenTtl?: number;
|
|
244
|
+
refreshTokenTtl?: number;
|
|
245
|
+
}
|
|
246
|
+
/** Data for creating an OAuth client */
|
|
247
|
+
interface CreateClientData {
|
|
248
|
+
name: string;
|
|
249
|
+
description?: string;
|
|
250
|
+
redirectUris: string[];
|
|
251
|
+
allowedScopes?: string[];
|
|
252
|
+
allowedGrantTypes?: string[];
|
|
253
|
+
}
|
|
254
|
+
/** Configuration for BioUsers client */
|
|
255
|
+
interface BioUsersConfig {
|
|
256
|
+
/** Bio users URL (env: BIO_USERS_URL) */
|
|
257
|
+
usersUrl: string;
|
|
258
|
+
/** Service API key (env: BIO_SERVICE_KEY) */
|
|
259
|
+
serviceKey: string;
|
|
260
|
+
/** Request timeout in milliseconds (default: 10000) */
|
|
261
|
+
timeoutMs?: number;
|
|
262
|
+
}
|
|
263
|
+
/** Filters for querying org members via /api/v2/users or /api/orgs/[slug]/members */
|
|
264
|
+
interface OrgMemberFilters {
|
|
265
|
+
/** Only return members with these modules enabled */
|
|
266
|
+
modules?: string[];
|
|
267
|
+
/** Only return members with these roles */
|
|
268
|
+
roles?: string[];
|
|
269
|
+
/** Max results (default: 50) */
|
|
270
|
+
limit?: number;
|
|
271
|
+
/** Page number for pagination (default: 1) */
|
|
272
|
+
page?: number;
|
|
273
|
+
}
|
|
274
|
+
/** A member as returned by GET /api/v2/users or GET /api/orgs/[slug]/members */
|
|
275
|
+
interface OrgMember {
|
|
276
|
+
bioId: string;
|
|
277
|
+
email: string;
|
|
278
|
+
name: string;
|
|
279
|
+
jobTitle?: string;
|
|
280
|
+
enabled_modules: string[];
|
|
281
|
+
roles?: string[];
|
|
282
|
+
}
|
|
283
|
+
/** Paginated response from the user access endpoints */
|
|
284
|
+
interface OrgMembersResult {
|
|
285
|
+
members: OrgMember[];
|
|
286
|
+
total: number;
|
|
287
|
+
page: number;
|
|
288
|
+
limit: number;
|
|
289
|
+
}
|
|
290
|
+
/** Admin API response wrapper */
|
|
291
|
+
interface AdminResponse<T> {
|
|
292
|
+
success: boolean;
|
|
293
|
+
data?: T;
|
|
294
|
+
error?: string;
|
|
295
|
+
meta?: {
|
|
296
|
+
total: number;
|
|
297
|
+
page: number;
|
|
298
|
+
limit: number;
|
|
299
|
+
};
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
export type { AuthorizeOptions as A, BioAuthConfig as B, CreateDepartmentData as C, IntrospectResult as I, JWKSVerifyOptions as J, OrgMember as O, TokenResponse as T, UserFilters as U, VerifyOptions as V, AuthorizeResult as a, BioUser as b, BioAdminConfig as c, UpdateUserData as d, BioDepartment as e, BioRole as f, CreateRoleData as g, BioOAuthClient as h, CreateClientData as i, BioTokenPayload as j, AdminResponse as k, BioAddress as l, BioClientTokenPayload as m, BioMessaging as n, BioUsersConfig as o, OrgMemberFilters as p, OrgMembersResult as q };
|