@propeller-commerce/propeller-v2-react-ui 0.9.0 → 0.10.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 CHANGED
@@ -8,6 +8,19 @@ once it reaches 1.0. Until then (the `0.x` line) the public API may change
8
8
  between minor versions; breaking changes are called out below and in
9
9
  [MIGRATION.md](./MIGRATION.md).
10
10
 
11
+ ## [0.10.0] - 2026-07-29
12
+
13
+ ### Added
14
+
15
+ - **Magic-token authentication in `useAuth`.** `magicLogin(token)` exchanges a
16
+ backend-issued magic token for a session (via
17
+ `MagicTokenService.magicTokenLogin`), sets the in-memory Bearer header — never
18
+ `setAccessToken` — and loads the viewer, mirroring `login()`. This is the
19
+ passwordless / punchout deep-link handoff. `createMagicToken(input)` issues a
20
+ magic token for a contact/customer (`MagicTokenCreateInput`, authenticated).
21
+ Both return the standard `Result` and are exposed on `UseAuthReturn`. No new
22
+ runtime dependency — the SDK's `MagicTokenService` ships in 0.14.0.
23
+
11
24
  ## [0.9.0] - 2026-07-29
12
25
 
13
26
  ### Changed
package/dist/index.cjs CHANGED
@@ -307,6 +307,66 @@ function useAuth(options) {
307
307
  setLoading(false);
308
308
  }
309
309
  }, [graphqlClient, language, onAuthHeaderUpdate, configuration]);
310
+ const magicLogin = React6.useCallback(async (token) => {
311
+ setLoading(true);
312
+ setError(null);
313
+ try {
314
+ const loginResult = await new propellerSdkV2.MagicTokenService(graphqlClient).magicTokenLogin(token);
315
+ const session = loginResult?.session;
316
+ const accessToken = session?.accessToken;
317
+ const refreshToken = session?.refreshToken;
318
+ const expiresAt = session?.expirationTime;
319
+ if (accessToken) {
320
+ const cfg = graphqlClient.getConfig();
321
+ graphqlClient.updateConfig({
322
+ headers: { ...cfg.headers, Authorization: `Bearer ${accessToken}` }
323
+ });
324
+ onAuthHeaderUpdate?.(accessToken);
325
+ }
326
+ const userService = propellerV2CoreUi.createServices(graphqlClient).user;
327
+ const viewerInput = {
328
+ ...configuration?.contactTrackAttributes?.length && {
329
+ contactAttributesInput: { attributeDescription: { names: configuration.contactTrackAttributes } }
330
+ },
331
+ ...configuration?.customerTrackAttributes?.length && {
332
+ customerAttributesInput: { attributeDescription: { names: configuration.customerTrackAttributes } }
333
+ },
334
+ ...configuration?.companyTrackAttributes?.length && {
335
+ companyAttributesInput: { attributeDescription: { names: configuration.companyTrackAttributes } }
336
+ },
337
+ // See isViewerSearchInput — an empty array `[]` is truthy but 400s the viewer.
338
+ ...isViewerSearchInput(configuration?.contactPAConfigInput) && {
339
+ contactPAConfigInput: configuration.contactPAConfigInput
340
+ },
341
+ ...isViewerSearchInput(configuration?.contactCompaniesSearchInput) && {
342
+ contactCompaniesSearchInput: configuration.contactCompaniesSearchInput
343
+ }
344
+ };
345
+ const viewer = await userService.getViewer(viewerInput);
346
+ const user = viewer;
347
+ return propellerV2CoreUi.ok({ user, accessToken, refreshToken, expiresAt });
348
+ } catch (e) {
349
+ const msg = e instanceof Error ? e.message : "Magic-token login failed";
350
+ setError(msg);
351
+ return propellerV2CoreUi.err(msg);
352
+ } finally {
353
+ setLoading(false);
354
+ }
355
+ }, [graphqlClient, onAuthHeaderUpdate, configuration]);
356
+ const createMagicToken = React6.useCallback(async (input) => {
357
+ setLoading(true);
358
+ setError(null);
359
+ try {
360
+ const token = await new propellerSdkV2.MagicTokenService(graphqlClient).createMagicToken(input);
361
+ return propellerV2CoreUi.ok(token);
362
+ } catch (e) {
363
+ const msg = e instanceof Error ? e.message : "Failed to create magic token";
364
+ setError(msg);
365
+ return propellerV2CoreUi.err(msg);
366
+ } finally {
367
+ setLoading(false);
368
+ }
369
+ }, [graphqlClient]);
310
370
  const registerContact = React6.useCallback(async (input, preferredLanguage = language, autoLogin = true) => {
311
371
  setLoading(true);
312
372
  setError(null);
@@ -553,7 +613,7 @@ function useAuth(options) {
553
613
  setLoading(false);
554
614
  }
555
615
  }, [graphqlClient]);
556
- return { loading, error, login, registerContact, registerCustomer, forgotPassword };
616
+ return { loading, error, login, magicLogin, createMagicToken, registerContact, registerCustomer, forgotPassword };
557
617
  }
558
618
  async function initCart(config) {
559
619
  const {