@insureco/bio 0.5.0 → 0.6.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/index.d.mts +88 -3
- package/dist/index.d.ts +88 -3
- package/dist/index.js +255 -2
- package/dist/index.mjs +252 -0
- package/dist/{types-Dkb-drHZ.d.mts → types-CJe1FP61.d.mts} +95 -1
- package/dist/{types-Dkb-drHZ.d.ts → types-CJe1FP61.d.ts} +95 -1
- package/dist/users.d.mts +1 -1
- package/dist/users.d.ts +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { B as BioAuthConfig, A as AuthorizeOptions, a as AuthorizeResult, T as TokenResponse, b as BioUser, I as IntrospectResult, c as BioAdminConfig, U as UserFilters, d as UpdateUserData, e as BioDepartment, C as CreateDepartmentData, f as BioRole, g as CreateRoleData, h as BioOAuthClient, i as CreateClientData, j as BioTokenPayload, V as VerifyOptions, J as JWKSVerifyOptions } from './types-
|
|
2
|
-
export {
|
|
1
|
+
import { B as BioAuthConfig, A as AuthorizeOptions, a as AuthorizeResult, T as TokenResponse, b as BioUser, I as IntrospectResult, c as BioAdminConfig, U as UserFilters, d as UpdateUserData, e as BioDepartment, C as CreateDepartmentData, f as BioRole, g as CreateRoleData, h as BioOAuthClient, i as CreateClientData, E as EmbedClientConfig, j as EmbedLoginParams, k as EmbedAuthResult, l as EmbedSignupParams, m as EmbedMagicLinkParams, n as EmbedVerifyParams, o as EmbedRefreshParams, p as EmbedLogoutParams, q as BioTokenPayload, V as VerifyOptions, J as JWKSVerifyOptions } from './types-CJe1FP61.mjs';
|
|
2
|
+
export { r as AdminResponse, s as BioAddress, t as BioClientTokenPayload, u as BioMessaging, v as BioUsersConfig, w as EmbedBranding, x as EmbedUser, O as OrgMember, y as OrgMemberFilters, z as OrgMembersResult } from './types-CJe1FP61.mjs';
|
|
3
3
|
export { AgencyProfile, AgencyProgram, AgencyStaffMember, AgentEmployer, AgentProfile, AppetiteMatchInput, AppetiteMatchProgram, AppetiteMatchResult, CarrierProfile, CarrierProgram, GraphClient, GraphClientConfig, ProgramProfile } from './graph.mjs';
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -105,6 +105,91 @@ declare class BioAdmin {
|
|
|
105
105
|
private request;
|
|
106
106
|
}
|
|
107
107
|
|
|
108
|
+
/**
|
|
109
|
+
* Client for Bio-ID headless embed endpoints.
|
|
110
|
+
*
|
|
111
|
+
* Use this when building custom login/signup UIs that authenticate
|
|
112
|
+
* directly against Bio-ID without redirects (no OAuth flow).
|
|
113
|
+
*
|
|
114
|
+
* All endpoints use X-Client-Id / X-Client-Secret header auth.
|
|
115
|
+
*
|
|
116
|
+
* @example
|
|
117
|
+
* ```typescript
|
|
118
|
+
* import { EmbedClient } from '@insureco/bio'
|
|
119
|
+
*
|
|
120
|
+
* const embed = EmbedClient.fromEnv()
|
|
121
|
+
*
|
|
122
|
+
* // Login
|
|
123
|
+
* const result = await embed.login({ email: 'user@example.com', password: 'secret' })
|
|
124
|
+
* console.log(result.accessToken, result.user.bioId)
|
|
125
|
+
*
|
|
126
|
+
* // Refresh
|
|
127
|
+
* const refreshed = await embed.refresh({ refreshToken: result.refreshToken })
|
|
128
|
+
*
|
|
129
|
+
* // Logout
|
|
130
|
+
* await embed.logout({ refreshToken: result.refreshToken })
|
|
131
|
+
* ```
|
|
132
|
+
*/
|
|
133
|
+
declare class EmbedClient {
|
|
134
|
+
private readonly bioIdUrl;
|
|
135
|
+
private readonly clientId;
|
|
136
|
+
private readonly clientSecret;
|
|
137
|
+
private readonly retries;
|
|
138
|
+
private readonly timeoutMs;
|
|
139
|
+
constructor(config: EmbedClientConfig);
|
|
140
|
+
/**
|
|
141
|
+
* Create an EmbedClient from environment variables.
|
|
142
|
+
*
|
|
143
|
+
* Reads: BIO_CLIENT_ID, BIO_CLIENT_SECRET, BIO_ID_URL
|
|
144
|
+
*/
|
|
145
|
+
static fromEnv(overrides?: Partial<EmbedClientConfig>): EmbedClient;
|
|
146
|
+
/**
|
|
147
|
+
* Authenticate a user with email and password.
|
|
148
|
+
*
|
|
149
|
+
* @param params - Email and password
|
|
150
|
+
* @returns Access token, refresh token, user profile, and optional branding
|
|
151
|
+
*/
|
|
152
|
+
login(params: EmbedLoginParams): Promise<EmbedAuthResult>;
|
|
153
|
+
/**
|
|
154
|
+
* Create a new user account.
|
|
155
|
+
*
|
|
156
|
+
* @param params - Email, password, name, and optional invite token
|
|
157
|
+
* @returns Access token, refresh token, user profile, and optional branding
|
|
158
|
+
*/
|
|
159
|
+
signup(params: EmbedSignupParams): Promise<EmbedAuthResult>;
|
|
160
|
+
/**
|
|
161
|
+
* Send a magic link email to the user.
|
|
162
|
+
*
|
|
163
|
+
* The user clicks the link to authenticate without a password.
|
|
164
|
+
* After sending, use `verify()` with the token from the link.
|
|
165
|
+
*
|
|
166
|
+
* @param params - Email address to send the magic link to
|
|
167
|
+
*/
|
|
168
|
+
sendMagicLink(params: EmbedMagicLinkParams): Promise<void>;
|
|
169
|
+
/**
|
|
170
|
+
* Verify a magic link token and exchange it for auth tokens.
|
|
171
|
+
*
|
|
172
|
+
* @param params - The token from the magic link
|
|
173
|
+
* @returns Access token, refresh token, user profile, and optional branding
|
|
174
|
+
*/
|
|
175
|
+
verify(params: EmbedVerifyParams): Promise<EmbedAuthResult>;
|
|
176
|
+
/**
|
|
177
|
+
* Refresh an expired access token using a refresh token.
|
|
178
|
+
*
|
|
179
|
+
* @param params - The refresh token to exchange
|
|
180
|
+
* @returns New access token, rotated refresh token, user profile, and optional branding
|
|
181
|
+
*/
|
|
182
|
+
refresh(params: EmbedRefreshParams): Promise<EmbedAuthResult>;
|
|
183
|
+
/**
|
|
184
|
+
* Revoke a refresh token (logout).
|
|
185
|
+
*
|
|
186
|
+
* @param params - The refresh token to revoke
|
|
187
|
+
*/
|
|
188
|
+
logout(params: EmbedLogoutParams): Promise<void>;
|
|
189
|
+
private embedRequest;
|
|
190
|
+
private fetchWithRetry;
|
|
191
|
+
}
|
|
192
|
+
|
|
108
193
|
/** Error thrown by Bio SDK operations */
|
|
109
194
|
declare class BioError extends Error {
|
|
110
195
|
/** HTTP status code (if from an API response) */
|
|
@@ -155,4 +240,4 @@ declare function isTokenExpired(token: string, bufferSeconds?: number): boolean;
|
|
|
155
240
|
*/
|
|
156
241
|
declare function verifyTokenJWKS(token: string, options?: JWKSVerifyOptions): Promise<BioTokenPayload>;
|
|
157
242
|
|
|
158
|
-
export { AuthorizeOptions, AuthorizeResult, BioAdmin, BioAdminConfig, BioAuth, BioAuthConfig, BioDepartment, BioError, BioOAuthClient, BioRole, BioTokenPayload, BioUser, CreateClientData, CreateDepartmentData, CreateRoleData, IntrospectResult, JWKSVerifyOptions, TokenResponse, UpdateUserData, UserFilters, VerifyOptions, decodeToken, generatePKCE, isTokenExpired, verifyToken, verifyTokenJWKS };
|
|
243
|
+
export { AuthorizeOptions, AuthorizeResult, BioAdmin, BioAdminConfig, BioAuth, BioAuthConfig, BioDepartment, BioError, BioOAuthClient, BioRole, BioTokenPayload, BioUser, CreateClientData, CreateDepartmentData, CreateRoleData, EmbedAuthResult, EmbedClient, EmbedClientConfig, EmbedLoginParams, EmbedLogoutParams, EmbedMagicLinkParams, EmbedRefreshParams, EmbedSignupParams, EmbedVerifyParams, IntrospectResult, JWKSVerifyOptions, TokenResponse, UpdateUserData, UserFilters, VerifyOptions, decodeToken, generatePKCE, isTokenExpired, verifyToken, verifyTokenJWKS };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { B as BioAuthConfig, A as AuthorizeOptions, a as AuthorizeResult, T as TokenResponse, b as BioUser, I as IntrospectResult, c as BioAdminConfig, U as UserFilters, d as UpdateUserData, e as BioDepartment, C as CreateDepartmentData, f as BioRole, g as CreateRoleData, h as BioOAuthClient, i as CreateClientData, j as BioTokenPayload, V as VerifyOptions, J as JWKSVerifyOptions } from './types-
|
|
2
|
-
export {
|
|
1
|
+
import { B as BioAuthConfig, A as AuthorizeOptions, a as AuthorizeResult, T as TokenResponse, b as BioUser, I as IntrospectResult, c as BioAdminConfig, U as UserFilters, d as UpdateUserData, e as BioDepartment, C as CreateDepartmentData, f as BioRole, g as CreateRoleData, h as BioOAuthClient, i as CreateClientData, E as EmbedClientConfig, j as EmbedLoginParams, k as EmbedAuthResult, l as EmbedSignupParams, m as EmbedMagicLinkParams, n as EmbedVerifyParams, o as EmbedRefreshParams, p as EmbedLogoutParams, q as BioTokenPayload, V as VerifyOptions, J as JWKSVerifyOptions } from './types-CJe1FP61.js';
|
|
2
|
+
export { r as AdminResponse, s as BioAddress, t as BioClientTokenPayload, u as BioMessaging, v as BioUsersConfig, w as EmbedBranding, x as EmbedUser, O as OrgMember, y as OrgMemberFilters, z as OrgMembersResult } from './types-CJe1FP61.js';
|
|
3
3
|
export { AgencyProfile, AgencyProgram, AgencyStaffMember, AgentEmployer, AgentProfile, AppetiteMatchInput, AppetiteMatchProgram, AppetiteMatchResult, CarrierProfile, CarrierProgram, GraphClient, GraphClientConfig, ProgramProfile } from './graph.js';
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -105,6 +105,91 @@ declare class BioAdmin {
|
|
|
105
105
|
private request;
|
|
106
106
|
}
|
|
107
107
|
|
|
108
|
+
/**
|
|
109
|
+
* Client for Bio-ID headless embed endpoints.
|
|
110
|
+
*
|
|
111
|
+
* Use this when building custom login/signup UIs that authenticate
|
|
112
|
+
* directly against Bio-ID without redirects (no OAuth flow).
|
|
113
|
+
*
|
|
114
|
+
* All endpoints use X-Client-Id / X-Client-Secret header auth.
|
|
115
|
+
*
|
|
116
|
+
* @example
|
|
117
|
+
* ```typescript
|
|
118
|
+
* import { EmbedClient } from '@insureco/bio'
|
|
119
|
+
*
|
|
120
|
+
* const embed = EmbedClient.fromEnv()
|
|
121
|
+
*
|
|
122
|
+
* // Login
|
|
123
|
+
* const result = await embed.login({ email: 'user@example.com', password: 'secret' })
|
|
124
|
+
* console.log(result.accessToken, result.user.bioId)
|
|
125
|
+
*
|
|
126
|
+
* // Refresh
|
|
127
|
+
* const refreshed = await embed.refresh({ refreshToken: result.refreshToken })
|
|
128
|
+
*
|
|
129
|
+
* // Logout
|
|
130
|
+
* await embed.logout({ refreshToken: result.refreshToken })
|
|
131
|
+
* ```
|
|
132
|
+
*/
|
|
133
|
+
declare class EmbedClient {
|
|
134
|
+
private readonly bioIdUrl;
|
|
135
|
+
private readonly clientId;
|
|
136
|
+
private readonly clientSecret;
|
|
137
|
+
private readonly retries;
|
|
138
|
+
private readonly timeoutMs;
|
|
139
|
+
constructor(config: EmbedClientConfig);
|
|
140
|
+
/**
|
|
141
|
+
* Create an EmbedClient from environment variables.
|
|
142
|
+
*
|
|
143
|
+
* Reads: BIO_CLIENT_ID, BIO_CLIENT_SECRET, BIO_ID_URL
|
|
144
|
+
*/
|
|
145
|
+
static fromEnv(overrides?: Partial<EmbedClientConfig>): EmbedClient;
|
|
146
|
+
/**
|
|
147
|
+
* Authenticate a user with email and password.
|
|
148
|
+
*
|
|
149
|
+
* @param params - Email and password
|
|
150
|
+
* @returns Access token, refresh token, user profile, and optional branding
|
|
151
|
+
*/
|
|
152
|
+
login(params: EmbedLoginParams): Promise<EmbedAuthResult>;
|
|
153
|
+
/**
|
|
154
|
+
* Create a new user account.
|
|
155
|
+
*
|
|
156
|
+
* @param params - Email, password, name, and optional invite token
|
|
157
|
+
* @returns Access token, refresh token, user profile, and optional branding
|
|
158
|
+
*/
|
|
159
|
+
signup(params: EmbedSignupParams): Promise<EmbedAuthResult>;
|
|
160
|
+
/**
|
|
161
|
+
* Send a magic link email to the user.
|
|
162
|
+
*
|
|
163
|
+
* The user clicks the link to authenticate without a password.
|
|
164
|
+
* After sending, use `verify()` with the token from the link.
|
|
165
|
+
*
|
|
166
|
+
* @param params - Email address to send the magic link to
|
|
167
|
+
*/
|
|
168
|
+
sendMagicLink(params: EmbedMagicLinkParams): Promise<void>;
|
|
169
|
+
/**
|
|
170
|
+
* Verify a magic link token and exchange it for auth tokens.
|
|
171
|
+
*
|
|
172
|
+
* @param params - The token from the magic link
|
|
173
|
+
* @returns Access token, refresh token, user profile, and optional branding
|
|
174
|
+
*/
|
|
175
|
+
verify(params: EmbedVerifyParams): Promise<EmbedAuthResult>;
|
|
176
|
+
/**
|
|
177
|
+
* Refresh an expired access token using a refresh token.
|
|
178
|
+
*
|
|
179
|
+
* @param params - The refresh token to exchange
|
|
180
|
+
* @returns New access token, rotated refresh token, user profile, and optional branding
|
|
181
|
+
*/
|
|
182
|
+
refresh(params: EmbedRefreshParams): Promise<EmbedAuthResult>;
|
|
183
|
+
/**
|
|
184
|
+
* Revoke a refresh token (logout).
|
|
185
|
+
*
|
|
186
|
+
* @param params - The refresh token to revoke
|
|
187
|
+
*/
|
|
188
|
+
logout(params: EmbedLogoutParams): Promise<void>;
|
|
189
|
+
private embedRequest;
|
|
190
|
+
private fetchWithRetry;
|
|
191
|
+
}
|
|
192
|
+
|
|
108
193
|
/** Error thrown by Bio SDK operations */
|
|
109
194
|
declare class BioError extends Error {
|
|
110
195
|
/** HTTP status code (if from an API response) */
|
|
@@ -155,4 +240,4 @@ declare function isTokenExpired(token: string, bufferSeconds?: number): boolean;
|
|
|
155
240
|
*/
|
|
156
241
|
declare function verifyTokenJWKS(token: string, options?: JWKSVerifyOptions): Promise<BioTokenPayload>;
|
|
157
242
|
|
|
158
|
-
export { AuthorizeOptions, AuthorizeResult, BioAdmin, BioAdminConfig, BioAuth, BioAuthConfig, BioDepartment, BioError, BioOAuthClient, BioRole, BioTokenPayload, BioUser, CreateClientData, CreateDepartmentData, CreateRoleData, IntrospectResult, JWKSVerifyOptions, TokenResponse, UpdateUserData, UserFilters, VerifyOptions, decodeToken, generatePKCE, isTokenExpired, verifyToken, verifyTokenJWKS };
|
|
243
|
+
export { AuthorizeOptions, AuthorizeResult, BioAdmin, BioAdminConfig, BioAuth, BioAuthConfig, BioDepartment, BioError, BioOAuthClient, BioRole, BioTokenPayload, BioUser, CreateClientData, CreateDepartmentData, CreateRoleData, EmbedAuthResult, EmbedClient, EmbedClientConfig, EmbedLoginParams, EmbedLogoutParams, EmbedMagicLinkParams, EmbedRefreshParams, EmbedSignupParams, EmbedVerifyParams, IntrospectResult, JWKSVerifyOptions, TokenResponse, UpdateUserData, UserFilters, VerifyOptions, decodeToken, generatePKCE, isTokenExpired, verifyToken, verifyTokenJWKS };
|
package/dist/index.js
CHANGED
|
@@ -33,6 +33,7 @@ __export(index_exports, {
|
|
|
33
33
|
BioAdmin: () => BioAdmin,
|
|
34
34
|
BioAuth: () => BioAuth,
|
|
35
35
|
BioError: () => BioError,
|
|
36
|
+
EmbedClient: () => EmbedClient,
|
|
36
37
|
GraphClient: () => GraphClient,
|
|
37
38
|
decodeToken: () => decodeToken,
|
|
38
39
|
generatePKCE: () => generatePKCE,
|
|
@@ -586,6 +587,257 @@ var BioAdmin = class _BioAdmin {
|
|
|
586
587
|
}
|
|
587
588
|
};
|
|
588
589
|
|
|
590
|
+
// src/embed.ts
|
|
591
|
+
var DEFAULT_BIO_URL = "https://bio.tawa.pro";
|
|
592
|
+
var DEFAULT_TIMEOUT_MS3 = 1e4;
|
|
593
|
+
var EmbedClient = class _EmbedClient {
|
|
594
|
+
bioIdUrl;
|
|
595
|
+
clientId;
|
|
596
|
+
clientSecret;
|
|
597
|
+
retries;
|
|
598
|
+
timeoutMs;
|
|
599
|
+
constructor(config) {
|
|
600
|
+
if (!config.clientId) {
|
|
601
|
+
throw new BioError("clientId is required", "config_error");
|
|
602
|
+
}
|
|
603
|
+
if (!config.clientSecret) {
|
|
604
|
+
throw new BioError("clientSecret is required", "config_error");
|
|
605
|
+
}
|
|
606
|
+
this.clientId = config.clientId;
|
|
607
|
+
this.clientSecret = config.clientSecret;
|
|
608
|
+
this.bioIdUrl = (config.bioIdUrl ?? DEFAULT_BIO_URL).replace(/\/$/, "");
|
|
609
|
+
this.retries = config.retries ?? 2;
|
|
610
|
+
this.timeoutMs = config.timeoutMs ?? DEFAULT_TIMEOUT_MS3;
|
|
611
|
+
}
|
|
612
|
+
/**
|
|
613
|
+
* Create an EmbedClient from environment variables.
|
|
614
|
+
*
|
|
615
|
+
* Reads: BIO_CLIENT_ID, BIO_CLIENT_SECRET, BIO_ID_URL
|
|
616
|
+
*/
|
|
617
|
+
static fromEnv(overrides) {
|
|
618
|
+
const clientId = overrides?.clientId ?? process.env.BIO_CLIENT_ID;
|
|
619
|
+
const clientSecret = overrides?.clientSecret ?? process.env.BIO_CLIENT_SECRET;
|
|
620
|
+
if (!clientId) {
|
|
621
|
+
throw new BioError(
|
|
622
|
+
"BIO_CLIENT_ID environment variable is required",
|
|
623
|
+
"config_error"
|
|
624
|
+
);
|
|
625
|
+
}
|
|
626
|
+
if (!clientSecret) {
|
|
627
|
+
throw new BioError(
|
|
628
|
+
"BIO_CLIENT_SECRET environment variable is required",
|
|
629
|
+
"config_error"
|
|
630
|
+
);
|
|
631
|
+
}
|
|
632
|
+
return new _EmbedClient({
|
|
633
|
+
clientId,
|
|
634
|
+
clientSecret,
|
|
635
|
+
bioIdUrl: overrides?.bioIdUrl ?? process.env.BIO_ID_URL,
|
|
636
|
+
retries: overrides?.retries,
|
|
637
|
+
timeoutMs: overrides?.timeoutMs
|
|
638
|
+
});
|
|
639
|
+
}
|
|
640
|
+
/**
|
|
641
|
+
* Authenticate a user with email and password.
|
|
642
|
+
*
|
|
643
|
+
* @param params - Email and password
|
|
644
|
+
* @returns Access token, refresh token, user profile, and optional branding
|
|
645
|
+
*/
|
|
646
|
+
async login(params) {
|
|
647
|
+
if (!params.email) throw new BioError("email is required", "validation_error");
|
|
648
|
+
if (!params.password) throw new BioError("password is required", "validation_error");
|
|
649
|
+
return this.embedRequest("/api/embed/login", {
|
|
650
|
+
email: params.email,
|
|
651
|
+
password: params.password
|
|
652
|
+
});
|
|
653
|
+
}
|
|
654
|
+
/**
|
|
655
|
+
* Create a new user account.
|
|
656
|
+
*
|
|
657
|
+
* @param params - Email, password, name, and optional invite token
|
|
658
|
+
* @returns Access token, refresh token, user profile, and optional branding
|
|
659
|
+
*/
|
|
660
|
+
async signup(params) {
|
|
661
|
+
if (!params.email) throw new BioError("email is required", "validation_error");
|
|
662
|
+
if (!params.password) throw new BioError("password is required", "validation_error");
|
|
663
|
+
if (!params.name) throw new BioError("name is required", "validation_error");
|
|
664
|
+
const body = {
|
|
665
|
+
email: params.email,
|
|
666
|
+
password: params.password,
|
|
667
|
+
name: params.name
|
|
668
|
+
};
|
|
669
|
+
if (params.inviteToken) {
|
|
670
|
+
body.inviteToken = params.inviteToken;
|
|
671
|
+
}
|
|
672
|
+
return this.embedRequest("/api/embed/signup", body);
|
|
673
|
+
}
|
|
674
|
+
/**
|
|
675
|
+
* Send a magic link email to the user.
|
|
676
|
+
*
|
|
677
|
+
* The user clicks the link to authenticate without a password.
|
|
678
|
+
* After sending, use `verify()` with the token from the link.
|
|
679
|
+
*
|
|
680
|
+
* @param params - Email address to send the magic link to
|
|
681
|
+
*/
|
|
682
|
+
async sendMagicLink(params) {
|
|
683
|
+
if (!params.email) throw new BioError("email is required", "validation_error");
|
|
684
|
+
const response = await this.fetchWithRetry(
|
|
685
|
+
"POST",
|
|
686
|
+
`${this.bioIdUrl}/api/embed/magic-link`,
|
|
687
|
+
JSON.stringify({ email: params.email })
|
|
688
|
+
);
|
|
689
|
+
const json = await parseJsonResponse(response);
|
|
690
|
+
if (!response.ok) {
|
|
691
|
+
throw new BioError(
|
|
692
|
+
extractErrorMessage(json, response.status),
|
|
693
|
+
extractErrorCode(json),
|
|
694
|
+
response.status,
|
|
695
|
+
json
|
|
696
|
+
);
|
|
697
|
+
}
|
|
698
|
+
}
|
|
699
|
+
/**
|
|
700
|
+
* Verify a magic link token and exchange it for auth tokens.
|
|
701
|
+
*
|
|
702
|
+
* @param params - The token from the magic link
|
|
703
|
+
* @returns Access token, refresh token, user profile, and optional branding
|
|
704
|
+
*/
|
|
705
|
+
async verify(params) {
|
|
706
|
+
if (!params.token) throw new BioError("token is required", "validation_error");
|
|
707
|
+
return this.embedRequest("/api/embed/verify", {
|
|
708
|
+
token: params.token
|
|
709
|
+
});
|
|
710
|
+
}
|
|
711
|
+
/**
|
|
712
|
+
* Refresh an expired access token using a refresh token.
|
|
713
|
+
*
|
|
714
|
+
* @param params - The refresh token to exchange
|
|
715
|
+
* @returns New access token, rotated refresh token, user profile, and optional branding
|
|
716
|
+
*/
|
|
717
|
+
async refresh(params) {
|
|
718
|
+
if (!params.refreshToken) throw new BioError("refreshToken is required", "validation_error");
|
|
719
|
+
return this.embedRequest("/api/embed/refresh", {
|
|
720
|
+
refreshToken: params.refreshToken
|
|
721
|
+
});
|
|
722
|
+
}
|
|
723
|
+
/**
|
|
724
|
+
* Revoke a refresh token (logout).
|
|
725
|
+
*
|
|
726
|
+
* @param params - The refresh token to revoke
|
|
727
|
+
*/
|
|
728
|
+
async logout(params) {
|
|
729
|
+
if (!params.refreshToken) throw new BioError("refreshToken is required", "validation_error");
|
|
730
|
+
const response = await this.fetchWithRetry(
|
|
731
|
+
"POST",
|
|
732
|
+
`${this.bioIdUrl}/api/embed/logout`,
|
|
733
|
+
JSON.stringify({ refreshToken: params.refreshToken })
|
|
734
|
+
);
|
|
735
|
+
const json = await parseJsonResponse(response);
|
|
736
|
+
if (!response.ok) {
|
|
737
|
+
throw new BioError(
|
|
738
|
+
extractErrorMessage(json, response.status),
|
|
739
|
+
extractErrorCode(json),
|
|
740
|
+
response.status,
|
|
741
|
+
json
|
|
742
|
+
);
|
|
743
|
+
}
|
|
744
|
+
}
|
|
745
|
+
// ── Private helpers ──────────────────────────────────────────────────────
|
|
746
|
+
async embedRequest(path, body) {
|
|
747
|
+
const response = await this.fetchWithRetry(
|
|
748
|
+
"POST",
|
|
749
|
+
`${this.bioIdUrl}${path}`,
|
|
750
|
+
JSON.stringify(body)
|
|
751
|
+
);
|
|
752
|
+
const json = await parseJsonResponse(response);
|
|
753
|
+
if (!response.ok) {
|
|
754
|
+
throw new BioError(
|
|
755
|
+
extractErrorMessage(json, response.status),
|
|
756
|
+
extractErrorCode(json),
|
|
757
|
+
response.status,
|
|
758
|
+
json
|
|
759
|
+
);
|
|
760
|
+
}
|
|
761
|
+
return mapEmbedResponse(json);
|
|
762
|
+
}
|
|
763
|
+
async fetchWithRetry(method, url, body, attempt = 0) {
|
|
764
|
+
try {
|
|
765
|
+
const response = await fetch(url, {
|
|
766
|
+
method,
|
|
767
|
+
headers: {
|
|
768
|
+
"Content-Type": "application/json",
|
|
769
|
+
"X-Client-Id": this.clientId,
|
|
770
|
+
"X-Client-Secret": this.clientSecret
|
|
771
|
+
},
|
|
772
|
+
body,
|
|
773
|
+
signal: AbortSignal.timeout(this.timeoutMs)
|
|
774
|
+
});
|
|
775
|
+
if (response.status >= 500 && attempt < this.retries) {
|
|
776
|
+
await sleep(retryDelay(attempt));
|
|
777
|
+
return this.fetchWithRetry(method, url, body, attempt + 1);
|
|
778
|
+
}
|
|
779
|
+
return response;
|
|
780
|
+
} catch (err) {
|
|
781
|
+
if (attempt < this.retries) {
|
|
782
|
+
await sleep(retryDelay(attempt));
|
|
783
|
+
return this.fetchWithRetry(method, url, body, attempt + 1);
|
|
784
|
+
}
|
|
785
|
+
const isTimeout = err instanceof DOMException && err.name === "TimeoutError";
|
|
786
|
+
throw new BioError(
|
|
787
|
+
isTimeout ? `Request timed out after ${this.timeoutMs}ms` : err instanceof Error ? err.message : "Network error",
|
|
788
|
+
isTimeout ? "timeout" : "network_error"
|
|
789
|
+
);
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
};
|
|
793
|
+
function mapEmbedResponse(raw) {
|
|
794
|
+
const data = raw.data ?? raw;
|
|
795
|
+
const rawUser = data.user ?? {};
|
|
796
|
+
const rawBranding = data.branding;
|
|
797
|
+
const user = {
|
|
798
|
+
bioId: rawUser.bioId,
|
|
799
|
+
email: rawUser.email,
|
|
800
|
+
name: rawUser.name,
|
|
801
|
+
orgSlug: rawUser.orgSlug
|
|
802
|
+
};
|
|
803
|
+
const result = {
|
|
804
|
+
accessToken: data.access_token,
|
|
805
|
+
refreshToken: data.refresh_token,
|
|
806
|
+
tokenType: data.token_type ?? "Bearer",
|
|
807
|
+
expiresIn: data.expires_in,
|
|
808
|
+
user
|
|
809
|
+
};
|
|
810
|
+
if (rawBranding) {
|
|
811
|
+
result.branding = {
|
|
812
|
+
displayName: rawBranding.displayName,
|
|
813
|
+
logoUrl: rawBranding.logoUrl,
|
|
814
|
+
logoMarkUrl: rawBranding.logoMarkUrl,
|
|
815
|
+
primaryColor: rawBranding.primaryColor,
|
|
816
|
+
secondaryColor: rawBranding.secondaryColor,
|
|
817
|
+
verified: rawBranding.verified,
|
|
818
|
+
whiteLabelApproved: rawBranding.whiteLabelApproved
|
|
819
|
+
};
|
|
820
|
+
}
|
|
821
|
+
return result;
|
|
822
|
+
}
|
|
823
|
+
function extractErrorMessage(json, status) {
|
|
824
|
+
const error = json.error;
|
|
825
|
+
if (typeof error === "object" && error !== null) {
|
|
826
|
+
return error.message ?? `Embed API returned ${status}`;
|
|
827
|
+
}
|
|
828
|
+
if (typeof error === "string") {
|
|
829
|
+
return error;
|
|
830
|
+
}
|
|
831
|
+
return `Embed API returned ${status}`;
|
|
832
|
+
}
|
|
833
|
+
function extractErrorCode(json) {
|
|
834
|
+
const error = json.error;
|
|
835
|
+
if (typeof error === "object" && error !== null) {
|
|
836
|
+
return error.code ?? "embed_error";
|
|
837
|
+
}
|
|
838
|
+
return "embed_error";
|
|
839
|
+
}
|
|
840
|
+
|
|
589
841
|
// src/jwt.ts
|
|
590
842
|
var import_node_crypto3 = __toESM(require("crypto"));
|
|
591
843
|
var DEFAULT_ISSUERS = [
|
|
@@ -740,7 +992,7 @@ async function verifyTokenJWKS(token, options) {
|
|
|
740
992
|
}
|
|
741
993
|
|
|
742
994
|
// src/graph.ts
|
|
743
|
-
var
|
|
995
|
+
var DEFAULT_TIMEOUT_MS4 = 1e4;
|
|
744
996
|
var BIO_GRAPH_URL = "https://bio-graph.tawa.pro";
|
|
745
997
|
var GraphClient = class _GraphClient {
|
|
746
998
|
graphUrl;
|
|
@@ -749,7 +1001,7 @@ var GraphClient = class _GraphClient {
|
|
|
749
1001
|
constructor(config = {}) {
|
|
750
1002
|
this.graphUrl = (config.graphUrl ?? process.env.BIO_GRAPH_URL ?? BIO_GRAPH_URL).replace(/\/$/, "");
|
|
751
1003
|
this.accessToken = config.accessToken;
|
|
752
|
-
this.timeoutMs = config.timeoutMs ??
|
|
1004
|
+
this.timeoutMs = config.timeoutMs ?? DEFAULT_TIMEOUT_MS4;
|
|
753
1005
|
}
|
|
754
1006
|
/**
|
|
755
1007
|
* Create a GraphClient from environment variables.
|
|
@@ -902,6 +1154,7 @@ var GraphClient = class _GraphClient {
|
|
|
902
1154
|
BioAdmin,
|
|
903
1155
|
BioAuth,
|
|
904
1156
|
BioError,
|
|
1157
|
+
EmbedClient,
|
|
905
1158
|
GraphClient,
|
|
906
1159
|
decodeToken,
|
|
907
1160
|
generatePKCE,
|
package/dist/index.mjs
CHANGED
|
@@ -515,6 +515,257 @@ var BioAdmin = class _BioAdmin {
|
|
|
515
515
|
}
|
|
516
516
|
};
|
|
517
517
|
|
|
518
|
+
// src/embed.ts
|
|
519
|
+
var DEFAULT_BIO_URL = "https://bio.tawa.pro";
|
|
520
|
+
var DEFAULT_TIMEOUT_MS3 = 1e4;
|
|
521
|
+
var EmbedClient = class _EmbedClient {
|
|
522
|
+
bioIdUrl;
|
|
523
|
+
clientId;
|
|
524
|
+
clientSecret;
|
|
525
|
+
retries;
|
|
526
|
+
timeoutMs;
|
|
527
|
+
constructor(config) {
|
|
528
|
+
if (!config.clientId) {
|
|
529
|
+
throw new BioError("clientId is required", "config_error");
|
|
530
|
+
}
|
|
531
|
+
if (!config.clientSecret) {
|
|
532
|
+
throw new BioError("clientSecret is required", "config_error");
|
|
533
|
+
}
|
|
534
|
+
this.clientId = config.clientId;
|
|
535
|
+
this.clientSecret = config.clientSecret;
|
|
536
|
+
this.bioIdUrl = (config.bioIdUrl ?? DEFAULT_BIO_URL).replace(/\/$/, "");
|
|
537
|
+
this.retries = config.retries ?? 2;
|
|
538
|
+
this.timeoutMs = config.timeoutMs ?? DEFAULT_TIMEOUT_MS3;
|
|
539
|
+
}
|
|
540
|
+
/**
|
|
541
|
+
* Create an EmbedClient from environment variables.
|
|
542
|
+
*
|
|
543
|
+
* Reads: BIO_CLIENT_ID, BIO_CLIENT_SECRET, BIO_ID_URL
|
|
544
|
+
*/
|
|
545
|
+
static fromEnv(overrides) {
|
|
546
|
+
const clientId = overrides?.clientId ?? process.env.BIO_CLIENT_ID;
|
|
547
|
+
const clientSecret = overrides?.clientSecret ?? process.env.BIO_CLIENT_SECRET;
|
|
548
|
+
if (!clientId) {
|
|
549
|
+
throw new BioError(
|
|
550
|
+
"BIO_CLIENT_ID environment variable is required",
|
|
551
|
+
"config_error"
|
|
552
|
+
);
|
|
553
|
+
}
|
|
554
|
+
if (!clientSecret) {
|
|
555
|
+
throw new BioError(
|
|
556
|
+
"BIO_CLIENT_SECRET environment variable is required",
|
|
557
|
+
"config_error"
|
|
558
|
+
);
|
|
559
|
+
}
|
|
560
|
+
return new _EmbedClient({
|
|
561
|
+
clientId,
|
|
562
|
+
clientSecret,
|
|
563
|
+
bioIdUrl: overrides?.bioIdUrl ?? process.env.BIO_ID_URL,
|
|
564
|
+
retries: overrides?.retries,
|
|
565
|
+
timeoutMs: overrides?.timeoutMs
|
|
566
|
+
});
|
|
567
|
+
}
|
|
568
|
+
/**
|
|
569
|
+
* Authenticate a user with email and password.
|
|
570
|
+
*
|
|
571
|
+
* @param params - Email and password
|
|
572
|
+
* @returns Access token, refresh token, user profile, and optional branding
|
|
573
|
+
*/
|
|
574
|
+
async login(params) {
|
|
575
|
+
if (!params.email) throw new BioError("email is required", "validation_error");
|
|
576
|
+
if (!params.password) throw new BioError("password is required", "validation_error");
|
|
577
|
+
return this.embedRequest("/api/embed/login", {
|
|
578
|
+
email: params.email,
|
|
579
|
+
password: params.password
|
|
580
|
+
});
|
|
581
|
+
}
|
|
582
|
+
/**
|
|
583
|
+
* Create a new user account.
|
|
584
|
+
*
|
|
585
|
+
* @param params - Email, password, name, and optional invite token
|
|
586
|
+
* @returns Access token, refresh token, user profile, and optional branding
|
|
587
|
+
*/
|
|
588
|
+
async signup(params) {
|
|
589
|
+
if (!params.email) throw new BioError("email is required", "validation_error");
|
|
590
|
+
if (!params.password) throw new BioError("password is required", "validation_error");
|
|
591
|
+
if (!params.name) throw new BioError("name is required", "validation_error");
|
|
592
|
+
const body = {
|
|
593
|
+
email: params.email,
|
|
594
|
+
password: params.password,
|
|
595
|
+
name: params.name
|
|
596
|
+
};
|
|
597
|
+
if (params.inviteToken) {
|
|
598
|
+
body.inviteToken = params.inviteToken;
|
|
599
|
+
}
|
|
600
|
+
return this.embedRequest("/api/embed/signup", body);
|
|
601
|
+
}
|
|
602
|
+
/**
|
|
603
|
+
* Send a magic link email to the user.
|
|
604
|
+
*
|
|
605
|
+
* The user clicks the link to authenticate without a password.
|
|
606
|
+
* After sending, use `verify()` with the token from the link.
|
|
607
|
+
*
|
|
608
|
+
* @param params - Email address to send the magic link to
|
|
609
|
+
*/
|
|
610
|
+
async sendMagicLink(params) {
|
|
611
|
+
if (!params.email) throw new BioError("email is required", "validation_error");
|
|
612
|
+
const response = await this.fetchWithRetry(
|
|
613
|
+
"POST",
|
|
614
|
+
`${this.bioIdUrl}/api/embed/magic-link`,
|
|
615
|
+
JSON.stringify({ email: params.email })
|
|
616
|
+
);
|
|
617
|
+
const json = await parseJsonResponse(response);
|
|
618
|
+
if (!response.ok) {
|
|
619
|
+
throw new BioError(
|
|
620
|
+
extractErrorMessage(json, response.status),
|
|
621
|
+
extractErrorCode(json),
|
|
622
|
+
response.status,
|
|
623
|
+
json
|
|
624
|
+
);
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
/**
|
|
628
|
+
* Verify a magic link token and exchange it for auth tokens.
|
|
629
|
+
*
|
|
630
|
+
* @param params - The token from the magic link
|
|
631
|
+
* @returns Access token, refresh token, user profile, and optional branding
|
|
632
|
+
*/
|
|
633
|
+
async verify(params) {
|
|
634
|
+
if (!params.token) throw new BioError("token is required", "validation_error");
|
|
635
|
+
return this.embedRequest("/api/embed/verify", {
|
|
636
|
+
token: params.token
|
|
637
|
+
});
|
|
638
|
+
}
|
|
639
|
+
/**
|
|
640
|
+
* Refresh an expired access token using a refresh token.
|
|
641
|
+
*
|
|
642
|
+
* @param params - The refresh token to exchange
|
|
643
|
+
* @returns New access token, rotated refresh token, user profile, and optional branding
|
|
644
|
+
*/
|
|
645
|
+
async refresh(params) {
|
|
646
|
+
if (!params.refreshToken) throw new BioError("refreshToken is required", "validation_error");
|
|
647
|
+
return this.embedRequest("/api/embed/refresh", {
|
|
648
|
+
refreshToken: params.refreshToken
|
|
649
|
+
});
|
|
650
|
+
}
|
|
651
|
+
/**
|
|
652
|
+
* Revoke a refresh token (logout).
|
|
653
|
+
*
|
|
654
|
+
* @param params - The refresh token to revoke
|
|
655
|
+
*/
|
|
656
|
+
async logout(params) {
|
|
657
|
+
if (!params.refreshToken) throw new BioError("refreshToken is required", "validation_error");
|
|
658
|
+
const response = await this.fetchWithRetry(
|
|
659
|
+
"POST",
|
|
660
|
+
`${this.bioIdUrl}/api/embed/logout`,
|
|
661
|
+
JSON.stringify({ refreshToken: params.refreshToken })
|
|
662
|
+
);
|
|
663
|
+
const json = await parseJsonResponse(response);
|
|
664
|
+
if (!response.ok) {
|
|
665
|
+
throw new BioError(
|
|
666
|
+
extractErrorMessage(json, response.status),
|
|
667
|
+
extractErrorCode(json),
|
|
668
|
+
response.status,
|
|
669
|
+
json
|
|
670
|
+
);
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
// ── Private helpers ──────────────────────────────────────────────────────
|
|
674
|
+
async embedRequest(path, body) {
|
|
675
|
+
const response = await this.fetchWithRetry(
|
|
676
|
+
"POST",
|
|
677
|
+
`${this.bioIdUrl}${path}`,
|
|
678
|
+
JSON.stringify(body)
|
|
679
|
+
);
|
|
680
|
+
const json = await parseJsonResponse(response);
|
|
681
|
+
if (!response.ok) {
|
|
682
|
+
throw new BioError(
|
|
683
|
+
extractErrorMessage(json, response.status),
|
|
684
|
+
extractErrorCode(json),
|
|
685
|
+
response.status,
|
|
686
|
+
json
|
|
687
|
+
);
|
|
688
|
+
}
|
|
689
|
+
return mapEmbedResponse(json);
|
|
690
|
+
}
|
|
691
|
+
async fetchWithRetry(method, url, body, attempt = 0) {
|
|
692
|
+
try {
|
|
693
|
+
const response = await fetch(url, {
|
|
694
|
+
method,
|
|
695
|
+
headers: {
|
|
696
|
+
"Content-Type": "application/json",
|
|
697
|
+
"X-Client-Id": this.clientId,
|
|
698
|
+
"X-Client-Secret": this.clientSecret
|
|
699
|
+
},
|
|
700
|
+
body,
|
|
701
|
+
signal: AbortSignal.timeout(this.timeoutMs)
|
|
702
|
+
});
|
|
703
|
+
if (response.status >= 500 && attempt < this.retries) {
|
|
704
|
+
await sleep(retryDelay(attempt));
|
|
705
|
+
return this.fetchWithRetry(method, url, body, attempt + 1);
|
|
706
|
+
}
|
|
707
|
+
return response;
|
|
708
|
+
} catch (err) {
|
|
709
|
+
if (attempt < this.retries) {
|
|
710
|
+
await sleep(retryDelay(attempt));
|
|
711
|
+
return this.fetchWithRetry(method, url, body, attempt + 1);
|
|
712
|
+
}
|
|
713
|
+
const isTimeout = err instanceof DOMException && err.name === "TimeoutError";
|
|
714
|
+
throw new BioError(
|
|
715
|
+
isTimeout ? `Request timed out after ${this.timeoutMs}ms` : err instanceof Error ? err.message : "Network error",
|
|
716
|
+
isTimeout ? "timeout" : "network_error"
|
|
717
|
+
);
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
};
|
|
721
|
+
function mapEmbedResponse(raw) {
|
|
722
|
+
const data = raw.data ?? raw;
|
|
723
|
+
const rawUser = data.user ?? {};
|
|
724
|
+
const rawBranding = data.branding;
|
|
725
|
+
const user = {
|
|
726
|
+
bioId: rawUser.bioId,
|
|
727
|
+
email: rawUser.email,
|
|
728
|
+
name: rawUser.name,
|
|
729
|
+
orgSlug: rawUser.orgSlug
|
|
730
|
+
};
|
|
731
|
+
const result = {
|
|
732
|
+
accessToken: data.access_token,
|
|
733
|
+
refreshToken: data.refresh_token,
|
|
734
|
+
tokenType: data.token_type ?? "Bearer",
|
|
735
|
+
expiresIn: data.expires_in,
|
|
736
|
+
user
|
|
737
|
+
};
|
|
738
|
+
if (rawBranding) {
|
|
739
|
+
result.branding = {
|
|
740
|
+
displayName: rawBranding.displayName,
|
|
741
|
+
logoUrl: rawBranding.logoUrl,
|
|
742
|
+
logoMarkUrl: rawBranding.logoMarkUrl,
|
|
743
|
+
primaryColor: rawBranding.primaryColor,
|
|
744
|
+
secondaryColor: rawBranding.secondaryColor,
|
|
745
|
+
verified: rawBranding.verified,
|
|
746
|
+
whiteLabelApproved: rawBranding.whiteLabelApproved
|
|
747
|
+
};
|
|
748
|
+
}
|
|
749
|
+
return result;
|
|
750
|
+
}
|
|
751
|
+
function extractErrorMessage(json, status) {
|
|
752
|
+
const error = json.error;
|
|
753
|
+
if (typeof error === "object" && error !== null) {
|
|
754
|
+
return error.message ?? `Embed API returned ${status}`;
|
|
755
|
+
}
|
|
756
|
+
if (typeof error === "string") {
|
|
757
|
+
return error;
|
|
758
|
+
}
|
|
759
|
+
return `Embed API returned ${status}`;
|
|
760
|
+
}
|
|
761
|
+
function extractErrorCode(json) {
|
|
762
|
+
const error = json.error;
|
|
763
|
+
if (typeof error === "object" && error !== null) {
|
|
764
|
+
return error.code ?? "embed_error";
|
|
765
|
+
}
|
|
766
|
+
return "embed_error";
|
|
767
|
+
}
|
|
768
|
+
|
|
518
769
|
// src/jwt.ts
|
|
519
770
|
import crypto3 from "crypto";
|
|
520
771
|
var DEFAULT_ISSUERS = [
|
|
@@ -671,6 +922,7 @@ export {
|
|
|
671
922
|
BioAdmin,
|
|
672
923
|
BioAuth,
|
|
673
924
|
BioError,
|
|
925
|
+
EmbedClient,
|
|
674
926
|
GraphClient,
|
|
675
927
|
decodeToken,
|
|
676
928
|
generatePKCE,
|
|
@@ -298,5 +298,99 @@ interface AdminResponse<T> {
|
|
|
298
298
|
limit: number;
|
|
299
299
|
};
|
|
300
300
|
}
|
|
301
|
+
/** Configuration for EmbedClient (headless embed auth) */
|
|
302
|
+
interface EmbedClientConfig {
|
|
303
|
+
/** OAuth client ID (env: BIO_CLIENT_ID) */
|
|
304
|
+
clientId: string;
|
|
305
|
+
/** OAuth client secret (env: BIO_CLIENT_SECRET) */
|
|
306
|
+
clientSecret: string;
|
|
307
|
+
/** Bio-ID base URL (env: BIO_ID_URL, default: https://bio.tawa.pro) */
|
|
308
|
+
bioIdUrl?: string;
|
|
309
|
+
/** Number of retry attempts on transient failures (default: 2) */
|
|
310
|
+
retries?: number;
|
|
311
|
+
/** Request timeout in milliseconds (default: 10000) */
|
|
312
|
+
timeoutMs?: number;
|
|
313
|
+
}
|
|
314
|
+
/** Parameters for embed login */
|
|
315
|
+
interface EmbedLoginParams {
|
|
316
|
+
/** User email address */
|
|
317
|
+
email: string;
|
|
318
|
+
/** User password */
|
|
319
|
+
password: string;
|
|
320
|
+
}
|
|
321
|
+
/** Parameters for embed signup */
|
|
322
|
+
interface EmbedSignupParams {
|
|
323
|
+
/** User email address */
|
|
324
|
+
email: string;
|
|
325
|
+
/** User password */
|
|
326
|
+
password: string;
|
|
327
|
+
/** Display name */
|
|
328
|
+
name: string;
|
|
329
|
+
/** Optional invite token for org-scoped signups */
|
|
330
|
+
inviteToken?: string;
|
|
331
|
+
}
|
|
332
|
+
/** Parameters for sending a magic link */
|
|
333
|
+
interface EmbedMagicLinkParams {
|
|
334
|
+
/** Email address to send the magic link to */
|
|
335
|
+
email: string;
|
|
336
|
+
}
|
|
337
|
+
/** Parameters for verifying a magic link token */
|
|
338
|
+
interface EmbedVerifyParams {
|
|
339
|
+
/** Magic link token from the email */
|
|
340
|
+
token: string;
|
|
341
|
+
}
|
|
342
|
+
/** Parameters for refreshing an access token */
|
|
343
|
+
interface EmbedRefreshParams {
|
|
344
|
+
/** Refresh token from a previous login/signup/verify/refresh */
|
|
345
|
+
refreshToken: string;
|
|
346
|
+
}
|
|
347
|
+
/** Parameters for logout (token revocation) */
|
|
348
|
+
interface EmbedLogoutParams {
|
|
349
|
+
/** Refresh token to revoke */
|
|
350
|
+
refreshToken: string;
|
|
351
|
+
}
|
|
352
|
+
/** User profile returned by embed endpoints */
|
|
353
|
+
interface EmbedUser {
|
|
354
|
+
/** Unique Bio-ID identifier */
|
|
355
|
+
bioId: string;
|
|
356
|
+
/** User email address */
|
|
357
|
+
email: string;
|
|
358
|
+
/** Display name */
|
|
359
|
+
name: string;
|
|
360
|
+
/** Organization slug (if the user belongs to an org) */
|
|
361
|
+
orgSlug?: string;
|
|
362
|
+
}
|
|
363
|
+
/** Branding data returned by embed endpoints */
|
|
364
|
+
interface EmbedBranding {
|
|
365
|
+
/** Organization display name */
|
|
366
|
+
displayName?: string;
|
|
367
|
+
/** Full logo URL */
|
|
368
|
+
logoUrl?: string;
|
|
369
|
+
/** Logo mark (icon) URL */
|
|
370
|
+
logoMarkUrl?: string;
|
|
371
|
+
/** Primary brand color (hex) */
|
|
372
|
+
primaryColor?: string;
|
|
373
|
+
/** Secondary brand color (hex) */
|
|
374
|
+
secondaryColor?: string;
|
|
375
|
+
/** Whether the org is verified */
|
|
376
|
+
verified?: boolean;
|
|
377
|
+
/** Whether white-label is approved for this org */
|
|
378
|
+
whiteLabelApproved?: boolean;
|
|
379
|
+
}
|
|
380
|
+
/** Auth result from embed login, signup, verify, or refresh */
|
|
381
|
+
interface EmbedAuthResult {
|
|
382
|
+
/** JWT access token */
|
|
383
|
+
accessToken: string;
|
|
384
|
+
/** Refresh token (use with refresh() or logout()) */
|
|
385
|
+
refreshToken: string;
|
|
386
|
+
/** Token type (always 'Bearer') */
|
|
387
|
+
tokenType: 'Bearer';
|
|
388
|
+
/** Access token lifetime in seconds */
|
|
389
|
+
expiresIn: number;
|
|
390
|
+
/** Authenticated user profile */
|
|
391
|
+
user: EmbedUser;
|
|
392
|
+
/** Optional org branding (present when the user belongs to a branded org) */
|
|
393
|
+
branding?: EmbedBranding;
|
|
394
|
+
}
|
|
301
395
|
|
|
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,
|
|
396
|
+
export type { AuthorizeOptions as A, BioAuthConfig as B, CreateDepartmentData as C, EmbedClientConfig as E, 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, EmbedLoginParams as j, EmbedAuthResult as k, EmbedSignupParams as l, EmbedMagicLinkParams as m, EmbedVerifyParams as n, EmbedRefreshParams as o, EmbedLogoutParams as p, BioTokenPayload as q, AdminResponse as r, BioAddress as s, BioClientTokenPayload as t, BioMessaging as u, BioUsersConfig as v, EmbedBranding as w, EmbedUser as x, OrgMemberFilters as y, OrgMembersResult as z };
|
|
@@ -298,5 +298,99 @@ interface AdminResponse<T> {
|
|
|
298
298
|
limit: number;
|
|
299
299
|
};
|
|
300
300
|
}
|
|
301
|
+
/** Configuration for EmbedClient (headless embed auth) */
|
|
302
|
+
interface EmbedClientConfig {
|
|
303
|
+
/** OAuth client ID (env: BIO_CLIENT_ID) */
|
|
304
|
+
clientId: string;
|
|
305
|
+
/** OAuth client secret (env: BIO_CLIENT_SECRET) */
|
|
306
|
+
clientSecret: string;
|
|
307
|
+
/** Bio-ID base URL (env: BIO_ID_URL, default: https://bio.tawa.pro) */
|
|
308
|
+
bioIdUrl?: string;
|
|
309
|
+
/** Number of retry attempts on transient failures (default: 2) */
|
|
310
|
+
retries?: number;
|
|
311
|
+
/** Request timeout in milliseconds (default: 10000) */
|
|
312
|
+
timeoutMs?: number;
|
|
313
|
+
}
|
|
314
|
+
/** Parameters for embed login */
|
|
315
|
+
interface EmbedLoginParams {
|
|
316
|
+
/** User email address */
|
|
317
|
+
email: string;
|
|
318
|
+
/** User password */
|
|
319
|
+
password: string;
|
|
320
|
+
}
|
|
321
|
+
/** Parameters for embed signup */
|
|
322
|
+
interface EmbedSignupParams {
|
|
323
|
+
/** User email address */
|
|
324
|
+
email: string;
|
|
325
|
+
/** User password */
|
|
326
|
+
password: string;
|
|
327
|
+
/** Display name */
|
|
328
|
+
name: string;
|
|
329
|
+
/** Optional invite token for org-scoped signups */
|
|
330
|
+
inviteToken?: string;
|
|
331
|
+
}
|
|
332
|
+
/** Parameters for sending a magic link */
|
|
333
|
+
interface EmbedMagicLinkParams {
|
|
334
|
+
/** Email address to send the magic link to */
|
|
335
|
+
email: string;
|
|
336
|
+
}
|
|
337
|
+
/** Parameters for verifying a magic link token */
|
|
338
|
+
interface EmbedVerifyParams {
|
|
339
|
+
/** Magic link token from the email */
|
|
340
|
+
token: string;
|
|
341
|
+
}
|
|
342
|
+
/** Parameters for refreshing an access token */
|
|
343
|
+
interface EmbedRefreshParams {
|
|
344
|
+
/** Refresh token from a previous login/signup/verify/refresh */
|
|
345
|
+
refreshToken: string;
|
|
346
|
+
}
|
|
347
|
+
/** Parameters for logout (token revocation) */
|
|
348
|
+
interface EmbedLogoutParams {
|
|
349
|
+
/** Refresh token to revoke */
|
|
350
|
+
refreshToken: string;
|
|
351
|
+
}
|
|
352
|
+
/** User profile returned by embed endpoints */
|
|
353
|
+
interface EmbedUser {
|
|
354
|
+
/** Unique Bio-ID identifier */
|
|
355
|
+
bioId: string;
|
|
356
|
+
/** User email address */
|
|
357
|
+
email: string;
|
|
358
|
+
/** Display name */
|
|
359
|
+
name: string;
|
|
360
|
+
/** Organization slug (if the user belongs to an org) */
|
|
361
|
+
orgSlug?: string;
|
|
362
|
+
}
|
|
363
|
+
/** Branding data returned by embed endpoints */
|
|
364
|
+
interface EmbedBranding {
|
|
365
|
+
/** Organization display name */
|
|
366
|
+
displayName?: string;
|
|
367
|
+
/** Full logo URL */
|
|
368
|
+
logoUrl?: string;
|
|
369
|
+
/** Logo mark (icon) URL */
|
|
370
|
+
logoMarkUrl?: string;
|
|
371
|
+
/** Primary brand color (hex) */
|
|
372
|
+
primaryColor?: string;
|
|
373
|
+
/** Secondary brand color (hex) */
|
|
374
|
+
secondaryColor?: string;
|
|
375
|
+
/** Whether the org is verified */
|
|
376
|
+
verified?: boolean;
|
|
377
|
+
/** Whether white-label is approved for this org */
|
|
378
|
+
whiteLabelApproved?: boolean;
|
|
379
|
+
}
|
|
380
|
+
/** Auth result from embed login, signup, verify, or refresh */
|
|
381
|
+
interface EmbedAuthResult {
|
|
382
|
+
/** JWT access token */
|
|
383
|
+
accessToken: string;
|
|
384
|
+
/** Refresh token (use with refresh() or logout()) */
|
|
385
|
+
refreshToken: string;
|
|
386
|
+
/** Token type (always 'Bearer') */
|
|
387
|
+
tokenType: 'Bearer';
|
|
388
|
+
/** Access token lifetime in seconds */
|
|
389
|
+
expiresIn: number;
|
|
390
|
+
/** Authenticated user profile */
|
|
391
|
+
user: EmbedUser;
|
|
392
|
+
/** Optional org branding (present when the user belongs to a branded org) */
|
|
393
|
+
branding?: EmbedBranding;
|
|
394
|
+
}
|
|
301
395
|
|
|
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,
|
|
396
|
+
export type { AuthorizeOptions as A, BioAuthConfig as B, CreateDepartmentData as C, EmbedClientConfig as E, 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, EmbedLoginParams as j, EmbedAuthResult as k, EmbedSignupParams as l, EmbedMagicLinkParams as m, EmbedVerifyParams as n, EmbedRefreshParams as o, EmbedLogoutParams as p, BioTokenPayload as q, AdminResponse as r, BioAddress as s, BioClientTokenPayload as t, BioMessaging as u, BioUsersConfig as v, EmbedBranding as w, EmbedUser as x, OrgMemberFilters as y, OrgMembersResult as z };
|
package/dist/users.d.mts
CHANGED
package/dist/users.d.ts
CHANGED