@turnkey/sdk-react 5.0.2 → 5.2.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 +29 -0
- package/README.md +1 -0
- package/dist/components/auth/Auth.d.ts +1 -4
- package/dist/components/auth/Auth.d.ts.map +1 -1
- package/dist/components/auth/Auth.js +90 -40
- package/dist/components/auth/Auth.js.map +1 -1
- package/dist/components/auth/Auth.mjs +281 -84
- package/dist/components/auth/Auth.mjs.map +1 -1
- package/dist/hooks/use-session.d.ts +2 -1
- package/dist/hooks/use-session.d.ts.map +1 -1
- package/package.json +7 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,34 @@
|
|
|
1
1
|
# @turnkey/sdk-react
|
|
2
2
|
|
|
3
|
+
## 5.2.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#632](https://github.com/tkhq/sdk/pull/632) [`a38a6e3`](https://github.com/tkhq/sdk/commit/a38a6e36dc2bf9abdea64bc817d1cad95b8a289a) Author [@amircheikh](https://github.com/amircheikh) - Added optional `socialLinking` boolean to the `authConfig`. If true, this will enable social linking for new Google <-> Gmail users. For more information on social linking, visit [our docs](https://docs.turnkey.com/authentication/social-logins#social-linking).
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- Updated dependencies [[`5afbe51`](https://github.com/tkhq/sdk/commit/5afbe51949bdd1997fad083a4c1e4272ff7409dc), [`10ee5c5`](https://github.com/tkhq/sdk/commit/10ee5c524b477ce998e4fc635152cd101ae5a9cc), [`a38a6e3`](https://github.com/tkhq/sdk/commit/a38a6e36dc2bf9abdea64bc817d1cad95b8a289a), [`40c4035`](https://github.com/tkhq/sdk/commit/40c40359ec7096d0bca39ffc93e89361b3b11a1a), [`593de2d`](https://github.com/tkhq/sdk/commit/593de2d9404ec8cf53426f9cf832c13eefa3fbf2)]:
|
|
12
|
+
- @turnkey/sdk-browser@5.2.0
|
|
13
|
+
- @turnkey/wallet-stamper@1.0.4
|
|
14
|
+
- @turnkey/crypto@2.4.0
|
|
15
|
+
- @turnkey/sdk-server@4.1.0
|
|
16
|
+
|
|
17
|
+
## 5.1.0
|
|
18
|
+
|
|
19
|
+
### Minor Changes
|
|
20
|
+
|
|
21
|
+
- Update @turnkey/sdk-types readme and install dependency in packages with common types
|
|
22
|
+
|
|
23
|
+
- [#650](https://github.com/tkhq/sdk/pull/650) [`27fe590`](https://github.com/tkhq/sdk/commit/27fe590cdc3eb6a8cde093eeefda2ee1cdc79412) Author [@turnekybc](https://github.com/turnekybc) - Update @turnkey/sdk-types readme and install dependency in packages with common types
|
|
24
|
+
|
|
25
|
+
### Patch Changes
|
|
26
|
+
|
|
27
|
+
- Updated dependencies [[`27fe590`](https://github.com/tkhq/sdk/commit/27fe590cdc3eb6a8cde093eeefda2ee1cdc79412)]:
|
|
28
|
+
- @turnkey/sdk-browser@5.1.0
|
|
29
|
+
- @turnkey/sdk-types@0.1.0
|
|
30
|
+
- @turnkey/sdk-server@4.0.1
|
|
31
|
+
|
|
3
32
|
## 5.0.2
|
|
4
33
|
|
|
5
34
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -1,9 +1,5 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import type { TurnkeyApiTypes, WalletAccount } from "@turnkey/sdk-browser";
|
|
3
|
-
export declare enum SessionType {
|
|
4
|
-
READ_ONLY = "SESSION_TYPE_READ_ONLY",
|
|
5
|
-
READ_WRITE = "SESSION_TYPE_READ_WRITE"
|
|
6
|
-
}
|
|
7
3
|
export interface PasskeyConfig {
|
|
8
4
|
displayName?: string;
|
|
9
5
|
name?: string;
|
|
@@ -24,6 +20,7 @@ interface AuthProps {
|
|
|
24
20
|
googleEnabled: boolean;
|
|
25
21
|
walletEnabled: boolean;
|
|
26
22
|
openOAuthInPage?: boolean;
|
|
23
|
+
socialLinking?: boolean;
|
|
27
24
|
sessionLengthSeconds?: number;
|
|
28
25
|
googleClientId?: string;
|
|
29
26
|
appleClientId?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Auth.d.ts","sourceRoot":"","sources":["../../../src/components/auth/Auth.tsx"],"names":[],"mappings":"AAGA,OAAO,KAA8B,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"Auth.d.ts","sourceRoot":"","sources":["../../../src/components/auth/Auth.tsx"],"names":[],"mappings":"AAGA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAenD,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAI3E,MAAM,WAAW,aAAa;IAC5B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,SAAS;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAoCD,UAAU,SAAS;IACjB,aAAa,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACnC,OAAO,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,UAAU,EAAE;QACV,YAAY,EAAE,OAAO,CAAC;QACtB,cAAc,EAAE,OAAO,CAAC;QACxB,YAAY,EAAE,OAAO,CAAC;QACtB,YAAY,EAAE,OAAO,CAAC;QACtB,eAAe,EAAE,OAAO,CAAC;QACzB,aAAa,EAAE,OAAO,CAAC;QACvB,aAAa,EAAE,OAAO,CAAC;QACvB,eAAe,CAAC,EAAE,OAAO,CAAC;QAC1B,aAAa,CAAC,EAAE,OAAO,CAAC;QACxB,oBAAoB,CAAC,EAAE,MAAM,CAAC;QAC9B,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,gBAAgB,CAAC,EAAE,MAAM,CAAC;KAC3B,CAAC;IACF,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,kBAAkB,CAAC,EAAE,eAAe,CAAC,4BAA4B,CAAC,CAAC;IACnE,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,cAAc,CAAC,EAAE,aAAa,EAAE,CAAC;IACjC,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,SAAS,CAAC,EAAE,SAAS,CAAC;CACvB;AAED,QAAA,MAAM,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC,SAAS,CAquB7B,CAAC;AAEF,eAAe,IAAI,CAAC"}
|
|
@@ -7,6 +7,7 @@ var jsxRuntime = require('react/jsx-runtime');
|
|
|
7
7
|
var Auth_module = require('./Auth.module.css.js');
|
|
8
8
|
var React = require('react');
|
|
9
9
|
var PhoneInput = require('./PhoneInput.js');
|
|
10
|
+
var jwtDecode = require('jwt-decode');
|
|
10
11
|
var Google = require('./Google.js');
|
|
11
12
|
var Apple = require('./Apple.js');
|
|
12
13
|
var Facebook = require('./Facebook.js');
|
|
@@ -21,12 +22,8 @@ var useTurnkey = require('../../hooks/use-turnkey.js');
|
|
|
21
22
|
var constants = require('./constants.js');
|
|
22
23
|
var sdkServer = require('@turnkey/sdk-server');
|
|
23
24
|
var parsePhoneNumberFromString = require('libphonenumber-js');
|
|
25
|
+
var sdkTypes = require('@turnkey/sdk-types');
|
|
24
26
|
|
|
25
|
-
exports.SessionType = void 0;
|
|
26
|
-
(function (SessionType) {
|
|
27
|
-
SessionType["READ_ONLY"] = "SESSION_TYPE_READ_ONLY";
|
|
28
|
-
SessionType["READ_WRITE"] = "SESSION_TYPE_READ_WRITE";
|
|
29
|
-
})(exports.SessionType || (exports.SessionType = {}));
|
|
30
27
|
const passkeyIcon = jsxRuntime.jsxs("svg", {
|
|
31
28
|
xmlns: "http://www.w3.org/2000/svg",
|
|
32
29
|
width: "43",
|
|
@@ -174,7 +171,7 @@ const Auth = ({
|
|
|
174
171
|
await indexedDbClient.resetKeyPair();
|
|
175
172
|
const pubKey = await indexedDbClient.getPublicKey();
|
|
176
173
|
await passkeyClient?.loginWithPasskey({
|
|
177
|
-
sessionType:
|
|
174
|
+
sessionType: sdkTypes.SessionType.READ_WRITE,
|
|
178
175
|
publicKey: pubKey,
|
|
179
176
|
expirationSeconds: authConfig.sessionLengthSeconds?.toString()
|
|
180
177
|
});
|
|
@@ -190,7 +187,7 @@ const Auth = ({
|
|
|
190
187
|
await indexedDbClient?.resetKeyPair();
|
|
191
188
|
const pubKey = await indexedDbClient.getPublicKey();
|
|
192
189
|
await passkeyClient?.loginWithPasskey({
|
|
193
|
-
sessionType:
|
|
190
|
+
sessionType: sdkTypes.SessionType.READ_WRITE,
|
|
194
191
|
publicKey: pubKey,
|
|
195
192
|
expirationSeconds: authConfig.sessionLengthSeconds?.toString()
|
|
196
193
|
});
|
|
@@ -230,44 +227,97 @@ const Auth = ({
|
|
|
230
227
|
}
|
|
231
228
|
setLoading(undefined);
|
|
232
229
|
};
|
|
233
|
-
const handleOAuthLogin = async (credential, providerName) => {
|
|
230
|
+
const handleOAuthLogin = async (credential, providerName, socialLinking = false) => {
|
|
234
231
|
const pubKey = await indexedDbClient?.getPublicKey();
|
|
235
232
|
if (!pubKey) {
|
|
236
233
|
return;
|
|
237
234
|
}
|
|
238
235
|
setOauthLoading(providerName);
|
|
239
|
-
const
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
236
|
+
const oauthProviders = [{
|
|
237
|
+
providerName,
|
|
238
|
+
oidcToken: credential
|
|
239
|
+
}];
|
|
240
|
+
let createSuborgData = {
|
|
241
|
+
oauthProviders,
|
|
242
|
+
...(customAccounts && {
|
|
243
|
+
customAccounts
|
|
244
|
+
})
|
|
244
245
|
};
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
246
|
+
const completeLogin = async suborgID => {
|
|
247
|
+
const sessionResponse = await sdkServer.server.oauthLogin({
|
|
248
|
+
suborgID,
|
|
249
|
+
oidcToken: credential,
|
|
250
|
+
publicKey: pubKey,
|
|
251
|
+
sessionLengthSeconds: authConfig.sessionLengthSeconds
|
|
252
|
+
});
|
|
253
|
+
if (sessionResponse?.session) {
|
|
254
|
+
await indexedDbClient.loginWithSession(sessionResponse.session);
|
|
255
|
+
return onAuthSuccess();
|
|
256
|
+
}
|
|
255
257
|
onError(constants.authErrors.oauth.loginFailed);
|
|
256
|
-
|
|
258
|
+
};
|
|
259
|
+
// Non-social-linking path: getOrCreateSuborg then login
|
|
260
|
+
if (!socialLinking) {
|
|
261
|
+
const resp = await sdkServer.server.getOrCreateSuborg({
|
|
262
|
+
filterType: constants.FilterType.OidcToken,
|
|
263
|
+
filterValue: credential,
|
|
264
|
+
additionalData: createSuborgData
|
|
265
|
+
});
|
|
266
|
+
const suborgIds = resp?.subOrganizationIds;
|
|
267
|
+
if (!suborgIds?.length) {
|
|
268
|
+
return onError(constants.authErrors.oauth.loginFailed);
|
|
269
|
+
}
|
|
270
|
+
return completeLogin(suborgIds[0]);
|
|
257
271
|
}
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
272
|
+
// Social-linking path
|
|
273
|
+
// See if there's already a suborg tied to this token
|
|
274
|
+
const oidcOrgIds = (await sdkServer.server.getSuborgs({
|
|
275
|
+
filterType: constants.FilterType.OidcToken,
|
|
276
|
+
filterValue: credential
|
|
277
|
+
}))?.organizationIds;
|
|
278
|
+
let orgId = oidcOrgIds?.[0];
|
|
279
|
+
// If not, try to link by verified email (Google only)
|
|
280
|
+
if (!orgId) {
|
|
281
|
+
const {
|
|
282
|
+
email: oidcEmail,
|
|
283
|
+
iss
|
|
284
|
+
} = jwtDecode.jwtDecode(credential) || {};
|
|
285
|
+
createSuborgData = {
|
|
286
|
+
email: oidcEmail,
|
|
287
|
+
oauthProviders,
|
|
288
|
+
...(customAccounts && {
|
|
289
|
+
customAccounts
|
|
290
|
+
})
|
|
291
|
+
};
|
|
292
|
+
if (oidcEmail && iss === "https://accounts.google.com") {
|
|
293
|
+
const emailOrgIds = (await sdkServer.server.getVerifiedSuborgs({
|
|
294
|
+
filterType: constants.FilterType.Email,
|
|
295
|
+
filterValue: oidcEmail
|
|
296
|
+
}))?.organizationIds;
|
|
297
|
+
if (emailOrgIds?.[0]) {
|
|
298
|
+
orgId = emailOrgIds[0];
|
|
299
|
+
// attach this new OIDC provider to the existing user
|
|
300
|
+
const userId = (await sdkServer.server.getUsers({
|
|
301
|
+
organizationId: orgId
|
|
302
|
+
}))?.users?.[0]?.userId;
|
|
303
|
+
if (!userId) {
|
|
304
|
+
return onError(constants.authErrors.oauth.loginFailed);
|
|
305
|
+
}
|
|
306
|
+
await sdkServer.server.createOauthProviders({
|
|
307
|
+
organizationId: orgId,
|
|
308
|
+
userId,
|
|
309
|
+
oauthProviders
|
|
310
|
+
});
|
|
311
|
+
} else {
|
|
312
|
+
// No orgs with the email. Create brand new suborg
|
|
313
|
+
orgId = (await sdkServer.server.createSuborg(createSuborgData))?.subOrganizationId;
|
|
314
|
+
}
|
|
315
|
+
} else {
|
|
316
|
+
// Non-Google or no email in OIDC. Create new suborg
|
|
317
|
+
orgId = (await sdkServer.server.createSuborg(createSuborgData))?.subOrganizationId;
|
|
318
|
+
}
|
|
270
319
|
}
|
|
320
|
+
return orgId ? completeLogin(orgId) : onError(constants.authErrors.oauth.loginFailed);
|
|
271
321
|
};
|
|
272
322
|
const handleLoginWithWallet = async () => {
|
|
273
323
|
setLoading("wallet");
|
|
@@ -300,7 +350,7 @@ const Auth = ({
|
|
|
300
350
|
await indexedDbClient.resetKeyPair();
|
|
301
351
|
const pubKey = await indexedDbClient.getPublicKey();
|
|
302
352
|
await walletClient.loginWithWallet({
|
|
303
|
-
sessionType:
|
|
353
|
+
sessionType: sdkTypes.SessionType.READ_WRITE,
|
|
304
354
|
publicKey: pubKey,
|
|
305
355
|
expirationSeconds: authConfig.sessionLengthSeconds?.toString()
|
|
306
356
|
});
|
|
@@ -345,17 +395,17 @@ const Auth = ({
|
|
|
345
395
|
layout: layout,
|
|
346
396
|
clientId: authConfig.googleClientId ?? process.env.NEXT_PUBLIC_GOOGLE_CLIENT_ID,
|
|
347
397
|
openInPage: authConfig.openOAuthInPage,
|
|
348
|
-
onSuccess: response => handleOAuthLogin(response.idToken, "Google")
|
|
398
|
+
onSuccess: response => handleOAuthLogin(response.idToken, "Google", authConfig.socialLinking)
|
|
349
399
|
}), appleEnabled && jsxRuntime.jsx(Apple.default, {
|
|
350
400
|
layout: layout,
|
|
351
401
|
clientId: authConfig.appleClientId ?? process.env.NEXT_PUBLIC_APPLE_CLIENT_ID,
|
|
352
402
|
openInPage: authConfig.openOAuthInPage,
|
|
353
|
-
onSuccess: response => handleOAuthLogin(response.idToken, "Apple")
|
|
403
|
+
onSuccess: response => handleOAuthLogin(response.idToken, "Apple") // No need to pass socialLinking for Apple. It's not supported
|
|
354
404
|
}), facebookEnabled && jsxRuntime.jsx(Facebook.default, {
|
|
355
405
|
layout: layout,
|
|
356
406
|
clientId: authConfig.facebookClientId ?? process.env.NEXT_PUBLIC_FACEBOOK_CLIENT_ID,
|
|
357
407
|
openInPage: authConfig.openOAuthInPage,
|
|
358
|
-
onSuccess: response => handleOAuthLogin(response.id_token, "Facebook")
|
|
408
|
+
onSuccess: response => handleOAuthLogin(response.id_token, "Facebook") // No need to pass socialLinking for Facebook. It's not supported
|
|
359
409
|
})]
|
|
360
410
|
});
|
|
361
411
|
};
|