@turnkey/sdk-browser 1.16.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +53 -0
- package/dist/__clients__/base-client.d.ts +7 -0
- package/dist/__clients__/base-client.d.ts.map +1 -0
- package/dist/__clients__/base-client.js +13 -0
- package/dist/__clients__/base-client.js.map +1 -0
- package/dist/__clients__/base-client.mjs +11 -0
- package/dist/__clients__/base-client.mjs.map +1 -0
- package/dist/__clients__/browser-clients.d.ts +243 -0
- package/dist/__clients__/browser-clients.d.ts.map +1 -0
- package/dist/__clients__/browser-clients.js +633 -0
- package/dist/__clients__/browser-clients.js.map +1 -0
- package/dist/__clients__/browser-clients.mjs +628 -0
- package/dist/__clients__/browser-clients.mjs.map +1 -0
- package/dist/__generated__/sdk-client-base.d.ts.map +1 -1
- package/dist/__generated__/sdk-client-base.js +106 -110
- package/dist/__generated__/sdk-client-base.js.map +1 -1
- package/dist/__generated__/sdk-client-base.mjs +106 -110
- package/dist/__generated__/sdk-client-base.mjs.map +1 -1
- package/dist/__generated__/version.d.ts +1 -1
- package/dist/__generated__/version.d.ts.map +1 -1
- package/dist/__generated__/version.js +1 -1
- package/dist/__generated__/version.mjs +1 -1
- package/dist/__types__/base.d.ts +12 -0
- package/dist/__types__/base.d.ts.map +1 -1
- package/dist/__types__/base.js +5 -0
- package/dist/__types__/base.js.map +1 -1
- package/dist/__types__/base.mjs +6 -1
- package/dist/__types__/base.mjs.map +1 -1
- package/dist/constants.d.ts +2 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +6 -0
- package/dist/constants.js.map +1 -0
- package/dist/constants.mjs +4 -0
- package/dist/constants.mjs.map +1 -0
- package/dist/index.d.ts +4 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -4
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +3 -2
- package/dist/index.mjs.map +1 -1
- package/dist/models.d.ts +1 -1
- package/dist/models.d.ts.map +1 -1
- package/dist/sdk-client.d.ts +14 -186
- package/dist/sdk-client.d.ts.map +1 -1
- package/dist/sdk-client.js +75 -437
- package/dist/sdk-client.js.map +1 -1
- package/dist/sdk-client.mjs +69 -431
- package/dist/sdk-client.mjs.map +1 -1
- package/dist/storage.d.ts +23 -3
- package/dist/storage.d.ts.map +1 -1
- package/dist/storage.js +17 -0
- package/dist/storage.js.map +1 -1
- package/dist/storage.mjs +17 -1
- package/dist/storage.mjs.map +1 -1
- package/package.json +6 -5
|
@@ -0,0 +1,633 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var http = require('@turnkey/http');
|
|
4
|
+
var baseClient = require('./base-client.js');
|
|
5
|
+
var base = require('../__types__/base.js');
|
|
6
|
+
var utils = require('../utils.js');
|
|
7
|
+
var storage = require('../storage.js');
|
|
8
|
+
var constants = require('../constants.js');
|
|
9
|
+
|
|
10
|
+
class TurnkeyBrowserClient extends baseClient.TurnkeyBaseClient {
|
|
11
|
+
constructor(config, authClient) {
|
|
12
|
+
super(config, authClient);
|
|
13
|
+
this.login = async (config) => {
|
|
14
|
+
const readOnlySessionResult = await this.createReadOnlySession(config || {});
|
|
15
|
+
await storage.saveSession(readOnlySessionResult, this.authClient);
|
|
16
|
+
return readOnlySessionResult;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Creates a read-write session. This method infers the current user's organization ID and target userId.
|
|
20
|
+
* To be used in conjunction with an `iframeStamper`: the resulting session's credential bundle can be
|
|
21
|
+
* injected into an iframeStamper to create a session that enables both read and write requests.
|
|
22
|
+
*
|
|
23
|
+
* @param targetEmbeddedKey
|
|
24
|
+
* @param expirationSeconds
|
|
25
|
+
* @param userId
|
|
26
|
+
* @returns {Promise<void>}
|
|
27
|
+
*/
|
|
28
|
+
this.refereshSession = async (sessionType = base.SessionType.READ_WRITE, targetPublicKey, // TODO: eventually we want to automatically pull this from localStorage/iframe
|
|
29
|
+
expirationSeconds = constants.DEFAULT_SESSION_EXPIRATION_IN_SECONDS) => {
|
|
30
|
+
try {
|
|
31
|
+
if (sessionType === base.SessionType.READ_ONLY) {
|
|
32
|
+
if (this instanceof TurnkeyPasskeyClient) {
|
|
33
|
+
throw new Error("You must use a passkey client to refresh a read session"); // TODO: support wallet client
|
|
34
|
+
}
|
|
35
|
+
const readOnlySessionResult = await this.createReadOnlySession({});
|
|
36
|
+
const session = {
|
|
37
|
+
sessionType: base.SessionType.READ_ONLY,
|
|
38
|
+
userId: readOnlySessionResult.userId,
|
|
39
|
+
organizationId: readOnlySessionResult.organizationId,
|
|
40
|
+
expiry: Number(readOnlySessionResult.sessionExpiry),
|
|
41
|
+
token: readOnlySessionResult.session,
|
|
42
|
+
};
|
|
43
|
+
await storage.storeSession(session, base.AuthClient.Passkey);
|
|
44
|
+
}
|
|
45
|
+
if (sessionType === base.SessionType.READ_WRITE) {
|
|
46
|
+
if (!targetPublicKey) {
|
|
47
|
+
throw new Error("You must provide a targetPublicKey to refresh a read-write session.");
|
|
48
|
+
}
|
|
49
|
+
const readWriteSessionResult = await this.createReadWriteSession({
|
|
50
|
+
targetPublicKey,
|
|
51
|
+
expirationSeconds,
|
|
52
|
+
invalidateExisting: true,
|
|
53
|
+
});
|
|
54
|
+
const session = {
|
|
55
|
+
sessionType: base.SessionType.READ_WRITE,
|
|
56
|
+
userId: readWriteSessionResult.userId,
|
|
57
|
+
organizationId: readWriteSessionResult.organizationId,
|
|
58
|
+
expiry: Date.now() + Number(expirationSeconds) * 1000,
|
|
59
|
+
token: readWriteSessionResult.credentialBundle,
|
|
60
|
+
};
|
|
61
|
+
if (this instanceof TurnkeyIframeClient) {
|
|
62
|
+
await this.injectCredentialBundle(session.token);
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
// Throw an error if the client is not an iframe client
|
|
66
|
+
throw new Error("You must use an iframe client to refresh a read-write session");
|
|
67
|
+
}
|
|
68
|
+
await storage.storeSession(session, base.AuthClient.Iframe);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
catch (error) {
|
|
72
|
+
throw new Error("Unable to refresh session.");
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
/**
|
|
76
|
+
* Log in with a bundle. This method uses a bundle sent to the end user email
|
|
77
|
+
* To be used in conjunction with an `iframeStamper`.
|
|
78
|
+
*
|
|
79
|
+
* @param bundle
|
|
80
|
+
* @param expirationSeconds
|
|
81
|
+
* @returns {Promise<void>}
|
|
82
|
+
*/
|
|
83
|
+
this.loginWithBundle = async (bundle, // we need a way to get the expiry of this token. Either it lives in the token itself or is returned from the server action and passed again here
|
|
84
|
+
expirationSeconds) => {
|
|
85
|
+
if (this instanceof TurnkeyIframeClient) {
|
|
86
|
+
await this.injectCredentialBundle(bundle);
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
// Throw an error if the client is not an iframe client
|
|
90
|
+
throw new Error("You must use an iframe client to log in with a session."); //should we default to a "localStorage" client?
|
|
91
|
+
}
|
|
92
|
+
const whoAmI = await this.getWhoami();
|
|
93
|
+
const session = {
|
|
94
|
+
sessionType: base.SessionType.READ_WRITE,
|
|
95
|
+
userId: whoAmI.userId,
|
|
96
|
+
organizationId: whoAmI.organizationId,
|
|
97
|
+
expiry: Date.now() + Number(expirationSeconds) * 1000,
|
|
98
|
+
token: bundle,
|
|
99
|
+
};
|
|
100
|
+
await storage.storeSession(session, base.AuthClient.Iframe);
|
|
101
|
+
};
|
|
102
|
+
/**
|
|
103
|
+
* Log in with a session object. This method uses a session object from server actions and stores it and the active client in local storage
|
|
104
|
+
* To be used in conjunction with an `iframeStamper`.
|
|
105
|
+
*
|
|
106
|
+
* @param session
|
|
107
|
+
* @returns {Promise<void>}
|
|
108
|
+
*/
|
|
109
|
+
this.loginWithSession = async (session) => {
|
|
110
|
+
if (this instanceof TurnkeyIframeClient) {
|
|
111
|
+
await this.injectCredentialBundle(session.token);
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
// Throw an error if the client is not an iframe client
|
|
115
|
+
throw new Error("You must use an iframe client to log in with a session."); //should we default to a "localStorage" client?
|
|
116
|
+
}
|
|
117
|
+
await storage.storeSession(session, base.AuthClient.Iframe);
|
|
118
|
+
};
|
|
119
|
+
/**
|
|
120
|
+
* Log in with a passkey.
|
|
121
|
+
* To be used in conjunction with a `passkeyStamper`
|
|
122
|
+
*
|
|
123
|
+
* @param session
|
|
124
|
+
* @returns {Promise<void>}
|
|
125
|
+
*/
|
|
126
|
+
this.loginWithPasskey = async (sessionType = base.SessionType.READ_WRITE, iframeClient, targetPublicKey, // TODO: eventually we want to automatically pull this from localStorage/iframe
|
|
127
|
+
expirationSeconds = constants.DEFAULT_SESSION_EXPIRATION_IN_SECONDS) => {
|
|
128
|
+
try {
|
|
129
|
+
// Create a read-only session
|
|
130
|
+
if (sessionType === base.SessionType.READ_ONLY) {
|
|
131
|
+
const readOnlySessionResult = await this.createReadOnlySession({});
|
|
132
|
+
const session = {
|
|
133
|
+
sessionType: base.SessionType.READ_ONLY,
|
|
134
|
+
userId: readOnlySessionResult.userId,
|
|
135
|
+
organizationId: readOnlySessionResult.organizationId,
|
|
136
|
+
expiry: Number(readOnlySessionResult.sessionExpiry),
|
|
137
|
+
token: readOnlySessionResult.session,
|
|
138
|
+
};
|
|
139
|
+
await storage.storeSession(session, base.AuthClient.Passkey);
|
|
140
|
+
}
|
|
141
|
+
// Create a read-write session
|
|
142
|
+
if (sessionType === base.SessionType.READ_WRITE) {
|
|
143
|
+
if (!targetPublicKey) {
|
|
144
|
+
throw new Error("You must provide a targetPublicKey to create a read-write session.");
|
|
145
|
+
}
|
|
146
|
+
const readWriteSessionResult = await this.createReadWriteSession({
|
|
147
|
+
targetPublicKey,
|
|
148
|
+
expirationSeconds,
|
|
149
|
+
});
|
|
150
|
+
const session = {
|
|
151
|
+
sessionType: base.SessionType.READ_WRITE,
|
|
152
|
+
userId: readWriteSessionResult.userId,
|
|
153
|
+
organizationId: readWriteSessionResult.organizationId,
|
|
154
|
+
expiry: Date.now() + Number(expirationSeconds) * 1000,
|
|
155
|
+
token: readWriteSessionResult.credentialBundle,
|
|
156
|
+
};
|
|
157
|
+
if (!iframeClient) {
|
|
158
|
+
throw new Error("You must provide an iframe client to log in with a passkey.");
|
|
159
|
+
}
|
|
160
|
+
await iframeClient.injectCredentialBundle(session.token);
|
|
161
|
+
await storage.storeSession(session, base.AuthClient.Iframe);
|
|
162
|
+
}
|
|
163
|
+
else {
|
|
164
|
+
throw new Error("Invalid session type passed.");
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
catch (error) {
|
|
168
|
+
throw new Error("Unable to log in with the provided passkey.");
|
|
169
|
+
}
|
|
170
|
+
};
|
|
171
|
+
/**
|
|
172
|
+
* Log in with a browser wallet.
|
|
173
|
+
*
|
|
174
|
+
* @param session
|
|
175
|
+
* @returns {Promise<void>}
|
|
176
|
+
*/
|
|
177
|
+
this.loginWithWallet = async (sessionType = base.SessionType.READ_WRITE, iframeClient, targetPublicKey, // TODO: eventually we want to automatically pull this from localStorage/iframe
|
|
178
|
+
expirationSeconds = constants.DEFAULT_SESSION_EXPIRATION_IN_SECONDS) => {
|
|
179
|
+
// Create a read-only session
|
|
180
|
+
if (sessionType === base.SessionType.READ_ONLY) {
|
|
181
|
+
const readOnlySessionResult = await this.createReadOnlySession({});
|
|
182
|
+
const session = {
|
|
183
|
+
sessionType: base.SessionType.READ_ONLY,
|
|
184
|
+
userId: readOnlySessionResult.userId,
|
|
185
|
+
organizationId: readOnlySessionResult.organizationId,
|
|
186
|
+
expiry: Number(readOnlySessionResult.sessionExpiry),
|
|
187
|
+
token: readOnlySessionResult.session,
|
|
188
|
+
};
|
|
189
|
+
await storage.storeSession(session, base.AuthClient.Wallet);
|
|
190
|
+
}
|
|
191
|
+
// Create a read-write session
|
|
192
|
+
if (sessionType === base.SessionType.READ_WRITE) {
|
|
193
|
+
if (!targetPublicKey) {
|
|
194
|
+
throw new Error("You must provide a targetPublicKey to create a read-write session.");
|
|
195
|
+
}
|
|
196
|
+
const readWriteSessionResult = await this.createReadWriteSession({
|
|
197
|
+
targetPublicKey,
|
|
198
|
+
expirationSeconds,
|
|
199
|
+
});
|
|
200
|
+
const session = {
|
|
201
|
+
sessionType: base.SessionType.READ_WRITE,
|
|
202
|
+
userId: readWriteSessionResult.userId,
|
|
203
|
+
organizationId: readWriteSessionResult.organizationId,
|
|
204
|
+
expiry: Date.now() + Number(expirationSeconds) * 1000,
|
|
205
|
+
token: readWriteSessionResult.credentialBundle,
|
|
206
|
+
};
|
|
207
|
+
if (!iframeClient) {
|
|
208
|
+
throw new Error("You must provide an iframe client to log in with a wallet.");
|
|
209
|
+
}
|
|
210
|
+
await iframeClient.injectCredentialBundle(session.token);
|
|
211
|
+
await storage.storeSession(session, base.AuthClient.Iframe);
|
|
212
|
+
}
|
|
213
|
+
else {
|
|
214
|
+
throw new Error("Invalid session type passed.");
|
|
215
|
+
}
|
|
216
|
+
};
|
|
217
|
+
/**
|
|
218
|
+
* Creates a read-write session. This method infers the current user's organization ID and target userId.
|
|
219
|
+
* To be used in conjunction with an `iframeStamper`: the resulting session's credential bundle can be
|
|
220
|
+
* injected into an iframeStamper to create a session that enables both read and write requests.
|
|
221
|
+
*
|
|
222
|
+
* @param targetEmbeddedKey
|
|
223
|
+
* @param expirationSeconds
|
|
224
|
+
* @param userId
|
|
225
|
+
* @returns {Promise<SdkApiTypes.TCreateReadWriteSessionResponse>}
|
|
226
|
+
*/
|
|
227
|
+
this.loginWithReadWriteSession = async (targetEmbeddedKey, expirationSeconds = constants.DEFAULT_SESSION_EXPIRATION_IN_SECONDS, userId) => {
|
|
228
|
+
try {
|
|
229
|
+
const readWriteSessionResult = await this.createReadWriteSession({
|
|
230
|
+
targetPublicKey: targetEmbeddedKey,
|
|
231
|
+
expirationSeconds,
|
|
232
|
+
userId: userId,
|
|
233
|
+
});
|
|
234
|
+
// Ensure session and sessionExpiry are included in the object
|
|
235
|
+
const readWriteSessionResultWithSession = {
|
|
236
|
+
...readWriteSessionResult,
|
|
237
|
+
credentialBundle: readWriteSessionResult.credentialBundle,
|
|
238
|
+
sessionExpiry: Date.now() + Number(expirationSeconds) * 1000,
|
|
239
|
+
};
|
|
240
|
+
// store auth bundle in local storage
|
|
241
|
+
await storage.saveSession(readWriteSessionResultWithSession, this.authClient);
|
|
242
|
+
return readWriteSessionResultWithSession;
|
|
243
|
+
}
|
|
244
|
+
catch (error) {
|
|
245
|
+
throw new Error("Unable to log in with the provided read-write session.");
|
|
246
|
+
}
|
|
247
|
+
};
|
|
248
|
+
/**
|
|
249
|
+
* Logs in with an existing auth bundle. this bundle enables both read and write requests.
|
|
250
|
+
*
|
|
251
|
+
* @param credentialBundle
|
|
252
|
+
* @param expirationSeconds
|
|
253
|
+
* @returns {Promise<boolean>}
|
|
254
|
+
*/
|
|
255
|
+
this.loginWithAuthBundle = async (credentialBundle, expirationSeconds = constants.DEFAULT_SESSION_EXPIRATION_IN_SECONDS) => {
|
|
256
|
+
try {
|
|
257
|
+
const whoAmIResult = await this.getWhoami();
|
|
258
|
+
const readWriteSessionResultWithSession = {
|
|
259
|
+
...whoAmIResult,
|
|
260
|
+
credentialBundle: credentialBundle,
|
|
261
|
+
sessionExpiry: Date.now() + Number(expirationSeconds) * 1000,
|
|
262
|
+
};
|
|
263
|
+
await storage.saveSession(readWriteSessionResultWithSession, this.authClient);
|
|
264
|
+
return true;
|
|
265
|
+
}
|
|
266
|
+
catch {
|
|
267
|
+
throw new Error("Unable to log in with the provided auth bundle.");
|
|
268
|
+
}
|
|
269
|
+
};
|
|
270
|
+
/**
|
|
271
|
+
* Removes authentication factors from an end user.
|
|
272
|
+
*
|
|
273
|
+
* This function allows selectively removing:
|
|
274
|
+
* - Phone number
|
|
275
|
+
* - Email
|
|
276
|
+
* - Authenticators (by ID)
|
|
277
|
+
* - OAuth providers (by ID)
|
|
278
|
+
* - API keys (by ID)
|
|
279
|
+
*
|
|
280
|
+
* All removal operations are executed in parallel if multiple
|
|
281
|
+
* parameters are provided.
|
|
282
|
+
*
|
|
283
|
+
* @param params - A structured object containing all the removal parameters
|
|
284
|
+
* @param params.userId - Unique identifier of the user
|
|
285
|
+
* @param params.phoneNumber - true to remove the phone number
|
|
286
|
+
* @param params.email - true to remove the email
|
|
287
|
+
* @param params.authenticatorIds - Array of authenticator IDs to remove
|
|
288
|
+
* @param params.oauthProviderIds - Array of OAuth provider IDs to remove
|
|
289
|
+
* @param params.apiKeyIds - Array of API key IDs to remove
|
|
290
|
+
* @returns A promise that resolves to an array of results from each removal operation
|
|
291
|
+
*/
|
|
292
|
+
this.deleteUserAuth = async (params) => {
|
|
293
|
+
try {
|
|
294
|
+
const { userId, phoneNumber, email, authenticatorIds, oauthProviderIds, apiKeyIds, } = params;
|
|
295
|
+
const promises = [];
|
|
296
|
+
if (phoneNumber) {
|
|
297
|
+
promises.push(this.updateUser({ userId, userPhoneNumber: "", userTagIds: [] }));
|
|
298
|
+
}
|
|
299
|
+
if (email) {
|
|
300
|
+
promises.push(this.updateUser({ userId, userEmail: "", userTagIds: [] }));
|
|
301
|
+
}
|
|
302
|
+
if (authenticatorIds && authenticatorIds.length > 0) {
|
|
303
|
+
promises.push(this.deleteAuthenticators({ userId, authenticatorIds }));
|
|
304
|
+
}
|
|
305
|
+
if (oauthProviderIds && oauthProviderIds.length > 0) {
|
|
306
|
+
promises.push(this.deleteOauthProviders({ userId, providerIds: oauthProviderIds }));
|
|
307
|
+
}
|
|
308
|
+
if (apiKeyIds && apiKeyIds.length > 0) {
|
|
309
|
+
promises.push(this.deleteApiKeys({ userId, apiKeyIds }));
|
|
310
|
+
}
|
|
311
|
+
// Execute all removal operations in parallel
|
|
312
|
+
return await Promise.all(promises);
|
|
313
|
+
}
|
|
314
|
+
catch (error) {
|
|
315
|
+
// Surface error
|
|
316
|
+
throw error;
|
|
317
|
+
}
|
|
318
|
+
};
|
|
319
|
+
/**
|
|
320
|
+
* Adds or updates authentication factors for an end user.
|
|
321
|
+
*
|
|
322
|
+
* This function allows selectively adding:
|
|
323
|
+
* - Phone number
|
|
324
|
+
* - Email
|
|
325
|
+
* - Authenticators
|
|
326
|
+
* - OAuth providers
|
|
327
|
+
* - API keys
|
|
328
|
+
*
|
|
329
|
+
* All additions/updates are executed in parallel if multiple
|
|
330
|
+
* parameters are provided.
|
|
331
|
+
*
|
|
332
|
+
* @param params - A structured object containing all the addition/update parameters
|
|
333
|
+
* @param params.userId - Unique identifier of the user
|
|
334
|
+
* @param params.phoneNumber - New phone number for the user
|
|
335
|
+
* @param params.email - New email address for the user
|
|
336
|
+
* @param params.authenticators - Array of authenticator objects to create
|
|
337
|
+
* @param params.oauthProviders - Array of OAuth provider objects to create
|
|
338
|
+
* @param params.apiKeys - Array of API key objects to create
|
|
339
|
+
* @returns A promise that resolves to an array of results from each addition or update
|
|
340
|
+
*/
|
|
341
|
+
this.addUserAuth = async (params) => {
|
|
342
|
+
try {
|
|
343
|
+
const { userId, phoneNumber, email, authenticators, oauthProviders, apiKeys, } = params;
|
|
344
|
+
const promises = [];
|
|
345
|
+
if (phoneNumber) {
|
|
346
|
+
promises.push(this.updateUser({
|
|
347
|
+
userId,
|
|
348
|
+
userPhoneNumber: phoneNumber,
|
|
349
|
+
userTagIds: [],
|
|
350
|
+
}));
|
|
351
|
+
}
|
|
352
|
+
if (email) {
|
|
353
|
+
promises.push(this.updateUser({ userId, userEmail: email, userTagIds: [] }));
|
|
354
|
+
}
|
|
355
|
+
if (authenticators && authenticators.length > 0) {
|
|
356
|
+
promises.push(this.createAuthenticators({ userId, authenticators }));
|
|
357
|
+
}
|
|
358
|
+
if (oauthProviders && oauthProviders.length > 0) {
|
|
359
|
+
promises.push(this.createOauthProviders({ userId, oauthProviders }));
|
|
360
|
+
}
|
|
361
|
+
if (apiKeys && apiKeys.length > 0) {
|
|
362
|
+
promises.push(this.createApiKeys({ userId, apiKeys }));
|
|
363
|
+
}
|
|
364
|
+
// Execute all additions/updates operations in parallel
|
|
365
|
+
return await Promise.all(promises);
|
|
366
|
+
}
|
|
367
|
+
catch (error) {
|
|
368
|
+
// Surface error
|
|
369
|
+
throw error;
|
|
370
|
+
}
|
|
371
|
+
};
|
|
372
|
+
}
|
|
373
|
+
/**
|
|
374
|
+
* Comprehensive authentication update for an end user.
|
|
375
|
+
* Combines add/update and delete operations into a single call.
|
|
376
|
+
*
|
|
377
|
+
* The behavior is driven by whether values are set to:
|
|
378
|
+
* - A string/array (to create or update)
|
|
379
|
+
* - `null` or an array of IDs (to remove)
|
|
380
|
+
*
|
|
381
|
+
* All operations are executed in parallel where applicable.
|
|
382
|
+
*
|
|
383
|
+
* @param params - A structured object containing all the update parameters
|
|
384
|
+
* @param params.userId - Unique identifier of the user
|
|
385
|
+
* @param params.phoneNumber - String to set (new phone) or `null` to remove
|
|
386
|
+
* @param params.email - String to set (new email) or `null` to remove
|
|
387
|
+
* @param params.authenticators - Object describing authenticators to add or remove
|
|
388
|
+
* @param params.oauthProviders - Object describing OAuth providers to add or remove
|
|
389
|
+
* @param params.apiKeys - Object describing API keys to add or remove
|
|
390
|
+
*
|
|
391
|
+
* @returns A promise that resolves to a boolean indicating overall success
|
|
392
|
+
*/
|
|
393
|
+
async updateUserAuth(params) {
|
|
394
|
+
try {
|
|
395
|
+
const { userId, phoneNumber, email, authenticators, oauthProviders, apiKeys, } = params;
|
|
396
|
+
const promises = [];
|
|
397
|
+
// Handle phone/email in a single updateUser call if both are changing,
|
|
398
|
+
// or separate calls if only one is changing.
|
|
399
|
+
const userUpdates = {};
|
|
400
|
+
if (phoneNumber !== undefined) {
|
|
401
|
+
userUpdates.userPhoneNumber = phoneNumber === null ? "" : phoneNumber;
|
|
402
|
+
}
|
|
403
|
+
if (email !== undefined) {
|
|
404
|
+
userUpdates.userEmail = email === null ? "" : email;
|
|
405
|
+
}
|
|
406
|
+
if (Object.keys(userUpdates).length > 0) {
|
|
407
|
+
promises.push(this.updateUser({ userId, ...userUpdates, userTagIds: [] }));
|
|
408
|
+
}
|
|
409
|
+
// Handle authenticators
|
|
410
|
+
if (authenticators) {
|
|
411
|
+
if (authenticators.add?.length) {
|
|
412
|
+
promises.push(this.createAuthenticators({
|
|
413
|
+
userId,
|
|
414
|
+
authenticators: authenticators.add,
|
|
415
|
+
}));
|
|
416
|
+
}
|
|
417
|
+
if (authenticators.deleteIds?.length) {
|
|
418
|
+
promises.push(this.deleteAuthenticators({
|
|
419
|
+
userId,
|
|
420
|
+
authenticatorIds: authenticators.deleteIds,
|
|
421
|
+
}));
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
// Handle OAuth providers
|
|
425
|
+
if (oauthProviders) {
|
|
426
|
+
if (oauthProviders.add?.length) {
|
|
427
|
+
promises.push(this.createOauthProviders({
|
|
428
|
+
userId,
|
|
429
|
+
oauthProviders: oauthProviders.add,
|
|
430
|
+
}));
|
|
431
|
+
}
|
|
432
|
+
if (oauthProviders.deleteIds?.length) {
|
|
433
|
+
promises.push(this.deleteOauthProviders({
|
|
434
|
+
userId,
|
|
435
|
+
providerIds: oauthProviders.deleteIds,
|
|
436
|
+
}));
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
// Handle API keys
|
|
440
|
+
if (apiKeys) {
|
|
441
|
+
if (apiKeys.add?.length) {
|
|
442
|
+
promises.push(this.createApiKeys({
|
|
443
|
+
userId,
|
|
444
|
+
apiKeys: apiKeys.add,
|
|
445
|
+
}));
|
|
446
|
+
}
|
|
447
|
+
if (apiKeys.deleteIds?.length) {
|
|
448
|
+
promises.push(this.deleteApiKeys({
|
|
449
|
+
userId,
|
|
450
|
+
apiKeyIds: apiKeys.deleteIds,
|
|
451
|
+
}));
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
// Execute all requested operations in parallel
|
|
455
|
+
await Promise.all(promises);
|
|
456
|
+
return true;
|
|
457
|
+
}
|
|
458
|
+
catch (error) {
|
|
459
|
+
// Surface error
|
|
460
|
+
throw error;
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
class TurnkeyPasskeyClient extends TurnkeyBrowserClient {
|
|
465
|
+
constructor(config) {
|
|
466
|
+
super(config, base.AuthClient.Passkey);
|
|
467
|
+
/**
|
|
468
|
+
* Create a passkey for an end-user, taking care of various lower-level details.
|
|
469
|
+
*
|
|
470
|
+
* @returns {Promise<Passkey>}
|
|
471
|
+
*/
|
|
472
|
+
this.createUserPasskey = async (config = {}) => {
|
|
473
|
+
const challenge = utils.generateRandomBuffer();
|
|
474
|
+
const encodedChallenge = utils.base64UrlEncode(challenge);
|
|
475
|
+
const authenticatorUserId = utils.generateRandomBuffer();
|
|
476
|
+
// WebAuthn credential options options can be found here:
|
|
477
|
+
// https://www.w3.org/TR/webauthn-2/#sctn-sample-registration
|
|
478
|
+
//
|
|
479
|
+
// All pubkey algorithms can be found here: https://www.iana.org/assignments/cose/cose.xhtml#algorithms
|
|
480
|
+
// Turnkey only supports ES256 (-7) and RS256 (-257)
|
|
481
|
+
//
|
|
482
|
+
// The pubkey type only supports one value, "public-key"
|
|
483
|
+
// See https://www.w3.org/TR/webauthn-2/#enumdef-publickeycredentialtype for more details
|
|
484
|
+
// TODO: consider un-nesting these config params
|
|
485
|
+
const webauthnConfig = {
|
|
486
|
+
publicKey: {
|
|
487
|
+
rp: {
|
|
488
|
+
id: config.publicKey?.rp?.id ?? this.rpId,
|
|
489
|
+
name: config.publicKey?.rp?.name ?? "",
|
|
490
|
+
},
|
|
491
|
+
challenge: config.publicKey?.challenge ?? challenge,
|
|
492
|
+
pubKeyCredParams: config.publicKey?.pubKeyCredParams ?? [
|
|
493
|
+
{
|
|
494
|
+
type: "public-key",
|
|
495
|
+
alg: -7,
|
|
496
|
+
},
|
|
497
|
+
{
|
|
498
|
+
type: "public-key",
|
|
499
|
+
alg: -257,
|
|
500
|
+
},
|
|
501
|
+
],
|
|
502
|
+
user: {
|
|
503
|
+
id: config.publicKey?.user?.id ?? authenticatorUserId,
|
|
504
|
+
name: config.publicKey?.user?.name ?? "Default User",
|
|
505
|
+
displayName: config.publicKey?.user?.displayName ?? "Default User",
|
|
506
|
+
},
|
|
507
|
+
authenticatorSelection: {
|
|
508
|
+
authenticatorAttachment: config.publicKey?.authenticatorSelection?.authenticatorAttachment ??
|
|
509
|
+
undefined,
|
|
510
|
+
requireResidentKey: config.publicKey?.authenticatorSelection?.requireResidentKey ??
|
|
511
|
+
true,
|
|
512
|
+
residentKey: config.publicKey?.authenticatorSelection?.residentKey ?? "required",
|
|
513
|
+
userVerification: config.publicKey?.authenticatorSelection?.userVerification ??
|
|
514
|
+
"preferred",
|
|
515
|
+
},
|
|
516
|
+
},
|
|
517
|
+
};
|
|
518
|
+
const attestation = await http.getWebAuthnAttestation(webauthnConfig);
|
|
519
|
+
return {
|
|
520
|
+
encodedChallenge: config.publicKey?.challenge
|
|
521
|
+
? utils.base64UrlEncode(config.publicKey?.challenge)
|
|
522
|
+
: encodedChallenge,
|
|
523
|
+
attestation,
|
|
524
|
+
};
|
|
525
|
+
};
|
|
526
|
+
/**
|
|
527
|
+
* Uses passkey authentication to create a read-write session, via an embedded API key,
|
|
528
|
+
* and stores + returns the resulting auth bundle that contains the encrypted API key.
|
|
529
|
+
* This auth bundle (also referred to as a credential bundle) can be injected into an `iframeStamper`,
|
|
530
|
+
* resulting in a touch-free authenticator. Unlike `loginWithReadWriteSession`, this method
|
|
531
|
+
* assumes the end-user's organization ID (i.e. the sub-organization ID) is already known.
|
|
532
|
+
*
|
|
533
|
+
* @param userId
|
|
534
|
+
* @param targetEmbeddedKey
|
|
535
|
+
* @param expirationSeconds
|
|
536
|
+
* @param curveType
|
|
537
|
+
* @returns {Promise<ReadWriteSession>}
|
|
538
|
+
*/
|
|
539
|
+
this.createPasskeySession = async (userId, targetEmbeddedKey, expirationSeconds = constants.DEFAULT_SESSION_EXPIRATION_IN_SECONDS, organizationId) => {
|
|
540
|
+
try {
|
|
541
|
+
const session = await storage.getStorageValue(storage.StorageKeys.Session);
|
|
542
|
+
organizationId = organizationId ?? session?.organizationId;
|
|
543
|
+
userId = userId ?? session?.userId;
|
|
544
|
+
if (!organizationId) {
|
|
545
|
+
throw new Error("Error creating passkey session: Organization ID is required");
|
|
546
|
+
}
|
|
547
|
+
if (!userId) {
|
|
548
|
+
throw new Error("Error creating passkey session: User ID is required");
|
|
549
|
+
}
|
|
550
|
+
const { authBundle: credentialBundle, publicKey } = await utils.createEmbeddedAPIKey(targetEmbeddedKey);
|
|
551
|
+
// add API key to Turnkey User
|
|
552
|
+
await this.createApiKeys({
|
|
553
|
+
organizationId,
|
|
554
|
+
userId,
|
|
555
|
+
apiKeys: [
|
|
556
|
+
{
|
|
557
|
+
apiKeyName: `Session Key ${String(Date.now())}`,
|
|
558
|
+
publicKey,
|
|
559
|
+
expirationSeconds,
|
|
560
|
+
curveType: "API_KEY_CURVE_P256",
|
|
561
|
+
},
|
|
562
|
+
],
|
|
563
|
+
});
|
|
564
|
+
const whoAmI = await this.getWhoami();
|
|
565
|
+
const expiry = Date.now() + Number(expirationSeconds) * 1000;
|
|
566
|
+
await storage.saveSession({
|
|
567
|
+
organizationId,
|
|
568
|
+
organizationName: whoAmI?.organizationName ?? "",
|
|
569
|
+
userId,
|
|
570
|
+
username: whoAmI?.username ?? "",
|
|
571
|
+
credentialBundle,
|
|
572
|
+
sessionExpiry: expiry,
|
|
573
|
+
}, this.authClient);
|
|
574
|
+
return {
|
|
575
|
+
credentialBundle,
|
|
576
|
+
expiry,
|
|
577
|
+
};
|
|
578
|
+
}
|
|
579
|
+
catch (error) {
|
|
580
|
+
throw new Error("Unable to create passkey session.");
|
|
581
|
+
}
|
|
582
|
+
};
|
|
583
|
+
this.rpId = this.stamper.rpId;
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
/**
|
|
587
|
+
* TurnkeyIframeClient is a client that uses an iframe to interact with the Turnkey API.
|
|
588
|
+
* It is used to create read-write sessions, and to inject credential bundles into the iframe.
|
|
589
|
+
* It is also used to extract encrypted credential bundles from the iframe.
|
|
590
|
+
* @extends TurnkeyBrowserClient
|
|
591
|
+
*/
|
|
592
|
+
class TurnkeyIframeClient extends TurnkeyBrowserClient {
|
|
593
|
+
constructor(config) {
|
|
594
|
+
super(config, base.AuthClient.Iframe);
|
|
595
|
+
this.injectCredentialBundle = async (credentialBundle) => {
|
|
596
|
+
return await this.stamper.injectCredentialBundle(credentialBundle);
|
|
597
|
+
};
|
|
598
|
+
this.injectWalletExportBundle = async (credentialBundle, organizationId) => {
|
|
599
|
+
return await this.stamper.injectWalletExportBundle(credentialBundle, organizationId);
|
|
600
|
+
};
|
|
601
|
+
this.injectKeyExportBundle = async (credentialBundle, organizationId, keyFormat) => {
|
|
602
|
+
return await this.stamper.injectKeyExportBundle(credentialBundle, organizationId, keyFormat);
|
|
603
|
+
};
|
|
604
|
+
this.injectImportBundle = async (bundle, organizationId, userId) => {
|
|
605
|
+
return await this.stamper.injectImportBundle(bundle, organizationId, userId);
|
|
606
|
+
};
|
|
607
|
+
this.extractWalletEncryptedBundle = async () => {
|
|
608
|
+
return await this.stamper.extractWalletEncryptedBundle();
|
|
609
|
+
};
|
|
610
|
+
this.extractKeyEncryptedBundle = async () => {
|
|
611
|
+
return await this.stamper.extractKeyEncryptedBundle();
|
|
612
|
+
};
|
|
613
|
+
this.iframePublicKey = this.stamper.iframePublicKey;
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
class TurnkeyWalletClient extends TurnkeyBrowserClient {
|
|
617
|
+
constructor(config) {
|
|
618
|
+
super(config, base.AuthClient.Wallet);
|
|
619
|
+
this.wallet = config.wallet;
|
|
620
|
+
}
|
|
621
|
+
async getPublicKey() {
|
|
622
|
+
return this.wallet.getPublicKey();
|
|
623
|
+
}
|
|
624
|
+
getWalletInterface() {
|
|
625
|
+
return this.wallet;
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
exports.TurnkeyBrowserClient = TurnkeyBrowserClient;
|
|
630
|
+
exports.TurnkeyIframeClient = TurnkeyIframeClient;
|
|
631
|
+
exports.TurnkeyPasskeyClient = TurnkeyPasskeyClient;
|
|
632
|
+
exports.TurnkeyWalletClient = TurnkeyWalletClient;
|
|
633
|
+
//# sourceMappingURL=browser-clients.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser-clients.js","sources":["../../src/__clients__/browser-clients.ts"],"sourcesContent":[null],"names":["TurnkeyBaseClient","saveSession","SessionType","DEFAULT_SESSION_EXPIRATION_IN_SECONDS","storeSession","AuthClient","generateRandomBuffer","base64UrlEncode","getWebAuthnAttestation","getStorageValue","StorageKeys","createEmbeddedAPIKey"],"mappings":"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"}
|