@rakomi/react-native 0.2.0 → 0.3.1
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/COMPLIANCE.md +3 -3
- package/README.md +24 -6
- package/THIRD-PARTY-NOTICES +1 -1
- package/dist/index.cjs +40 -6
- package/dist/index.d.cts +30 -8
- package/dist/index.d.ts +30 -8
- package/dist/index.js +34 -8
- package/package.json +3 -3
- package/sbom.cdx.json +10 -10
package/COMPLIANCE.md
CHANGED
|
@@ -10,7 +10,7 @@ This package is a "product with digital elements" under CRA Art. 3(1). Same post
|
|
|
10
10
|
|---|---|
|
|
11
11
|
| Art. 13 — Vulnerability handling | Documented secure vulnerability-handling process; vulnerability records retained with the technical documentation. Internal fix targets (e.g. 14 days for High severity) are an operational SLA, **not** a statutory deadline. See `SECURITY.md`. |
|
|
12
12
|
| Art. 14 — Reporting of actively exploited vulnerabilities & severe incidents | Statutory reporting to the designated authority on the CRA timeline (early warning → notification → final report) and informing impacted users; published advisories via GitHub Security Advisories. See `SECURITY.md`. |
|
|
13
|
-
| Annex I — Essential cybersecurity requirements | Secure defaults: fixed asymmetric token-signature verification, PKCE with S256 challenge (RFC 7636), biometric opt-in, ephemeral session, minimal attack surface. **Passkeys:** no passkey library is bundled or depended on by **this package** — the OS ceremony is reached through a module the host supplies. Read that precisely: it removes third-party ceremony code from *our* dependency tree and therefore from *our* SBOM; the module you wire **is** on the credential path and is **your** supply-chain surface, so account for it in yours. The bridge itself carries no bearer token, emits nothing to telemetry or the console, and an unwired adapter fails closed (`PASSKEY_NOT_SUPPORTED`) rather than falling back to a different ceremony.
|
|
13
|
+
| Annex I — Essential cybersecurity requirements | Secure defaults: fixed asymmetric token-signature verification, PKCE with S256 challenge (RFC 7636), biometric opt-in, ephemeral session, minimal attack surface. **Passkeys:** no passkey library is bundled or depended on by **this package** — the OS ceremony is reached through a module the host supplies. Read that precisely: it removes third-party ceremony code from *our* dependency tree and therefore from *our* SBOM; the module you wire **is** on the credential path and is **your** supply-chain surface, so account for it in yours. The bridge itself carries no bearer token, emits nothing to telemetry or the console, and an unwired adapter fails closed (`PASSKEY_NOT_SUPPORTED`) rather than falling back to a different ceremony. |
|
|
14
14
|
|
|
15
15
|
## GDPR — Reg. (EU) 2016/679
|
|
16
16
|
|
|
@@ -18,8 +18,8 @@ This package is a "product with digital elements" under CRA Art. 3(1). Same post
|
|
|
18
18
|
|---|---|
|
|
19
19
|
| Art. 25 — Data protection by design | No PII collected client-side beyond what API requires; analytics opt-in via `onEvent` only. **Passkeys — sign-in:** identified sign-in takes an opaque, server-issued user handle, never an email or a username. **Passkeys — registration (state this plainly):** the registration options the server issues carry the account's `user.name` / `user.displayName`, which today is the user's **email address**. It crosses the bridge to the host-supplied module and is passed to the platform credential provider, which stores it with the credential and may **sync it to the user's platform account** (iCloud Keychain / Google Password Manager). This is inherent to WebAuthn — the value is what the user is shown when they pick a passkey — not a choice this SDK makes, and it is disclosed here rather than glossed. The SDK adds no identifier of its own. **Errors:** the credential-envelope validator names the failing FIELD, never its VALUE; error messages relayed from the server or from the host's own callbacks are passed through verbatim and are the tenant's surface to control. |
|
|
20
20
|
| Art. 28 — Processor obligations | SDK is a data-processor adjunct; tenant is data controller. DPA covers the relationship. |
|
|
21
|
-
| Art. 32 — Security of processing | Pseudonymisation + encryption at rest (Keychain) + access control (biometric opt-in). **Passkeys — key material:** the private key is created and held by the platform credential provider; it never enters SDK memory and the SDK holds no passkey material at rest.
|
|
22
|
-
| Art. 32 — Security of processing (session integrity) | A completed ceremony whose session was **not** actually stored is reported as a failure, never as a success — the SDK re-reads the token runtime and matches the session identity before it reports a sign-in.
|
|
21
|
+
| Art. 32 — Security of processing | Pseudonymisation + encryption at rest (Keychain) + access control (biometric opt-in). **Passkeys — key material:** the private key is created and held by the platform credential provider; it never enters SDK memory and the SDK holds no passkey material at rest. No access token, step-up token or bearer secret reaches the ceremony adapter. |
|
|
22
|
+
| Art. 32 — Security of processing (session integrity) | A completed ceremony whose session was **not** actually stored is reported as a failure, never as a success — the SDK re-reads the token runtime and matches the session identity before it reports a sign-in. |
|
|
23
23
|
| Art. 32 — Security of processing (re-authentication gate) | Management actions (list / rename / delete) are re-authentication-gated. **The gate is enforced by the API, not by this SDK** — the SDK transmits the step-up token it is given and does not itself decide whether one is sufficient. Stated here because an SDK compliance doc must not claim credit for a server-side control. |
|
|
24
24
|
| Art. 9 — Special categories (negative scope) | **No biometric data is processed by this SDK.** A fingerprint or face is consumed by the operating system to unlock the authenticator; the SDK receives only the resulting assertion. It never reads, stores, transmits or infers a biometric template, so Art. 9's special-category regime is not engaged by anything this library does. (Whether YOUR app processes biometrics for other purposes is your assessment.) |
|
|
25
25
|
|
package/README.md
CHANGED
|
@@ -2,9 +2,27 @@
|
|
|
2
2
|
|
|
3
3
|
React Native / Expo SDK for [Rakomi](https://rakomi.com) — EU-native auth-as-a-service.
|
|
4
4
|
|
|
5
|
-
> **Status
|
|
6
|
-
>
|
|
7
|
-
>
|
|
5
|
+
> **Status: PREVIEW.** `@rakomi/react-native` is a pre-1.0 package — no stability or support
|
|
6
|
+
> guarantee (SemVer 2.0.0 §4). The exported hook and component **surface** is frozen for parity with
|
|
7
|
+
> [`@rakomi/react`](https://www.npmjs.com/package/@rakomi/react), and every name below is exported
|
|
8
|
+
> and type-checked, but not every export's **behavior** is wired to the network yet.
|
|
9
|
+
>
|
|
10
|
+
> **Works today:** social sign-in via the system browser (`<SignIn providers={[...]} />` /
|
|
11
|
+
> `startSocialSignIn()`), magic link, email OTP, registration, MFA (TOTP), passkeys
|
|
12
|
+
> (sign-in/step-up/register/list/rename/delete), session management (`useAuth`, `useSession`,
|
|
13
|
+
> `getToken`), `<UserButton>`, `<SignedIn>`/`<SignedOut>`, `<Protect>`, `useOrganization` /
|
|
14
|
+
> `useOrganizationList` (JWT-claim reads), `useAuthConfig`, `useBranding`, `useBaasPlans`,
|
|
15
|
+
> `useBaasSubscription`.
|
|
16
|
+
>
|
|
17
|
+
> **Not yet wired — calls resolve/return an error placeholder, no network request is made:**
|
|
18
|
+
> `useAuth().signIn()` (direct email+password) and `useAuth().switchOrganization()`;
|
|
19
|
+
> `useLinkedAccounts().link()`/`.unlink()`; `useAnonymousSignin().signInAnonymously()`. `<SignIn />`
|
|
20
|
+
> renders social providers and MFA TOTP entry only — there is no password field in the pre-built
|
|
21
|
+
> component. `<UserProfile>` and `<Feature>` are marked preview individually below. Each of these is
|
|
22
|
+
> also called out at its own symbol in the [full reference docs](https://docs.rakomi.dev/sdk/react-native/authentication/#what-works-today).
|
|
23
|
+
>
|
|
24
|
+
> Token-manager runtime, JWKS verification, social-provider deep-link auto-handler, a bare-RN adapter
|
|
25
|
+
> example, and a demo app land in subsequent 0.x releases.
|
|
8
26
|
|
|
9
27
|
## Install
|
|
10
28
|
|
|
@@ -36,11 +54,11 @@ export default function App() {
|
|
|
36
54
|
}
|
|
37
55
|
```
|
|
38
56
|
|
|
39
|
-
## What's included
|
|
57
|
+
## What's included
|
|
40
58
|
|
|
41
59
|
- **`<RakomiProvider>`** — context provider. Freezes the native adapter on mount. AppState debounce 300ms. Connectivity transitions wired.
|
|
42
|
-
- **Hooks (parity-locked):** `useAuth`, `useUser`, `useSession`, `useFlag`, `useOrganization`, `useOrganizationList`, `useLinkedAccounts
|
|
43
|
-
- **Components:** `<SignIn />` (
|
|
60
|
+
- **Hooks (parity-locked):** `useAuth`, `useUser`, `useSession`, `useFlag`, `useOrganization`, `useOrganizationList`, `useLinkedAccounts` (preview), `useTranslation`, `useAuthConfig`, `useBranding`, `useAnonymousSignin` (preview), `useBaasPlans`, `useBaasSubscription`. Type-level parity with `@rakomi/react` is enforced by CI — see the status banner above for which hooks make real network calls today.
|
|
61
|
+
- **Components:** `<SignIn />` (social + MFA TOTP — no password field), `<SignUp />`, `<UserButton />`, `<UserProfile />` (preview), `<SignedIn>`, `<SignedOut>`, `<Protect>`, `<Feature>` (preview — reads the JWT directly, no live evaluation). RN primitives only — no HTML, no WebView.
|
|
44
62
|
- **OAuth (RFC 8252):** PKCE S256, 32-byte state with single-use 60s TTL + constant-time comparison, system browser via `expo-web-browser` (`preferEphemeralSession: true` default), confused-deputy guard on callback ingest.
|
|
45
63
|
- **Native adapter contract:** `NativeAuthAdapter` interface with forward-compat slots (`verifiers` for EUDI, `dpopProver` for DPoP, `par` for RFC 9126 PAR).
|
|
46
64
|
- **`tokenCache` injection sugar** — replace storage without re-implementing the full adapter.
|
package/THIRD-PARTY-NOTICES
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
THIRD-PARTY SOFTWARE NOTICES AND INFORMATION
|
|
2
2
|
|
|
3
|
-
For the npm package: @rakomi/react-native@0.
|
|
3
|
+
For the npm package: @rakomi/react-native@0.3.1
|
|
4
4
|
|
|
5
5
|
This package's published bundle (`dist/`) INLINES the third-party components listed below.
|
|
6
6
|
Their copyright and permission notices are reproduced verbatim, as required by their licenses
|
package/dist/index.cjs
CHANGED
|
@@ -1013,6 +1013,21 @@ function RakomiProvider(props) {
|
|
|
1013
1013
|
return Object.freeze(built);
|
|
1014
1014
|
}, [props.nativeAdapter, props.tokenCache]);
|
|
1015
1015
|
const http = react.useMemo(() => createRnHttpClient({ baseUrl: props.baseUrl }), [props.baseUrl]);
|
|
1016
|
+
const authorizationEndpointCache = react.useMemo(
|
|
1017
|
+
() => sdkCore.createAuthorizationEndpointCache({
|
|
1018
|
+
fetchDiscoveryDocument: async () => {
|
|
1019
|
+
const response = await http.fetch("/.well-known/openid-configuration", {
|
|
1020
|
+
method: "GET",
|
|
1021
|
+
headers: { Accept: "application/json" }
|
|
1022
|
+
});
|
|
1023
|
+
if (!response.ok) {
|
|
1024
|
+
throw new Error(`discovery fetch failed: HTTP ${response.status}`);
|
|
1025
|
+
}
|
|
1026
|
+
return response.json();
|
|
1027
|
+
}
|
|
1028
|
+
}),
|
|
1029
|
+
[http]
|
|
1030
|
+
);
|
|
1016
1031
|
const events = react.useMemo(() => new sdkCore.EventLog(props.onEvent), [props.onEvent]);
|
|
1017
1032
|
const [snapshot, dispatch] = react.useReducer(sdkCore.reduce, sdkCore.INITIAL_SNAPSHOT);
|
|
1018
1033
|
const passkeyCeremonyLock = react.useRef(createCeremonyLock()).current;
|
|
@@ -1148,6 +1163,7 @@ function RakomiProvider(props) {
|
|
|
1148
1163
|
redirectUri: props.redirectUri,
|
|
1149
1164
|
adapter,
|
|
1150
1165
|
http,
|
|
1166
|
+
authorizationEndpointCache,
|
|
1151
1167
|
snapshot,
|
|
1152
1168
|
state: snapshot.state,
|
|
1153
1169
|
isSignedIn: sdkCore.isSignedIn(snapshot),
|
|
@@ -1163,7 +1179,7 @@ function RakomiProvider(props) {
|
|
|
1163
1179
|
beginAuthFlow,
|
|
1164
1180
|
dpopSession
|
|
1165
1181
|
}),
|
|
1166
|
-
[adapter, http, snapshot, events, props.publishableKey, props.baseUrl, props.redirectUri, props.locale, translate, signOut, getToken, submitOAuthTokens, beginAuthFlow, dpopSession, passkeyCeremonyLock]
|
|
1182
|
+
[adapter, http, authorizationEndpointCache, snapshot, events, props.publishableKey, props.baseUrl, props.redirectUri, props.locale, translate, signOut, getToken, submitOAuthTokens, beginAuthFlow, dpopSession, passkeyCeremonyLock]
|
|
1167
1183
|
);
|
|
1168
1184
|
return /* @__PURE__ */ jsxRuntime.jsx(RakomiContext.Provider, { value, children: props.children });
|
|
1169
1185
|
}
|
|
@@ -1620,14 +1636,24 @@ function SignIn(props) {
|
|
|
1620
1636
|
const [step, setStep] = react.useState({ kind: "methods" });
|
|
1621
1637
|
const [code, setCode] = react.useState("");
|
|
1622
1638
|
const [busy, setBusy] = react.useState(false);
|
|
1623
|
-
const tokenEndpoint = props.tokenEndpoint ?? "/
|
|
1624
|
-
const
|
|
1625
|
-
const totpVerifyEndpoint = props.totpVerifyEndpoint ?? "/v1/auth/mfa/totp/verify";
|
|
1639
|
+
const tokenEndpoint = props.tokenEndpoint ?? "/oauth/token";
|
|
1640
|
+
const totpVerifyEndpoint = props.totpVerifyEndpoint ?? "/v1/auth/mfa/verify-login";
|
|
1626
1641
|
const providers = props.providers ?? ["google"];
|
|
1627
1642
|
async function onProviderPress(provider) {
|
|
1628
1643
|
if (busy) return;
|
|
1629
1644
|
setBusy(true);
|
|
1630
1645
|
ctx.events.push({ type: "sign_in_attempted", severity: "info", metadata: { provider } });
|
|
1646
|
+
let authorizationEndpoint = props.authorizationEndpoint;
|
|
1647
|
+
if (!authorizationEndpoint) {
|
|
1648
|
+
const resolved = await ctx.authorizationEndpointCache.resolve(ctx.baseUrl);
|
|
1649
|
+
if (!resolved.ok) {
|
|
1650
|
+
ctx.events.push({ type: "sign_in_failed", severity: "warning", error: resolved.error });
|
|
1651
|
+
setStep({ kind: "error", error: resolved.error });
|
|
1652
|
+
setBusy(false);
|
|
1653
|
+
return;
|
|
1654
|
+
}
|
|
1655
|
+
authorizationEndpoint = resolved.authorizationEndpoint;
|
|
1656
|
+
}
|
|
1631
1657
|
const outcome = await startSocialSignIn({
|
|
1632
1658
|
adapter: ctx.adapter,
|
|
1633
1659
|
http: ctx.http,
|
|
@@ -1833,7 +1859,7 @@ function UserButton(props) {
|
|
|
1833
1859
|
function UserProfile(props) {
|
|
1834
1860
|
react.useEffect(() => {
|
|
1835
1861
|
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
1836
|
-
console.warn("[@rakomi/react-native] <UserProfile /> is in preview
|
|
1862
|
+
console.warn("[@rakomi/react-native] <UserProfile /> is in preview \u2014 feedback welcome.");
|
|
1837
1863
|
}
|
|
1838
1864
|
}, []);
|
|
1839
1865
|
const ctx = useRakomiContext();
|
|
@@ -2660,7 +2686,7 @@ function useMfa() {
|
|
|
2660
2686
|
const ctx = useRakomiContext();
|
|
2661
2687
|
return {
|
|
2662
2688
|
verifyTotp: async (challengeToken, code, endpoint) => {
|
|
2663
|
-
const url = endpoint ?? `${ctx.baseUrl}/v1/auth/mfa/
|
|
2689
|
+
const url = endpoint ?? `${ctx.baseUrl}/v1/auth/mfa/verify-login`;
|
|
2664
2690
|
const result = await sdkCore.verifyTotp({ http: ctx.http, endpoint: url, challengeToken, code });
|
|
2665
2691
|
if (result.ok) {
|
|
2666
2692
|
const nonce = await ctx.beginAuthFlow();
|
|
@@ -2691,6 +2717,10 @@ Object.defineProperty(exports, "base64url", {
|
|
|
2691
2717
|
enumerable: true,
|
|
2692
2718
|
get: function () { return sdkCore.base64url; }
|
|
2693
2719
|
});
|
|
2720
|
+
Object.defineProperty(exports, "createAuthorizationEndpointCache", {
|
|
2721
|
+
enumerable: true,
|
|
2722
|
+
get: function () { return sdkCore.createAuthorizationEndpointCache; }
|
|
2723
|
+
});
|
|
2694
2724
|
Object.defineProperty(exports, "createTranslator", {
|
|
2695
2725
|
enumerable: true,
|
|
2696
2726
|
get: function () { return sdkCore.createTranslator; }
|
|
@@ -2707,6 +2737,10 @@ Object.defineProperty(exports, "decodeUser", {
|
|
|
2707
2737
|
enumerable: true,
|
|
2708
2738
|
get: function () { return sdkCore.decodeUser; }
|
|
2709
2739
|
});
|
|
2740
|
+
Object.defineProperty(exports, "deriveAuthorizationEndpointFallback", {
|
|
2741
|
+
enumerable: true,
|
|
2742
|
+
get: function () { return sdkCore.deriveAuthorizationEndpointFallback; }
|
|
2743
|
+
});
|
|
2710
2744
|
Object.defineProperty(exports, "generatePkce", {
|
|
2711
2745
|
enumerable: true,
|
|
2712
2746
|
get: function () { return sdkCore.generatePkce; }
|
package/dist/index.d.cts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ReactNode } from 'react';
|
|
2
2
|
import { AuthEvent, Locale, Translations, AuthMachineState, SignInOptions, SignInResult, TokenResult, AuthError, UserResource, HasParams, SwitchOrgResult, SessionResource, AuthConfig, BrandingConfig, OrgMembershipClaim, TranslationFn, OAuthTokenResponse, HttpClient, OpaqueUserHandle, PasskeyCeremonyAdapter, PasskeySummary, PasskeyError, AssertPasskeyResult, StepUpWithPasskeyResult, RegisterPasskeyResult, ListPasskeysResult, PasskeySummaryResult, DeletePasskeyResult, RequestResult, VerifyResult } from '@rakomi/sdk-core';
|
|
3
|
-
export { AssertPasskeyResult, AuthError, AuthEvent, AuthMachineState, CryptoProvider, DeletePasskeyResult, HasParams, HttpClient, KeyValueStore, ListPasskeysResult, Locale, MfaStepUpRequiredError, MfaStepUpUnavailableError, OpaqueUserHandle, PasskeyCeremonyAdapter, PasskeyError, PasskeyErrorCode, PasskeySummary, PasskeySummaryResult, PasskeyTokens, PkceChallenge, RegisterPasskeyResult, RegisterResult, SessionResource, SignInOptions, SignInResult, StepUpWithPasskeyResult, SwitchOrgResult, TokenResult, Translations, UserResource, base64url, createTranslator, decodeJwtPayload, decodeSession, decodeUser, generatePkce, getErrorMessage, hasPermission, hasRole, isSafeUrl, networkError, parseOAuthCallbackError, parseTokenEndpointError, scorePassword, selectPluralForm } from '@rakomi/sdk-core';
|
|
3
|
+
export { AssertPasskeyResult, AuthError, AuthEvent, AuthMachineState, AuthorizationEndpointCache, AuthorizationEndpointCacheOptions, CryptoProvider, DeletePasskeyResult, HasParams, HttpClient, KeyValueStore, ListPasskeysResult, Locale, MfaStepUpRequiredError, MfaStepUpUnavailableError, OpaqueUserHandle, PasskeyCeremonyAdapter, PasskeyError, PasskeyErrorCode, PasskeySummary, PasskeySummaryResult, PasskeyTokens, PkceChallenge, RegisterPasskeyResult, RegisterResult, SessionResource, SignInOptions, SignInResult, StepUpWithPasskeyResult, SwitchOrgResult, TokenResult, Translations, UserResource, base64url, createAuthorizationEndpointCache, createTranslator, decodeJwtPayload, decodeSession, decodeUser, deriveAuthorizationEndpointFallback, generatePkce, getErrorMessage, hasPermission, hasRole, isSafeUrl, networkError, parseOAuthCallbackError, parseTokenEndpointError, scorePassword, selectPluralForm } from '@rakomi/sdk-core';
|
|
4
4
|
import { D as DpopProver, N as NativeAuthAdapter, T as TokenCache } from './passkey-adapter-D_Z3Z7lV.cjs';
|
|
5
5
|
export { A as AppLifecycle, a as AppStateValue, b as AttestationVerifier, B as BackgroundTask, c as BiometricGate, d as BiometricResult, e as BrowserAuthSessionOptions, f as BrowserAuthSessionResult, C as ConnectivityProvider, g as CreateDefaultExpoAdapterOptions, h as CreateNativeDpopProverOptions, i as CreateNativePasskeyAdapterOptions, j as DeepLinkProvider, k as DpopProofInput, l as NativeDpopModuleSpec, m as NativePasskeyCeremonyAdapter, n as NativePasskeyModuleSpec, P as ParClient, S as SystemBrowser, o as createDefaultExpoAdapter, p as createNativeDpopProver, q as createNativePasskeyAdapter } from './passkey-adapter-D_Z3Z7lV.cjs';
|
|
6
6
|
|
|
@@ -134,6 +134,11 @@ declare function RakomiProvider(props: RakomiProviderProps): ReactNode;
|
|
|
134
134
|
* Discriminated-union AuthState — identical to `@rakomi/react`'s `AuthState`.
|
|
135
135
|
*
|
|
136
136
|
* `state: AuthMachineState` is the addition.
|
|
137
|
+
*
|
|
138
|
+
* @experimental Preview — `signIn()` and `switchOrganization()` are present for type parity with
|
|
139
|
+
* `@rakomi/react` but always resolve `{ status: 'error', error: { code: 'INVALID_CONFIG', … } }` in the
|
|
140
|
+
* current release; nothing is wired to the network yet. Use one of the working sign-in paths instead
|
|
141
|
+
* (social, magic link, email OTP, passkeys — see the package README / docs).
|
|
137
142
|
*/
|
|
138
143
|
type AuthState = {
|
|
139
144
|
isLoaded: false;
|
|
@@ -239,13 +244,19 @@ type LinkedMethods = LinkedMethod[];
|
|
|
239
244
|
interface UseLinkedAccountsResult {
|
|
240
245
|
isLoaded: boolean;
|
|
241
246
|
methods: LinkedMethods;
|
|
247
|
+
/** @experimental Preview — always resolves `{ status: 'error' }` in the current release; no network call is made. */
|
|
242
248
|
link: (provider: LinkProvider) => Promise<{
|
|
243
249
|
status: 'redirect' | 'error';
|
|
244
250
|
}>;
|
|
251
|
+
/** @experimental Preview — always resolves `{ status: 'error' }` in the current release; no network call is made. */
|
|
245
252
|
unlink: (provider: LinkProvider | 'password' | 'magic_link' | 'email_otp' | 'passkey') => Promise<{
|
|
246
253
|
status: 'complete' | 'error';
|
|
247
254
|
}>;
|
|
248
255
|
}
|
|
256
|
+
/**
|
|
257
|
+
* @experimental Preview — `methods` reads the JWT's `linked_methods` claim (live), but `link()` and
|
|
258
|
+
* `unlink()` are not yet wired to the network in this release; see the return type's per-field notes.
|
|
259
|
+
*/
|
|
249
260
|
declare function useLinkedAccounts(): UseLinkedAccountsResult;
|
|
250
261
|
declare function useTranslation(): {
|
|
251
262
|
t: TranslationFn;
|
|
@@ -263,12 +274,14 @@ interface UseBrandingReturn {
|
|
|
263
274
|
declare function useBranding(): UseBrandingReturn;
|
|
264
275
|
interface UseAnonymousSigninResult {
|
|
265
276
|
isLoaded: boolean;
|
|
277
|
+
/** @experimental Preview — always resolves `{ status: 'error' }` in the current release; no network call is made. */
|
|
266
278
|
signInAnonymously: (options?: {
|
|
267
279
|
publicMetadata?: Record<string, unknown>;
|
|
268
280
|
}) => Promise<{
|
|
269
281
|
status: 'complete' | 'error';
|
|
270
282
|
}>;
|
|
271
283
|
}
|
|
284
|
+
/** @experimental Preview — `signInAnonymously()` is not yet wired to the network in this release; see the return type's field note. */
|
|
272
285
|
declare function useAnonymousSignin(): UseAnonymousSigninResult;
|
|
273
286
|
interface BaasPlanPublicItem {
|
|
274
287
|
id: string;
|
|
@@ -354,15 +367,19 @@ interface FeatureProps {
|
|
|
354
367
|
declare function Feature({ flag, children, fallback }: FeatureProps): ReactNode;
|
|
355
368
|
|
|
356
369
|
/**
|
|
357
|
-
* `<SignIn />` — RN port.
|
|
370
|
+
* `<SignIn />` — RN port. **Preview:** `@rakomi/react-native` is a pre-1.0 preview package — see the
|
|
371
|
+
* package README for the full "what's wired today" boundary.
|
|
358
372
|
*
|
|
359
373
|
* Renders a sign-in flow using ONLY RN primitives (`<View>`, `<Text>`,
|
|
360
374
|
* `<TextInput>`, `<Pressable>`) — no HTML. Supports:
|
|
361
|
-
* - Password (direct) sign-in.
|
|
362
375
|
* - Social provider list (Google, GitHub, …) via `startSocialSignIn`.
|
|
363
376
|
* - MFA TOTP code entry view (`keyboardType="number-pad"`,
|
|
364
377
|
* `textContentType="oneTimeCode"`, `autoComplete="sms-otp"`).
|
|
365
378
|
*
|
|
379
|
+
* There is no email/password field in this component — direct email+password sign-in is not wired in
|
|
380
|
+
* the current release. Use `useRegister()` for account creation, or one of the other working sign-in
|
|
381
|
+
* paths (magic link, email OTP, passkeys).
|
|
382
|
+
*
|
|
366
383
|
* Accessibility:
|
|
367
384
|
* - Every interactive element has `accessibilityLabel` + `accessibilityRole`.
|
|
368
385
|
* - i18n keys come from `useRakomiContext.translate`.
|
|
@@ -370,11 +387,16 @@ declare function Feature({ flag, children, fallback }: FeatureProps): ReactNode;
|
|
|
370
387
|
*/
|
|
371
388
|
|
|
372
389
|
interface SignInProps {
|
|
373
|
-
/**
|
|
390
|
+
/**
|
|
391
|
+
* Full authorization-endpoint URL to open the system browser to. Default: resolved via OIDC
|
|
392
|
+
* discovery against `baseUrl` (cached, with a host-naming fallback) — see `useRakomiContext()`'s
|
|
393
|
+
* `authorizationEndpointCache`. A bare `${baseUrl}/oauth/authorize` is NOT a valid default: that
|
|
394
|
+
* path on the API host returns JSON, not the hosted login UI.
|
|
395
|
+
*/
|
|
374
396
|
authorizationEndpoint?: string;
|
|
375
|
-
/**
|
|
397
|
+
/** RFC 6749 §3.2 token endpoint used for the PKCE code→token exchange, default `${baseUrl}/oauth/token`. */
|
|
376
398
|
tokenEndpoint?: string;
|
|
377
|
-
/** MFA TOTP verify endpoint, default `${baseUrl}/v1/auth/mfa/
|
|
399
|
+
/** MFA TOTP verify endpoint, default `${baseUrl}/v1/auth/mfa/verify-login`. */
|
|
378
400
|
totpVerifyEndpoint?: string;
|
|
379
401
|
/** Social providers to render. Default: ['google']. */
|
|
380
402
|
providers?: string[];
|
|
@@ -424,8 +446,8 @@ declare function UserButton(props: UserButtonProps): ReactNode;
|
|
|
424
446
|
/**
|
|
425
447
|
* `<UserProfile />` — RN port (PREVIEW).
|
|
426
448
|
*
|
|
427
|
-
*
|
|
428
|
-
*
|
|
449
|
+
* In preview — on first mount in `__DEV__` builds we log a warning so consumers don't accidentally
|
|
450
|
+
* ship it to production ahead of graduation.
|
|
429
451
|
*/
|
|
430
452
|
|
|
431
453
|
interface UserProfileProps {
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ReactNode } from 'react';
|
|
2
2
|
import { AuthEvent, Locale, Translations, AuthMachineState, SignInOptions, SignInResult, TokenResult, AuthError, UserResource, HasParams, SwitchOrgResult, SessionResource, AuthConfig, BrandingConfig, OrgMembershipClaim, TranslationFn, OAuthTokenResponse, HttpClient, OpaqueUserHandle, PasskeyCeremonyAdapter, PasskeySummary, PasskeyError, AssertPasskeyResult, StepUpWithPasskeyResult, RegisterPasskeyResult, ListPasskeysResult, PasskeySummaryResult, DeletePasskeyResult, RequestResult, VerifyResult } from '@rakomi/sdk-core';
|
|
3
|
-
export { AssertPasskeyResult, AuthError, AuthEvent, AuthMachineState, CryptoProvider, DeletePasskeyResult, HasParams, HttpClient, KeyValueStore, ListPasskeysResult, Locale, MfaStepUpRequiredError, MfaStepUpUnavailableError, OpaqueUserHandle, PasskeyCeremonyAdapter, PasskeyError, PasskeyErrorCode, PasskeySummary, PasskeySummaryResult, PasskeyTokens, PkceChallenge, RegisterPasskeyResult, RegisterResult, SessionResource, SignInOptions, SignInResult, StepUpWithPasskeyResult, SwitchOrgResult, TokenResult, Translations, UserResource, base64url, createTranslator, decodeJwtPayload, decodeSession, decodeUser, generatePkce, getErrorMessage, hasPermission, hasRole, isSafeUrl, networkError, parseOAuthCallbackError, parseTokenEndpointError, scorePassword, selectPluralForm } from '@rakomi/sdk-core';
|
|
3
|
+
export { AssertPasskeyResult, AuthError, AuthEvent, AuthMachineState, AuthorizationEndpointCache, AuthorizationEndpointCacheOptions, CryptoProvider, DeletePasskeyResult, HasParams, HttpClient, KeyValueStore, ListPasskeysResult, Locale, MfaStepUpRequiredError, MfaStepUpUnavailableError, OpaqueUserHandle, PasskeyCeremonyAdapter, PasskeyError, PasskeyErrorCode, PasskeySummary, PasskeySummaryResult, PasskeyTokens, PkceChallenge, RegisterPasskeyResult, RegisterResult, SessionResource, SignInOptions, SignInResult, StepUpWithPasskeyResult, SwitchOrgResult, TokenResult, Translations, UserResource, base64url, createAuthorizationEndpointCache, createTranslator, decodeJwtPayload, decodeSession, decodeUser, deriveAuthorizationEndpointFallback, generatePkce, getErrorMessage, hasPermission, hasRole, isSafeUrl, networkError, parseOAuthCallbackError, parseTokenEndpointError, scorePassword, selectPluralForm } from '@rakomi/sdk-core';
|
|
4
4
|
import { D as DpopProver, N as NativeAuthAdapter, T as TokenCache } from './passkey-adapter-D_Z3Z7lV.js';
|
|
5
5
|
export { A as AppLifecycle, a as AppStateValue, b as AttestationVerifier, B as BackgroundTask, c as BiometricGate, d as BiometricResult, e as BrowserAuthSessionOptions, f as BrowserAuthSessionResult, C as ConnectivityProvider, g as CreateDefaultExpoAdapterOptions, h as CreateNativeDpopProverOptions, i as CreateNativePasskeyAdapterOptions, j as DeepLinkProvider, k as DpopProofInput, l as NativeDpopModuleSpec, m as NativePasskeyCeremonyAdapter, n as NativePasskeyModuleSpec, P as ParClient, S as SystemBrowser, o as createDefaultExpoAdapter, p as createNativeDpopProver, q as createNativePasskeyAdapter } from './passkey-adapter-D_Z3Z7lV.js';
|
|
6
6
|
|
|
@@ -134,6 +134,11 @@ declare function RakomiProvider(props: RakomiProviderProps): ReactNode;
|
|
|
134
134
|
* Discriminated-union AuthState — identical to `@rakomi/react`'s `AuthState`.
|
|
135
135
|
*
|
|
136
136
|
* `state: AuthMachineState` is the addition.
|
|
137
|
+
*
|
|
138
|
+
* @experimental Preview — `signIn()` and `switchOrganization()` are present for type parity with
|
|
139
|
+
* `@rakomi/react` but always resolve `{ status: 'error', error: { code: 'INVALID_CONFIG', … } }` in the
|
|
140
|
+
* current release; nothing is wired to the network yet. Use one of the working sign-in paths instead
|
|
141
|
+
* (social, magic link, email OTP, passkeys — see the package README / docs).
|
|
137
142
|
*/
|
|
138
143
|
type AuthState = {
|
|
139
144
|
isLoaded: false;
|
|
@@ -239,13 +244,19 @@ type LinkedMethods = LinkedMethod[];
|
|
|
239
244
|
interface UseLinkedAccountsResult {
|
|
240
245
|
isLoaded: boolean;
|
|
241
246
|
methods: LinkedMethods;
|
|
247
|
+
/** @experimental Preview — always resolves `{ status: 'error' }` in the current release; no network call is made. */
|
|
242
248
|
link: (provider: LinkProvider) => Promise<{
|
|
243
249
|
status: 'redirect' | 'error';
|
|
244
250
|
}>;
|
|
251
|
+
/** @experimental Preview — always resolves `{ status: 'error' }` in the current release; no network call is made. */
|
|
245
252
|
unlink: (provider: LinkProvider | 'password' | 'magic_link' | 'email_otp' | 'passkey') => Promise<{
|
|
246
253
|
status: 'complete' | 'error';
|
|
247
254
|
}>;
|
|
248
255
|
}
|
|
256
|
+
/**
|
|
257
|
+
* @experimental Preview — `methods` reads the JWT's `linked_methods` claim (live), but `link()` and
|
|
258
|
+
* `unlink()` are not yet wired to the network in this release; see the return type's per-field notes.
|
|
259
|
+
*/
|
|
249
260
|
declare function useLinkedAccounts(): UseLinkedAccountsResult;
|
|
250
261
|
declare function useTranslation(): {
|
|
251
262
|
t: TranslationFn;
|
|
@@ -263,12 +274,14 @@ interface UseBrandingReturn {
|
|
|
263
274
|
declare function useBranding(): UseBrandingReturn;
|
|
264
275
|
interface UseAnonymousSigninResult {
|
|
265
276
|
isLoaded: boolean;
|
|
277
|
+
/** @experimental Preview — always resolves `{ status: 'error' }` in the current release; no network call is made. */
|
|
266
278
|
signInAnonymously: (options?: {
|
|
267
279
|
publicMetadata?: Record<string, unknown>;
|
|
268
280
|
}) => Promise<{
|
|
269
281
|
status: 'complete' | 'error';
|
|
270
282
|
}>;
|
|
271
283
|
}
|
|
284
|
+
/** @experimental Preview — `signInAnonymously()` is not yet wired to the network in this release; see the return type's field note. */
|
|
272
285
|
declare function useAnonymousSignin(): UseAnonymousSigninResult;
|
|
273
286
|
interface BaasPlanPublicItem {
|
|
274
287
|
id: string;
|
|
@@ -354,15 +367,19 @@ interface FeatureProps {
|
|
|
354
367
|
declare function Feature({ flag, children, fallback }: FeatureProps): ReactNode;
|
|
355
368
|
|
|
356
369
|
/**
|
|
357
|
-
* `<SignIn />` — RN port.
|
|
370
|
+
* `<SignIn />` — RN port. **Preview:** `@rakomi/react-native` is a pre-1.0 preview package — see the
|
|
371
|
+
* package README for the full "what's wired today" boundary.
|
|
358
372
|
*
|
|
359
373
|
* Renders a sign-in flow using ONLY RN primitives (`<View>`, `<Text>`,
|
|
360
374
|
* `<TextInput>`, `<Pressable>`) — no HTML. Supports:
|
|
361
|
-
* - Password (direct) sign-in.
|
|
362
375
|
* - Social provider list (Google, GitHub, …) via `startSocialSignIn`.
|
|
363
376
|
* - MFA TOTP code entry view (`keyboardType="number-pad"`,
|
|
364
377
|
* `textContentType="oneTimeCode"`, `autoComplete="sms-otp"`).
|
|
365
378
|
*
|
|
379
|
+
* There is no email/password field in this component — direct email+password sign-in is not wired in
|
|
380
|
+
* the current release. Use `useRegister()` for account creation, or one of the other working sign-in
|
|
381
|
+
* paths (magic link, email OTP, passkeys).
|
|
382
|
+
*
|
|
366
383
|
* Accessibility:
|
|
367
384
|
* - Every interactive element has `accessibilityLabel` + `accessibilityRole`.
|
|
368
385
|
* - i18n keys come from `useRakomiContext.translate`.
|
|
@@ -370,11 +387,16 @@ declare function Feature({ flag, children, fallback }: FeatureProps): ReactNode;
|
|
|
370
387
|
*/
|
|
371
388
|
|
|
372
389
|
interface SignInProps {
|
|
373
|
-
/**
|
|
390
|
+
/**
|
|
391
|
+
* Full authorization-endpoint URL to open the system browser to. Default: resolved via OIDC
|
|
392
|
+
* discovery against `baseUrl` (cached, with a host-naming fallback) — see `useRakomiContext()`'s
|
|
393
|
+
* `authorizationEndpointCache`. A bare `${baseUrl}/oauth/authorize` is NOT a valid default: that
|
|
394
|
+
* path on the API host returns JSON, not the hosted login UI.
|
|
395
|
+
*/
|
|
374
396
|
authorizationEndpoint?: string;
|
|
375
|
-
/**
|
|
397
|
+
/** RFC 6749 §3.2 token endpoint used for the PKCE code→token exchange, default `${baseUrl}/oauth/token`. */
|
|
376
398
|
tokenEndpoint?: string;
|
|
377
|
-
/** MFA TOTP verify endpoint, default `${baseUrl}/v1/auth/mfa/
|
|
399
|
+
/** MFA TOTP verify endpoint, default `${baseUrl}/v1/auth/mfa/verify-login`. */
|
|
378
400
|
totpVerifyEndpoint?: string;
|
|
379
401
|
/** Social providers to render. Default: ['google']. */
|
|
380
402
|
providers?: string[];
|
|
@@ -424,8 +446,8 @@ declare function UserButton(props: UserButtonProps): ReactNode;
|
|
|
424
446
|
/**
|
|
425
447
|
* `<UserProfile />` — RN port (PREVIEW).
|
|
426
448
|
*
|
|
427
|
-
*
|
|
428
|
-
*
|
|
449
|
+
* In preview — on first mount in `__DEV__` builds we log a warning so consumers don't accidentally
|
|
450
|
+
* ship it to production ahead of graduation.
|
|
429
451
|
*/
|
|
430
452
|
|
|
431
453
|
interface UserProfileProps {
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createContext, useMemo, useReducer, useRef, useEffect, useState, useCallback, useContext } from 'react';
|
|
2
|
-
import { EventLog, reduce, INITIAL_SNAPSHOT, createTranslator, isSignedIn, hasPermission, hasRole, extractOrgClaims, parseAuthConfigResponse, generatePkce, issueState, buildAuthorizationUrl, consumeState, exchangeAuthCode, parseOAuthCallbackError, scorePassword, isSafeUrl, passkeyError, decodeUser, assertPasskey, stepUpWithPasskey, registerPasskey, listPasskeys, renamePasskey, deletePasskey, verifyMagicLink, requestMagicLink, verifyEmailOtp, requestEmailOtp, register, verifyTotp, MfaStepUpUnavailableError, decodeSession, deriveTenantStorageKey, createJwksCache, refreshAccessToken, decodeJwtPayload, PasskeyCeremonyError } from '@rakomi/sdk-core';
|
|
3
|
-
export { MfaStepUpRequiredError, MfaStepUpUnavailableError, base64url, createTranslator, decodeJwtPayload, decodeSession, decodeUser, generatePkce, getErrorMessage, hasPermission, hasRole, isSafeUrl, networkError, parseOAuthCallbackError, parseTokenEndpointError, scorePassword, selectPluralForm } from '@rakomi/sdk-core';
|
|
2
|
+
import { createAuthorizationEndpointCache, EventLog, reduce, INITIAL_SNAPSHOT, createTranslator, isSignedIn, hasPermission, hasRole, extractOrgClaims, parseAuthConfigResponse, generatePkce, issueState, buildAuthorizationUrl, consumeState, exchangeAuthCode, parseOAuthCallbackError, scorePassword, isSafeUrl, passkeyError, decodeUser, assertPasskey, stepUpWithPasskey, registerPasskey, listPasskeys, renamePasskey, deletePasskey, verifyMagicLink, requestMagicLink, verifyEmailOtp, requestEmailOtp, register, verifyTotp, MfaStepUpUnavailableError, decodeSession, deriveTenantStorageKey, createJwksCache, refreshAccessToken, decodeJwtPayload, PasskeyCeremonyError } from '@rakomi/sdk-core';
|
|
3
|
+
export { MfaStepUpRequiredError, MfaStepUpUnavailableError, base64url, createAuthorizationEndpointCache, createTranslator, decodeJwtPayload, decodeSession, decodeUser, deriveAuthorizationEndpointFallback, generatePkce, getErrorMessage, hasPermission, hasRole, isSafeUrl, networkError, parseOAuthCallbackError, parseTokenEndpointError, scorePassword, selectPluralForm } from '@rakomi/sdk-core';
|
|
4
4
|
import { jwtVerify } from 'jose';
|
|
5
5
|
import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
|
|
6
6
|
|
|
@@ -1012,6 +1012,21 @@ function RakomiProvider(props) {
|
|
|
1012
1012
|
return Object.freeze(built);
|
|
1013
1013
|
}, [props.nativeAdapter, props.tokenCache]);
|
|
1014
1014
|
const http = useMemo(() => createRnHttpClient({ baseUrl: props.baseUrl }), [props.baseUrl]);
|
|
1015
|
+
const authorizationEndpointCache = useMemo(
|
|
1016
|
+
() => createAuthorizationEndpointCache({
|
|
1017
|
+
fetchDiscoveryDocument: async () => {
|
|
1018
|
+
const response = await http.fetch("/.well-known/openid-configuration", {
|
|
1019
|
+
method: "GET",
|
|
1020
|
+
headers: { Accept: "application/json" }
|
|
1021
|
+
});
|
|
1022
|
+
if (!response.ok) {
|
|
1023
|
+
throw new Error(`discovery fetch failed: HTTP ${response.status}`);
|
|
1024
|
+
}
|
|
1025
|
+
return response.json();
|
|
1026
|
+
}
|
|
1027
|
+
}),
|
|
1028
|
+
[http]
|
|
1029
|
+
);
|
|
1015
1030
|
const events = useMemo(() => new EventLog(props.onEvent), [props.onEvent]);
|
|
1016
1031
|
const [snapshot, dispatch] = useReducer(reduce, INITIAL_SNAPSHOT);
|
|
1017
1032
|
const passkeyCeremonyLock = useRef(createCeremonyLock()).current;
|
|
@@ -1147,6 +1162,7 @@ function RakomiProvider(props) {
|
|
|
1147
1162
|
redirectUri: props.redirectUri,
|
|
1148
1163
|
adapter,
|
|
1149
1164
|
http,
|
|
1165
|
+
authorizationEndpointCache,
|
|
1150
1166
|
snapshot,
|
|
1151
1167
|
state: snapshot.state,
|
|
1152
1168
|
isSignedIn: isSignedIn(snapshot),
|
|
@@ -1162,7 +1178,7 @@ function RakomiProvider(props) {
|
|
|
1162
1178
|
beginAuthFlow,
|
|
1163
1179
|
dpopSession
|
|
1164
1180
|
}),
|
|
1165
|
-
[adapter, http, snapshot, events, props.publishableKey, props.baseUrl, props.redirectUri, props.locale, translate, signOut, getToken, submitOAuthTokens, beginAuthFlow, dpopSession, passkeyCeremonyLock]
|
|
1181
|
+
[adapter, http, authorizationEndpointCache, snapshot, events, props.publishableKey, props.baseUrl, props.redirectUri, props.locale, translate, signOut, getToken, submitOAuthTokens, beginAuthFlow, dpopSession, passkeyCeremonyLock]
|
|
1166
1182
|
);
|
|
1167
1183
|
return /* @__PURE__ */ jsx(RakomiContext.Provider, { value, children: props.children });
|
|
1168
1184
|
}
|
|
@@ -1619,14 +1635,24 @@ function SignIn(props) {
|
|
|
1619
1635
|
const [step, setStep] = useState({ kind: "methods" });
|
|
1620
1636
|
const [code, setCode] = useState("");
|
|
1621
1637
|
const [busy, setBusy] = useState(false);
|
|
1622
|
-
const tokenEndpoint = props.tokenEndpoint ?? "/
|
|
1623
|
-
const
|
|
1624
|
-
const totpVerifyEndpoint = props.totpVerifyEndpoint ?? "/v1/auth/mfa/totp/verify";
|
|
1638
|
+
const tokenEndpoint = props.tokenEndpoint ?? "/oauth/token";
|
|
1639
|
+
const totpVerifyEndpoint = props.totpVerifyEndpoint ?? "/v1/auth/mfa/verify-login";
|
|
1625
1640
|
const providers = props.providers ?? ["google"];
|
|
1626
1641
|
async function onProviderPress(provider) {
|
|
1627
1642
|
if (busy) return;
|
|
1628
1643
|
setBusy(true);
|
|
1629
1644
|
ctx.events.push({ type: "sign_in_attempted", severity: "info", metadata: { provider } });
|
|
1645
|
+
let authorizationEndpoint = props.authorizationEndpoint;
|
|
1646
|
+
if (!authorizationEndpoint) {
|
|
1647
|
+
const resolved = await ctx.authorizationEndpointCache.resolve(ctx.baseUrl);
|
|
1648
|
+
if (!resolved.ok) {
|
|
1649
|
+
ctx.events.push({ type: "sign_in_failed", severity: "warning", error: resolved.error });
|
|
1650
|
+
setStep({ kind: "error", error: resolved.error });
|
|
1651
|
+
setBusy(false);
|
|
1652
|
+
return;
|
|
1653
|
+
}
|
|
1654
|
+
authorizationEndpoint = resolved.authorizationEndpoint;
|
|
1655
|
+
}
|
|
1630
1656
|
const outcome = await startSocialSignIn({
|
|
1631
1657
|
adapter: ctx.adapter,
|
|
1632
1658
|
http: ctx.http,
|
|
@@ -1832,7 +1858,7 @@ function UserButton(props) {
|
|
|
1832
1858
|
function UserProfile(props) {
|
|
1833
1859
|
useEffect(() => {
|
|
1834
1860
|
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
1835
|
-
console.warn("[@rakomi/react-native] <UserProfile /> is in preview
|
|
1861
|
+
console.warn("[@rakomi/react-native] <UserProfile /> is in preview \u2014 feedback welcome.");
|
|
1836
1862
|
}
|
|
1837
1863
|
}, []);
|
|
1838
1864
|
const ctx = useRakomiContext();
|
|
@@ -2659,7 +2685,7 @@ function useMfa() {
|
|
|
2659
2685
|
const ctx = useRakomiContext();
|
|
2660
2686
|
return {
|
|
2661
2687
|
verifyTotp: async (challengeToken, code, endpoint) => {
|
|
2662
|
-
const url = endpoint ?? `${ctx.baseUrl}/v1/auth/mfa/
|
|
2688
|
+
const url = endpoint ?? `${ctx.baseUrl}/v1/auth/mfa/verify-login`;
|
|
2663
2689
|
const result = await verifyTotp({ http: ctx.http, endpoint: url, challengeToken, code });
|
|
2664
2690
|
if (result.ok) {
|
|
2665
2691
|
const nonce = await ctx.beginAuthFlow();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rakomi/react-native",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "React Native / Expo SDK for Rakomi authentication.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"rakomi",
|
|
@@ -83,11 +83,11 @@
|
|
|
83
83
|
}
|
|
84
84
|
},
|
|
85
85
|
"devDependencies": {
|
|
86
|
-
"@rakomi/react": "0.
|
|
86
|
+
"@rakomi/react": "0.3.1"
|
|
87
87
|
},
|
|
88
88
|
"dependencies": {
|
|
89
89
|
"jose": "^6.2.3",
|
|
90
|
-
"@rakomi/sdk-core": "^0.
|
|
90
|
+
"@rakomi/sdk-core": "^0.3.1"
|
|
91
91
|
},
|
|
92
92
|
"scripts": {
|
|
93
93
|
"build": "NODE_OPTIONS=--max-old-space-size=4096 tsup",
|
package/sbom.cdx.json
CHANGED
|
@@ -20,16 +20,16 @@
|
|
|
20
20
|
"type": "application",
|
|
21
21
|
"group": "rakomi",
|
|
22
22
|
"name": "generate-sbom",
|
|
23
|
-
"version": "sha256:
|
|
23
|
+
"version": "sha256:ffabbf3f1638"
|
|
24
24
|
}
|
|
25
25
|
]
|
|
26
26
|
},
|
|
27
27
|
"component": {
|
|
28
28
|
"type": "library",
|
|
29
|
-
"bom-ref": "pkg:npm/%40rakomi%2Freact-native@0.
|
|
29
|
+
"bom-ref": "pkg:npm/%40rakomi%2Freact-native@0.3.1",
|
|
30
30
|
"name": "@rakomi/react-native",
|
|
31
|
-
"version": "0.
|
|
32
|
-
"purl": "pkg:npm/%40rakomi%2Freact-native@0.
|
|
31
|
+
"version": "0.3.1",
|
|
32
|
+
"purl": "pkg:npm/%40rakomi%2Freact-native@0.3.1",
|
|
33
33
|
"licenses": [
|
|
34
34
|
{
|
|
35
35
|
"license": {
|
|
@@ -42,10 +42,10 @@
|
|
|
42
42
|
"components": [
|
|
43
43
|
{
|
|
44
44
|
"type": "library",
|
|
45
|
-
"bom-ref": "pkg:npm/@rakomi/sdk-core@0.
|
|
45
|
+
"bom-ref": "pkg:npm/@rakomi/sdk-core@0.3.1",
|
|
46
46
|
"name": "@rakomi/sdk-core",
|
|
47
|
-
"version": "0.
|
|
48
|
-
"purl": "pkg:npm/@rakomi/sdk-core@0.
|
|
47
|
+
"version": "0.3.1",
|
|
48
|
+
"purl": "pkg:npm/@rakomi/sdk-core@0.3.1",
|
|
49
49
|
"licenses": [
|
|
50
50
|
{
|
|
51
51
|
"license": {
|
|
@@ -56,10 +56,10 @@
|
|
|
56
56
|
},
|
|
57
57
|
{
|
|
58
58
|
"type": "library",
|
|
59
|
-
"bom-ref": "pkg:npm/jose@6.2.
|
|
59
|
+
"bom-ref": "pkg:npm/jose@6.2.10",
|
|
60
60
|
"name": "jose",
|
|
61
|
-
"version": "6.2.
|
|
62
|
-
"purl": "pkg:npm/jose@6.2.
|
|
61
|
+
"version": "6.2.10",
|
|
62
|
+
"purl": "pkg:npm/jose@6.2.10",
|
|
63
63
|
"licenses": [
|
|
64
64
|
{
|
|
65
65
|
"license": {
|