From deed976ec8ba0ff490b2054f74f04efe5530c84c Mon Sep 17 00:00:00 2001 From: David Dal Busco Date: Wed, 3 Sep 2025 08:32:51 +0200 Subject: [PATCH 01/18] docs: authentication with Passkeys Signed-off-by: David Dal Busco --- docs/build/authentication/index.md | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/docs/build/authentication/index.md b/docs/build/authentication/index.md index a1361648..9a47adfd 100644 --- a/docs/build/authentication/index.md +++ b/docs/build/authentication/index.md @@ -6,24 +6,41 @@ keywords: secure user identification, user identity, Internet Identity, - NFID + NFID, + Passkey, + WebAuthn ] --- # Authentication -Juno allows you to securely identify users **anonymously**. +Juno allows you to securely identify users anonymously, without passwords and without tracking. -Our easy-to-use SDKs support authentication through [Internet Identity] and [NFID]. +You can choose between [Passkeys] for built-in authentication, or integrate third-party providers like [Internet Identity] or [NFID]. -Juno Authentication integrates tightly with other Juno services like [datastore](../datastore/index.mdx) and [storage](../storage/index.mdx). +Authentication works hand-in-hand with other Juno services like [Datastore](../datastore/index.mdx) and [Storage](../storage/index.mdx). -You can manage your users in the [authentication](https://console.juno.build/authentication) view in Juno's console. A new entry is created when a user successfully signs in. +You can see and manage your users anytime in the [authentication](https://console.juno.build/authentication) view of the Console. ![An overview of the anonymous display of the users in Juno Console](../../img/satellite/authentication.webp) --- +## User Identity + +When someone signs in to your app, they get an identity. + +That identity is what ties them to the data they create and the actions they take. + +Identities are: + +- **Anonymous**: they don't expose personal info. +- **Scoped**: they are unique to the domain (or subdomain) where the user signs in. + +Together, this makes authentication privacy-friendly by default and predictable for developers. + +--- + ## Domain-Based User Identity For privacy reasons and to prevent tracking across sites, Juno's authentication is tied to the domain your app uses. From f142004efb9cee419b2fb52c3162cf4a67f500f7 Mon Sep 17 00:00:00 2001 From: David Dal Busco Date: Wed, 3 Sep 2025 09:22:00 +0200 Subject: [PATCH 02/18] docs: review domain based Signed-off-by: David Dal Busco --- docs/build/authentication/index.md | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/docs/build/authentication/index.md b/docs/build/authentication/index.md index 9a47adfd..26fa21a5 100644 --- a/docs/build/authentication/index.md +++ b/docs/build/authentication/index.md @@ -41,23 +41,27 @@ Together, this makes authentication privacy-friendly by default and predictable --- -## Domain-Based User Identity +## Domain-Based Identity -For privacy reasons and to prevent tracking across sites, Juno's authentication is tied to the domain your app uses. +For privacy reasons and to prevent tracking across sites, a user's identity is tied to the domain where they sign in. -This means that if a user signs in on both the default domain (`icp0.io`) and a custom domain, they will be treated as two separate users by default. +### Passkeys -The same applies to subdomains: signing in on `hello.com` and `www.hello.com` will result in two separate user identities. +With Passkeys, the identity is linked to the hostname the user signs in on. It works for that domain and its subdomains. -That's why, when setting up a domain in the Console, you're prompted to choose a **primary domain**. This domain is used to consistently identify users, regardless of whether they sign in via the default or a custom domain. +For example, a passkey created on `hello.com` will also work on `www.hello.com`, but not on a different domain like `world.com`. -:::important +You can change this in the sign-up options if you want it to cover a different domain than the one read from the browser's URL. For example, you may want to use the top-level domain when signing in on a subdomain. You cannot specify a totally different domain. -- It is strongly recommended to set up such a primary domain only once per project and preferably before going live. +### Internet Identity -- In addition to configuring settings, you must also instruct your application to use the main domain you have selected by setting the `derivationOrigin` parameter to the sign-in options. +With Internet Identity, a user's identity is created separately for each domain. -::: +If a user signs in on two different domains, they will be treated as two separate users by default. The same applies to subdomains: signing in on `hello.com` and `www.hello.com` creates two different identities unless you configure a primary domain. + +The first custom domain you add in the Console is automatically set as the primary domain. You can change this setting later in Authentication, but we don't recommend it once users have already registered, since their identities are not migrated when the configuration changes. + +To let users keep the same identity across domains, you must also configure your frontend app to specify the main domain at sign-in. This is known as the "derivation origin" (or "alternative origins"). ### Recommendation @@ -72,9 +76,5 @@ If you're unsure which domain to use as the primary domain, here are two common Choosing the right derivation origin early helps avoid identity issues later, but both approaches are valid depending on your goals. -### More Information - -This mechanism is called the "derivation origin" (or "alternative origins"). See the [documentation](https://internetcomputer.org/docs/current/developer-docs/integrations/internet-identity/alternative-origins/) for more details about the specification. - [Internet Identity]: ../../terminology.md#internet-identity [NFID]: ../../terminology.md#nfid From 3c00126a981960c5ffd848a9462ddd7840985ccb Mon Sep 17 00:00:00 2001 From: David Dal Busco Date: Wed, 3 Sep 2025 16:49:45 +0200 Subject: [PATCH 03/18] docs: sign-up Signed-off-by: David Dal Busco --- docs/build/authentication/development.md | 78 ++++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/docs/build/authentication/development.md b/docs/build/authentication/development.md index bd1c3276..9735331d 100644 --- a/docs/build/authentication/development.md +++ b/docs/build/authentication/development.md @@ -10,6 +10,84 @@ The Juno SDK must be [installed](../../setup-the-sdk.mdx) and initialized in you --- +## Sign-up + +If your app provides features that require authentication, your users need to sign up to create an identity that grants them access to your application. + +### Passkeys + +With Passkeys, sign-up creates a digital key that lives on the user’s device — for example in the browser, iCloud Keychain, Google Password Manager, etc. During sign-up, the user will be asked to use their authenticator twice: once to generate the passkey, and once more to sign their new identity which is then used to interact securely with your satellite. + +```typescript +import { signUp } from "@junobuild/core"; + +await signUp({ + webauthn: { + options: { + passkey: {} + } + } +}); +``` + +#### Options + +Passkey sign-up can be customized with a handful of options. These let you control how long a session lasts, how the passkey is displayed to the user, and whether you want to track progress in your own UI. + +| Option | Type | Default | Description | +| ----------------------------- | ---------------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `maxTimeToLiveInMilliseconds` | `number` | — | Maximum lifetime of the user’s session in **milliseconds**. Once expired, the session cannot be extended. | +| `onProgress` | `(progress) => void` | — | Callback fired at each step of the sign-up flow (e.g., creating credential, validating, signing). Useful if you want to show progress indicators in your UI. | +| `passkey` | `CreatePasskeyOptions` | — | Options for how the passkey should be created. For example, you can set a `displayName` to make the passkey recognizable in iCloud Keychain or Google Password Manager. | + +Example with options: + +```typescript +import { signUp } from "@junobuild/core"; + +await signUp({ + webauthn: { + options: { + maxTimeToLiveInMilliseconds: 1000 * 60 * 60, // 1 hour + onProgress: ({ step, state }) => { + console.log("Step:", step, "State:", state); + }, + passkey: { + displayName: "My Cool App" // or user input + } + } + } +}); +``` + +:::tip + +It’s common to let the user choose a nickname during sign-up. + +This nickname can be passed as the `displayName` in the `passkey` option so the passkey is easy to recognize the next time they sign in (e.g. in iCloud Keychain or Google Password Manager). + +::: + +### Checking Availability + +Not every browser or device supports Passkeys. You can check availability before showing a sign-up button with: + +```typescript +import { isWebAuthnAvailable } from "@junobuild/core"; + +if (await isWebAuthnAvailable()) { + // Show Passkey sign-up option +} +``` + +### Internet Identity / NFID + +With Internet Identity and NFID there is no separate sign-up step. Users always go through **sign-in**, and if it’s their first time, that flow will automatically create their identity. + +In practice, your UI could simply show a button like **Continue with Internet Identity** or **Continue with NFID**. + +--- + ## Sign-in You can authorize an existing or new user with the identity provider using `signIn`. From eb19691f9371882c4deb3aa06c1d78541299733b Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 3 Sep 2025 14:51:26 +0000 Subject: [PATCH 04/18] =?UTF-8?q?=F0=9F=93=84=20Update=20LLMs.txt=20snapsh?= =?UTF-8?q?ot=20for=20PR=20review?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .llms-snapshots/llms-full.txt | 50 +++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/.llms-snapshots/llms-full.txt b/.llms-snapshots/llms-full.txt index 6bc09120..71532cca 100644 --- a/.llms-snapshots/llms-full.txt +++ b/.llms-snapshots/llms-full.txt @@ -821,6 +821,56 @@ The Juno SDK must be [installed](/docs/setup-the-sdk.md) and initialized in your --- +## Sign-up + +If your app provides features that require authentication, your users need to sign up to create an identity that grants them access to your application. + +### Passkeys + +With Passkeys, sign-up creates a digital key that lives on the user’s device — for example in the browser, iCloud Keychain, Google Password Manager, etc. During sign-up, the user will be asked to use their authenticator twice: once to generate the passkey, and once more to sign their new identity which is then used to interact securely with your satellite. + +``` +import { signUp } from "@junobuild/core";await signUp({ webauthn: { options: { passkey: {} } }}); +``` + +#### Options + +Passkey sign-up can be customized with a handful of options. These let you control how long a session lasts, how the passkey is displayed to the user, and whether you want to track progress in your own UI. + +| Option | Type | Default | Description | +| --- | --- | --- | --- | +| `maxTimeToLiveInMilliseconds` | `number` | — | Maximum lifetime of the user’s session in **milliseconds**. Once expired, the session cannot be extended. | +| `onProgress` | `(progress) => void` | — | Callback fired at each step of the sign-up flow (e.g., creating credential, validating, signing). Useful if you want to show progress indicators in your UI. | +| `passkey` | `CreatePasskeyOptions` | — | Options for how the passkey should be created. For example, you can set a `displayName` to make the passkey recognizable in iCloud Keychain or Google Password Manager. | + +Example with options: + +``` +import { signUp } from "@junobuild/core";await signUp({ webauthn: { options: { maxTimeToLiveInMilliseconds: 1000 * 60 * 60, // 1 hour onProgress: ({ step, state }) => { console.log("Step:", step, "State:", state); }, passkey: { displayName: "My Cool App" // or user input } } }}); +``` + +**Tip:** + +It’s common to let the user choose a nickname during sign-up. + +This nickname can be passed as the `displayName` in the `passkey` option so the passkey is easy to recognize the next time they sign in (e.g. in iCloud Keychain or Google Password Manager). + +### Checking Availability + +Not every browser or device supports Passkeys. You can check availability before showing a sign-up button with: + +``` +import { isWebAuthnAvailable } from "@junobuild/core";if (await isWebAuthnAvailable()) { // Show Passkey sign-up option} +``` + +### Internet Identity / NFID + +With Internet Identity and NFID there is no separate sign-up step. Users always go through **sign-in**, and if it’s their first time, that flow will automatically create their identity. + +In practice, your UI could simply show a button like **Continue with Internet Identity** or **Continue with NFID**. + +--- + ## Sign-in You can authorize an existing or new user with the identity provider using `signIn`. From 12d08442ae44bc588c5d00ca2e0b853afc6a0e45 Mon Sep 17 00:00:00 2001 From: David Dal Busco Date: Wed, 3 Sep 2025 18:05:12 +0200 Subject: [PATCH 05/18] docs: sign-in Signed-off-by: David Dal Busco --- docs/build/authentication/development.md | 165 ++++++++++++++++++----- 1 file changed, 134 insertions(+), 31 deletions(-) diff --git a/docs/build/authentication/development.md b/docs/build/authentication/development.md index 9735331d..01a882fc 100644 --- a/docs/build/authentication/development.md +++ b/docs/build/authentication/development.md @@ -16,17 +16,15 @@ If your app provides features that require authentication, your users need to si ### Passkeys -With Passkeys, sign-up creates a digital key that lives on the user’s device — for example in the browser, iCloud Keychain, Google Password Manager, etc. During sign-up, the user will be asked to use their authenticator twice: once to generate the passkey, and once more to sign their new identity which is then used to interact securely with your satellite. +With Passkeys, sign-up creates a digital key that lives on the user's device — for example in the browser, iCloud Keychain, Google Password Manager, etc. + +During sign-up, the user will be asked to use their authenticator twice: once to generate the passkey, and once more to sign their new identity which is then used to interact securely with your satellite. ```typescript import { signUp } from "@junobuild/core"; await signUp({ - webauthn: { - options: { - passkey: {} - } - } + webauthn: {} }); ``` @@ -36,7 +34,7 @@ Passkey sign-up can be customized with a handful of options. These let you contr | Option | Type | Default | Description | | ----------------------------- | ---------------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `maxTimeToLiveInMilliseconds` | `number` | — | Maximum lifetime of the user’s session in **milliseconds**. Once expired, the session cannot be extended. | +| `maxTimeToLiveInMilliseconds` | `number` | — | Maximum lifetime of the user's session in **milliseconds**. Once expired, the session cannot be extended. | | `onProgress` | `(progress) => void` | — | Callback fired at each step of the sign-up flow (e.g., creating credential, validating, signing). Useful if you want to show progress indicators in your UI. | | `passkey` | `CreatePasskeyOptions` | — | Options for how the passkey should be created. For example, you can set a `displayName` to make the passkey recognizable in iCloud Keychain or Google Password Manager. | @@ -62,13 +60,13 @@ await signUp({ :::tip -It’s common to let the user choose a nickname during sign-up. +It's common to let the user choose a nickname during sign-up. This nickname can be passed as the `displayName` in the `passkey` option so the passkey is easy to recognize the next time they sign in (e.g. in iCloud Keychain or Google Password Manager). ::: -### Checking Availability +#### Checking Availability Not every browser or device supports Passkeys. You can check availability before showing a sign-up button with: @@ -82,44 +80,110 @@ if (await isWebAuthnAvailable()) { ### Internet Identity / NFID -With Internet Identity and NFID there is no separate sign-up step. Users always go through **sign-in**, and if it’s their first time, that flow will automatically create their identity. +With Internet Identity and NFID there is no separate sign-up step. Users always go through sign-in, and if it's their first time, that flow will automatically create their identity. -In practice, your UI could simply show a button like **Continue with Internet Identity** or **Continue with NFID**. +In practice, your UI could simply show a button like "Continue with Internet Identity" or "Continue with NFID". --- ## Sign-in -You can authorize an existing or new user with the identity provider using `signIn`. +If your app provides features that require authentication, your users need to sign in to access their identity and continue using your application securely. + +### Passkeys + +With Passkeys, sign-in uses the digital key previously created on the user's device — for example in the browser, iCloud Keychain, Google Password Manager, etc. + +During sign-in, the user will be asked to use their authenticator to prove possession of the passkey and re-establish a valid session with your satellite. ```typescript import { signIn } from "@junobuild/core"; -await signIn(); +await signIn({ + webauthn: {} +}); ``` -The sign-in feature supports following customization options: +#### Options + +Passkey sign-in can also be customized with options similar to sign-up. These let you control how long a session lasts and whether you want to track progress in your own UI. + +| Option | Type | Default | Description | +| ----------------------------- | -------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------ | +| `maxTimeToLiveInMilliseconds` | `number` | — | Maximum lifetime of the user's session in **milliseconds**. Once expired, the session cannot be extended. | +| `onProgress` | `(progress) => void` | — | Callback fired at each step of the sign-up flow (e.g., fetching credential, validating, signing). Useful to customize your UI. | + +Example with options: + +```typescript +import { signIn } from "@junobuild/core"; + +await signIn({ + webauthn: { + options: { + maxTimeToLiveInMilliseconds: 1000 * 60 * 60, // 1 hour + onProgress: ({ step, state }) => { + console.log("Step:", step, "State:", state); + } + } + } +}); +``` + +### Internet Identity + +When a user signs in with Internet Identity, they log in with the provider to confirm their identity. If successful, a session is created and the user can interact with your satellite. There's no separate sign-up step — the account in your satellite is created automatically the first time they sign in, so the user can access your services right away. + +```typescript +import { signIn } from "@junobuild/core"; + +await signIn({ + ii: {} +}); +``` + +#### Options + +Internet Identity sign-in can be customized with options that let you control session lifetime, provider configuration, or track progress during the flow. + +| Option | Default Value | Default | Description | +| ----------------------- | ------------------------------------------ | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `maxTimeToLiveInMillis` | `BigInt(4 * 60 * 60 * 1000 * 1000 * 1000)` | — | Specifies the duration for the session (defaults to **4 hours**). It's **important** to note that this duration remains constant, whether the users are active or inactive. | +| `windowed` | `true` | — | By default, the authentication flow is presented in a popup window on desktop that is automatically centered on the browser. This behavior can be turned off by setting the option to `false`, causing the authentication flow to happen in a separate tab instead. | +| `derivationOrigin` | — | — | The main domain to be used to ensure your users are identified with the same public ID, regardless of which of your satellite's URLs they use to access your application. | +| `allowPin` | `false` | — | We consider the specific PIN authentication method of [Internet Identity](https://internetcomputer.org/docs/current/references/ii-spec#client-authentication-protocol) as "insecure" because users can easily lose their login information if they do not register a passphrase, particularly as Safari clears the browser cache every two weeks in cases of inactivity. This is why we **disable** it by default. | +| `onProgress` | `(progress) => void` | — | Callback for provider sign-in and user creation/loading. | +| `domain` | `internetcomputer.org` or `ic0.app` | `internetcomputer.org` | The domain on which to open Internet Identity. | -| Option | Default Value | Description | -| ------------------ | ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| `maxTimeToLive` | `BigInt(4 * 60 * 60 * 1000 * 1000 * 1000)` | Specifies the duration for the session (defaults to **4 hours**). It's **important** to note that this duration remains constant, whether the users are active or inactive. | -| `windowed` | `true` | By default, the authentication flow is presented in a popup window on desktop that is automatically centered on the browser. This behavior can be turned off by setting the option to `false`, causing the authentication flow to happen in a separate tab instead. | -| `derivationOrigin` | — | The main domain to be used to ensure your users are identified with the same public ID, regardless of which of your satellite’s URLs they use to access your application. | -| `allowPin` | `false` | We consider the specific PIN authentication method of [Internet Identity](https://internetcomputer.org/docs/current/references/ii-spec#client-authentication-protocol) as "insecure" because users can easily lose their login information if they do not register a passphrase, particularly as Safari clears the browser cache every two weeks in cases of inactivity. This is why we **disable** it by default. | +Example with options: -You can configure the default sign-in flow that uses Internet Identity. You can also set NFID as a provider. Check out the [advanced Sign-in guidelines](./customization.md#sign-in-providers) for more details. +```typescript +await signIn({ + ii: { + options: { + maxTimeToLiveInMilliseconds: 1000 * 60 * 30, // 30 minutes + onProgress: ({ step, state }) => { + console.log("Step:", step, "State:", state); + }, + derivationOrigin: "https://myapp.com" + } + } +}); +``` -### Handling Errors +#### Handling Errors If the sign-in flow encounters an error, an exception will be thrown. -When a user cancels sign-in (e.g., by closing the modal), the library throws a `SignInUserInterruptError`. This error indicates that the user intentionally interrupted the sign-in process, and it's generally best practice to ignore it rather than showing an error message. +When a user cancels sign-in with Internet Identity (e.g., by closing the modal), the library throws a `SignInUserInterruptError`. This error indicates that the user intentionally interrupted the sign-in process, and it's generally best practice to ignore it rather than showing an error message. ```typescript import { signIn } from "@junobuild/core"; try { - await signIn(); + await signIn({ + ii: {} + }); } catch (error: unknown) { if (error instanceof SignInUserInterruptError) { // User canceled sign-in, no need to show an error @@ -131,11 +195,56 @@ try { } ``` +### NFID + +NFID flows follow a similar pattern to authentication with Internet Identity. The user signs in with the provider, and if successful, a session is created so they can interact with your satellite. If it's their first time, the account in your satellite is created automatically. + +```typescript +import { signIn } from "@junobuild/core"; + +await signIn({ + nfid: {} +}); +``` + +#### Options + +NFID sign-in can be customized with following options: + +| Option | Default Value | Default | Description | +| ----------------------- | ------------------------------------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `maxTimeToLiveInMillis` | `BigInt(4 * 60 * 60 * 1000 * 1000 * 1000)` | — | Specifies the duration for the session (defaults to **4 hours**). It's **important** to note that this duration remains constant, whether the users are active or inactive. | +| `windowed` | `true` | — | By default, the authentication flow is presented in a popup window on desktop that is automatically centered on the browser. This behavior can be turned off by setting the option to `false`, causing the authentication flow to happen in a separate tab instead. | +| `derivationOrigin` | — | — | The main domain to be used to ensure your users are identified with the same public ID, regardless of which of your satellite's URLs they use to access your application. | +| `allowPin` | `false` | — | We consider the specific PIN authentication method of [Internet Identity](https://internetcomputer.org/docs/current/references/ii-spec#client-authentication-protocol) as "insecure" because users can easily lose their login information if they do not register a passphrase, particularly as Safari clears the browser cache every two weeks in cases of inactivity. This is why we **disable** it by default. | +| `onProgress` | `(progress) => void` | — | Callback for provider sign-in and user creation/loading. | +| `appName` | `string` | — | The name of your application, shown to the user during sign-in. | +| `logoUrl` | `string` | — | URL of your application's logo, shown to the user during sign-in. | + +Example with options: + +```typescript +import { signIn } from "@junobuild/core"; + +await signIn({ + nfid: { + options: { + maxTimeToLiveInMilliseconds: 1000 * 60 * 30, // 30 minutes + onProgress: ({ step, state }) => { + console.log("Step:", step, "State:", state); + }, + appName: "My Cool App", + logoUrl: "https://myapp.com/logo.png" + } + } +}); +``` + --- ## Sign-out -You can end a user's session by logging them out. +You can end a user's session, no matter which provider they used to sign in, by logging them out. ```typescript import { signOut } from "@junobuild/core"; @@ -143,12 +252,6 @@ import { signOut } from "@junobuild/core"; await signOut(); ``` -:::note - -This will clear the sign-in information stored in IndexedDB. - -::: - --- ## Listening to Auth Changes From b488da94d48315d85acbff6aea14387fb6c1c404 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 3 Sep 2025 16:06:56 +0000 Subject: [PATCH 06/18] =?UTF-8?q?=F0=9F=93=84=20Update=20LLMs.txt=20snapsh?= =?UTF-8?q?ot=20for=20PR=20review?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .llms-snapshots/llms-full.txt | 113 ++++++++++++++++++++++++++-------- 1 file changed, 88 insertions(+), 25 deletions(-) diff --git a/.llms-snapshots/llms-full.txt b/.llms-snapshots/llms-full.txt index 71532cca..2bac747e 100644 --- a/.llms-snapshots/llms-full.txt +++ b/.llms-snapshots/llms-full.txt @@ -827,10 +827,12 @@ If your app provides features that require authentication, your users need to si ### Passkeys -With Passkeys, sign-up creates a digital key that lives on the user’s device — for example in the browser, iCloud Keychain, Google Password Manager, etc. During sign-up, the user will be asked to use their authenticator twice: once to generate the passkey, and once more to sign their new identity which is then used to interact securely with your satellite. +With Passkeys, sign-up creates a digital key that lives on the user's device — for example in the browser, iCloud Keychain, Google Password Manager, etc. + +During sign-up, the user will be asked to use their authenticator twice: once to generate the passkey, and once more to sign their new identity which is then used to interact securely with your satellite. ``` -import { signUp } from "@junobuild/core";await signUp({ webauthn: { options: { passkey: {} } }}); +import { signUp } from "@junobuild/core";await signUp({ webauthn: {}}); ``` #### Options @@ -839,7 +841,7 @@ Passkey sign-up can be customized with a handful of options. These let you contr | Option | Type | Default | Description | | --- | --- | --- | --- | -| `maxTimeToLiveInMilliseconds` | `number` | — | Maximum lifetime of the user’s session in **milliseconds**. Once expired, the session cannot be extended. | +| `maxTimeToLiveInMilliseconds` | `number` | — | Maximum lifetime of the user's session in **milliseconds**. Once expired, the session cannot be extended. | | `onProgress` | `(progress) => void` | — | Callback fired at each step of the sign-up flow (e.g., creating credential, validating, signing). Useful if you want to show progress indicators in your UI. | | `passkey` | `CreatePasskeyOptions` | — | Options for how the passkey should be created. For example, you can set a `displayName` to make the passkey recognizable in iCloud Keychain or Google Password Manager. | @@ -851,11 +853,11 @@ import { signUp } from "@junobuild/core";await signUp({ webauthn: { options: **Tip:** -It’s common to let the user choose a nickname during sign-up. +It's common to let the user choose a nickname during sign-up. This nickname can be passed as the `displayName` in the `passkey` option so the passkey is easy to recognize the next time they sign in (e.g. in iCloud Keychain or Google Password Manager). -### Checking Availability +#### Checking Availability Not every browser or device supports Passkeys. You can check availability before showing a sign-up button with: @@ -865,55 +867,116 @@ import { isWebAuthnAvailable } from "@junobuild/core";if (await isWebAuthnAvaila ### Internet Identity / NFID -With Internet Identity and NFID there is no separate sign-up step. Users always go through **sign-in**, and if it’s their first time, that flow will automatically create their identity. +With Internet Identity and NFID there is no separate sign-up step. Users always go through sign-in, and if it's their first time, that flow will automatically create their identity. -In practice, your UI could simply show a button like **Continue with Internet Identity** or **Continue with NFID**. +In practice, your UI could simply show a button like "Continue with Internet Identity" or "Continue with NFID". --- ## Sign-in -You can authorize an existing or new user with the identity provider using `signIn`. +If your app provides features that require authentication, your users need to sign in to access their identity and continue using your application securely. + +### Passkeys + +With Passkeys, sign-in uses the digital key previously created on the user's device — for example in the browser, iCloud Keychain, Google Password Manager, etc. + +During sign-in, the user will be asked to use their authenticator to prove possession of the passkey and re-establish a valid session with your satellite. ``` -import { signIn } from "@junobuild/core";await signIn(); +import { signIn } from "@junobuild/core";await signIn({ webauthn: {}}); ``` -The sign-in feature supports following customization options: +#### Options -| Option | Default Value | Description | -| --- | --- | --- | -| `maxTimeToLive` | `BigInt(4 * 60 * 60 * 1000 * 1000 * 1000)` | Specifies the duration for the session (defaults to **4 hours**). It's **important** to note that this duration remains constant, whether the users are active or inactive. | -| `windowed` | `true` | By default, the authentication flow is presented in a popup window on desktop that is automatically centered on the browser. This behavior can be turned off by setting the option to `false`, causing the authentication flow to happen in a separate tab instead. | -| `derivationOrigin` | — | The main domain to be used to ensure your users are identified with the same public ID, regardless of which of your satellite’s URLs they use to access your application. | -| `allowPin` | `false` | We consider the specific PIN authentication method of [Internet Identity](https://internetcomputer.org/docs/current/references/ii-spec#client-authentication-protocol) as "insecure" because users can easily lose their login information if they do not register a passphrase, particularly as Safari clears the browser cache every two weeks in cases of inactivity. This is why we **disable** it by default. | +Passkey sign-in can also be customized with options similar to sign-up. These let you control how long a session lasts and whether you want to track progress in your own UI. -You can configure the default sign-in flow that uses Internet Identity. You can also set NFID as a provider. Check out the [advanced Sign-in guidelines](/docs/build/authentication/customization.md#sign-in-providers) for more details. +| Option | Type | Default | Description | +| --- | --- | --- | --- | +| `maxTimeToLiveInMilliseconds` | `number` | — | Maximum lifetime of the user's session in **milliseconds**. Once expired, the session cannot be extended. | +| `onProgress` | `(progress) => void` | — | Callback fired at each step of the sign-up flow (e.g., fetching credential, validating, signing). Useful to customize your UI. | + +Example with options: -### Handling Errors +``` +import { signIn } from "@junobuild/core";await signIn({ webauthn: { options: { maxTimeToLiveInMilliseconds: 1000 * 60 * 60, // 1 hour onProgress: ({ step, state }) => { console.log("Step:", step, "State:", state); } } }}); +``` + +### Internet Identity + +When a user signs in with Internet Identity, they log in with the provider to confirm their identity. If successful, a session is created and the user can interact with your satellite. There's no separate sign-up step — the account in your satellite is created automatically the first time they sign in, so the user can access your services right away. + +``` +import { signIn } from "@junobuild/core";await signIn({ ii: {}}); +``` + +#### Options + +Internet Identity sign-in can be customized with options that let you control session lifetime, provider configuration, or track progress during the flow. + +| Option | Default Value | Default | Description | +| --- | --- | --- | --- | +| `maxTimeToLiveInMillis` | `BigInt(4 * 60 * 60 * 1000 * 1000 * 1000)` | — | Specifies the duration for the session (defaults to **4 hours**). It's **important** to note that this duration remains constant, whether the users are active or inactive. | +| `windowed` | `true` | — | By default, the authentication flow is presented in a popup window on desktop that is automatically centered on the browser. This behavior can be turned off by setting the option to `false`, causing the authentication flow to happen in a separate tab instead. | +| `derivationOrigin` | — | — | The main domain to be used to ensure your users are identified with the same public ID, regardless of which of your satellite's URLs they use to access your application. | +| `allowPin` | `false` | — | We consider the specific PIN authentication method of [Internet Identity](https://internetcomputer.org/docs/current/references/ii-spec#client-authentication-protocol) as "insecure" because users can easily lose their login information if they do not register a passphrase, particularly as Safari clears the browser cache every two weeks in cases of inactivity. This is why we **disable** it by default. | +| `onProgress` | `(progress) => void` | — | Callback for provider sign-in and user creation/loading. | +| `domain` | `internetcomputer.org` or `ic0.app` | `internetcomputer.org` | The domain on which to open Internet Identity. | + +Example with options: + +``` +await signIn({ ii: { options: { maxTimeToLiveInMilliseconds: 1000 * 60 * 30, // 30 minutes onProgress: ({ step, state }) => { console.log("Step:", step, "State:", state); }, derivationOrigin: "https://myapp.com" } }}); +``` + +#### Handling Errors If the sign-in flow encounters an error, an exception will be thrown. -When a user cancels sign-in (e.g., by closing the modal), the library throws a `SignInUserInterruptError`. This error indicates that the user intentionally interrupted the sign-in process, and it's generally best practice to ignore it rather than showing an error message. +When a user cancels sign-in with Internet Identity (e.g., by closing the modal), the library throws a `SignInUserInterruptError`. This error indicates that the user intentionally interrupted the sign-in process, and it's generally best practice to ignore it rather than showing an error message. + +``` +import { signIn } from "@junobuild/core";try { await signIn({ ii: {} });} catch (error: unknown) { if (error instanceof SignInUserInterruptError) { // User canceled sign-in, no need to show an error return; } // Handle other errors console.error("Sign-in failed:", error);} +``` + +### NFID + +NFID flows follow a similar pattern to authentication with Internet Identity. The user signs in with the provider, and if successful, a session is created so they can interact with your satellite. If it's their first time, the account in your satellite is created automatically. + +``` +import { signIn } from "@junobuild/core";await signIn({ nfid: {}}); +``` + +#### Options + +NFID sign-in can be customized with following options: + +| Option | Default Value | Default | Description | +| --- | --- | --- | --- | +| `maxTimeToLiveInMillis` | `BigInt(4 * 60 * 60 * 1000 * 1000 * 1000)` | — | Specifies the duration for the session (defaults to **4 hours**). It's **important** to note that this duration remains constant, whether the users are active or inactive. | +| `windowed` | `true` | — | By default, the authentication flow is presented in a popup window on desktop that is automatically centered on the browser. This behavior can be turned off by setting the option to `false`, causing the authentication flow to happen in a separate tab instead. | +| `derivationOrigin` | — | — | The main domain to be used to ensure your users are identified with the same public ID, regardless of which of your satellite's URLs they use to access your application. | +| `allowPin` | `false` | — | We consider the specific PIN authentication method of [Internet Identity](https://internetcomputer.org/docs/current/references/ii-spec#client-authentication-protocol) as "insecure" because users can easily lose their login information if they do not register a passphrase, particularly as Safari clears the browser cache every two weeks in cases of inactivity. This is why we **disable** it by default. | +| `onProgress` | `(progress) => void` | — | Callback for provider sign-in and user creation/loading. | +| `appName` | `string` | — | The name of your application, shown to the user during sign-in. | +| `logoUrl` | `string` | — | URL of your application's logo, shown to the user during sign-in. | + +Example with options: ``` -import { signIn } from "@junobuild/core";try { await signIn();} catch (error: unknown) { if (error instanceof SignInUserInterruptError) { // User canceled sign-in, no need to show an error return; } // Handle other errors console.error("Sign-in failed:", error);} +import { signIn } from "@junobuild/core";await signIn({ nfid: { options: { maxTimeToLiveInMilliseconds: 1000 * 60 * 30, // 30 minutes onProgress: ({ step, state }) => { console.log("Step:", step, "State:", state); }, appName: "My Cool App", logoUrl: "https://myapp.com/logo.png" } }}); ``` --- ## Sign-out -You can end a user's session by logging them out. +You can end a user's session, no matter which provider they used to sign in, by logging them out. ``` import { signOut } from "@junobuild/core";await signOut(); ``` -**Note:** - -This will clear the sign-in information stored in IndexedDB. - --- ## Listening to Auth Changes From 0aac55a273c0a95edec50deb8d02aeafb278b70c Mon Sep 17 00:00:00 2001 From: David Dal Busco Date: Wed, 3 Sep 2025 18:07:37 +0200 Subject: [PATCH 07/18] docs: customization Signed-off-by: David Dal Busco --- docs/build/authentication/customization.md | 66 ++-------------------- docs/build/authentication/development.md | 2 +- 2 files changed, 6 insertions(+), 62 deletions(-) diff --git a/docs/build/authentication/customization.md b/docs/build/authentication/customization.md index 8966ecac..52b72067 100644 --- a/docs/build/authentication/customization.md +++ b/docs/build/authentication/customization.md @@ -4,69 +4,13 @@ Here are some customization options to tailor your sign-in flow and handle sessi --- -## Sign-In Providers +## Sign Context -Juno supports Internet Identity and NFID, which also offers additional authentication methods like Google and email. +Some options apply to both sign-up and sign-in flows. -:::note - -You can implement the `signIn` function in your application as many times as you wish, with various configurations. It is also perfectly acceptable to use both Internet Identity and NFID within the same project. - -::: - ---- - -### Internet Identity - -Internet Identity is available at two different URLs: `internetcomputer.org` and `ic0.app`. - -By default, the SDK uses `internetcomputer.org`. - -```typescript -import { signIn, InternetIdentityProvider } from "@junobuild/core"; - -// Default domain is 'internetcomputer.org' -await signIn({ - provider: new InternetIdentityProvider({}) -}); -``` - -You can switch to `ic0.app` by setting the domain option accordingly. - -```typescript -import { signIn, InternetIdentityProvider } from "@junobuild/core"; - -await signIn({ - provider: new InternetIdentityProvider({ - domain: "ic0.app" - }) -}); -``` - -We use the former by default because we believe it offers a better user experience and branding. - -:::note - -It is worth mentioning that your users will be able to sign in to your app with Internet Identity, regardless of which of those two domains they originally created their identity on. - -::: - ---- - -### NFID - -To set up NFID, you need to configure the corresponding provider and provide your application name and a link to your logo. - -```typescript -import { signIn, NFIDProvider } from "@junobuild/core"; - -await signIn({ - provider: new NFIDProvider({ - appName: "Your app name", - logoUrl: "https://somewhere.com/your_logo.png" - }) -}); -``` +| Option | Type | Default | Description | +| ------------- | --------- | ------- | ----------------------------------------------------------------------------------------------------------------- | +| `windowGuard` | `boolean` | `true` | Prevents the user from closing the current window/tab while the flow is in progress. Disabling it is discouraged. | --- diff --git a/docs/build/authentication/development.md b/docs/build/authentication/development.md index 01a882fc..a90d33f4 100644 --- a/docs/build/authentication/development.md +++ b/docs/build/authentication/development.md @@ -146,7 +146,7 @@ await signIn({ Internet Identity sign-in can be customized with options that let you control session lifetime, provider configuration, or track progress during the flow. -| Option | Default Value | Default | Description | +| Option | Type | Default | Description | | ----------------------- | ------------------------------------------ | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `maxTimeToLiveInMillis` | `BigInt(4 * 60 * 60 * 1000 * 1000 * 1000)` | — | Specifies the duration for the session (defaults to **4 hours**). It's **important** to note that this duration remains constant, whether the users are active or inactive. | | `windowed` | `true` | — | By default, the authentication flow is presented in a popup window on desktop that is automatically centered on the browser. This behavior can be turned off by setting the option to `false`, causing the authentication flow to happen in a separate tab instead. | From ab87a2238fb7bbf54ef49669529034fa30dbd935 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 3 Sep 2025 16:09:23 +0000 Subject: [PATCH 08/18] =?UTF-8?q?=F0=9F=93=84=20Update=20LLMs.txt=20snapsh?= =?UTF-8?q?ot=20for=20PR=20review?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .llms-snapshots/llms-full.txt | 46 +++++------------------------------ 1 file changed, 6 insertions(+), 40 deletions(-) diff --git a/.llms-snapshots/llms-full.txt b/.llms-snapshots/llms-full.txt index 2bac747e..4b9b08e5 100644 --- a/.llms-snapshots/llms-full.txt +++ b/.llms-snapshots/llms-full.txt @@ -733,47 +733,13 @@ Here are some customization options to tailor your sign-in flow and handle sessi --- -## Sign-In Providers +## Sign Context -Juno supports Internet Identity and NFID, which also offers additional authentication methods like Google and email. +Some options apply to both sign-up and sign-in flows. -**Note:** - -You can implement the `signIn` function in your application as many times as you wish, with various configurations. It is also perfectly acceptable to use both Internet Identity and NFID within the same project. - ---- - -### Internet Identity - -Internet Identity is available at two different URLs: `internetcomputer.org` and `ic0.app`. - -By default, the SDK uses `internetcomputer.org`. - -``` -import { signIn, InternetIdentityProvider } from "@junobuild/core";// Default domain is 'internetcomputer.org'await signIn({ provider: new InternetIdentityProvider({})}); -``` - -You can switch to `ic0.app` by setting the domain option accordingly. - -``` -import { signIn, InternetIdentityProvider } from "@junobuild/core";await signIn({ provider: new InternetIdentityProvider({ domain: "ic0.app" })}); -``` - -We use the former by default because we believe it offers a better user experience and branding. - -**Note:** - -It is worth mentioning that your users will be able to sign in to your app with Internet Identity, regardless of which of those two domains they originally created their identity on. - ---- - -### NFID - -To set up NFID, you need to configure the corresponding provider and provide your application name and a link to your logo. - -``` -import { signIn, NFIDProvider } from "@junobuild/core";await signIn({ provider: new NFIDProvider({ appName: "Your app name", logoUrl: "https://somewhere.com/your_logo.png" })}); -``` +| Option | Type | Default | Description | +| --- | --- | --- | --- | +| `windowGuard` | `boolean` | `true` | Prevents the user from closing the current window/tab while the flow is in progress. Disabling it is discouraged. | --- @@ -914,7 +880,7 @@ import { signIn } from "@junobuild/core";await signIn({ ii: {}}); Internet Identity sign-in can be customized with options that let you control session lifetime, provider configuration, or track progress during the flow. -| Option | Default Value | Default | Description | +| Option | Type | Default | Description | | --- | --- | --- | --- | | `maxTimeToLiveInMillis` | `BigInt(4 * 60 * 60 * 1000 * 1000 * 1000)` | — | Specifies the duration for the session (defaults to **4 hours**). It's **important** to note that this duration remains constant, whether the users are active or inactive. | | `windowed` | `true` | — | By default, the authentication flow is presented in a popup window on desktop that is automatically centered on the browser. This behavior can be turned off by setting the option to `false`, causing the authentication flow to happen in a separate tab instead. | From 29acb161b07cad71829488d9938b371589ef35fb Mon Sep 17 00:00:00 2001 From: David Dal Busco Date: Wed, 3 Sep 2025 18:37:55 +0200 Subject: [PATCH 09/18] docs: review Signed-off-by: David Dal Busco --- docs/build/authentication/development.md | 62 +++++++++++++----------- 1 file changed, 34 insertions(+), 28 deletions(-) diff --git a/docs/build/authentication/development.md b/docs/build/authentication/development.md index a90d33f4..df005d81 100644 --- a/docs/build/authentication/development.md +++ b/docs/build/authentication/development.md @@ -32,11 +32,19 @@ await signUp({ Passkey sign-up can be customized with a handful of options. These let you control how long a session lasts, how the passkey is displayed to the user, and whether you want to track progress in your own UI. -| Option | Type | Default | Description | -| ----------------------------- | ---------------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `maxTimeToLiveInMilliseconds` | `number` | — | Maximum lifetime of the user's session in **milliseconds**. Once expired, the session cannot be extended. | -| `onProgress` | `(progress) => void` | — | Callback fired at each step of the sign-up flow (e.g., creating credential, validating, signing). Useful if you want to show progress indicators in your UI. | -| `passkey` | `CreatePasskeyOptions` | — | Options for how the passkey should be created. For example, you can set a `displayName` to make the passkey recognizable in iCloud Keychain or Google Password Manager. | +| Option | Type | Default | Description | +| ----------------------------- | ---------------------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `maxTimeToLiveInMilliseconds` | `number` | **4 hours** | Maximum lifetime of the user's session in **milliseconds**. Once expired, the session cannot be extended. | +| `onProgress` | `(progress) => void` | | Callback fired at each step of the sign-up flow (e.g., creating credential, validating, signing). Useful if you want to show progress indicators in your UI. | +| `passkey` | `CreatePasskeyOptions` | | Options for how the passkey should be created. | + +The `passkey` option accepts the following fields: + +| Option | Type | Default | Description | +| ------------------ | -------- | ---------------------- | ---------------------------------------------------------------------------------------------------------------- | +| `appId.id` | `string` | Current URL `hostname` | Domain your passkeys are tied to (e.g., `example.com` or `login.example.com`). Subdomains are supported. | +| `user.displayName` | `string` | `document.title` | Friendly name for the account (e.g., `"Maria Sanchez"`). Helps the user recognize which passkey belongs to them. | +| `user.name` | `string` | `displayName` | User-recognizable account identifier (e.g., email, username, or phone number). Distinguishes between accounts. | Example with options: @@ -108,10 +116,10 @@ await signIn({ Passkey sign-in can also be customized with options similar to sign-up. These let you control how long a session lasts and whether you want to track progress in your own UI. -| Option | Type | Default | Description | -| ----------------------------- | -------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------ | -| `maxTimeToLiveInMilliseconds` | `number` | — | Maximum lifetime of the user's session in **milliseconds**. Once expired, the session cannot be extended. | -| `onProgress` | `(progress) => void` | — | Callback fired at each step of the sign-up flow (e.g., fetching credential, validating, signing). Useful to customize your UI. | +| Option | Type | Default | Description | +| ----------------------------- | -------------------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------ | +| `maxTimeToLiveInMilliseconds` | `number` | **4 hours** | Maximum lifetime of the user's session in **milliseconds**. Once expired, the session cannot be extended. | +| `onProgress` | `(progress) => void` | | Callback fired at each step of the sign-up flow (e.g., fetching credential, validating, signing). Useful to customize your UI. | Example with options: @@ -146,14 +154,14 @@ await signIn({ Internet Identity sign-in can be customized with options that let you control session lifetime, provider configuration, or track progress during the flow. -| Option | Type | Default | Description | -| ----------------------- | ------------------------------------------ | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| `maxTimeToLiveInMillis` | `BigInt(4 * 60 * 60 * 1000 * 1000 * 1000)` | — | Specifies the duration for the session (defaults to **4 hours**). It's **important** to note that this duration remains constant, whether the users are active or inactive. | -| `windowed` | `true` | — | By default, the authentication flow is presented in a popup window on desktop that is automatically centered on the browser. This behavior can be turned off by setting the option to `false`, causing the authentication flow to happen in a separate tab instead. | -| `derivationOrigin` | — | — | The main domain to be used to ensure your users are identified with the same public ID, regardless of which of your satellite's URLs they use to access your application. | -| `allowPin` | `false` | — | We consider the specific PIN authentication method of [Internet Identity](https://internetcomputer.org/docs/current/references/ii-spec#client-authentication-protocol) as "insecure" because users can easily lose their login information if they do not register a passphrase, particularly as Safari clears the browser cache every two weeks in cases of inactivity. This is why we **disable** it by default. | -| `onProgress` | `(progress) => void` | — | Callback for provider sign-in and user creation/loading. | -| `domain` | `internetcomputer.org` or `ic0.app` | `internetcomputer.org` | The domain on which to open Internet Identity. | +| Option | Type | Default | Description | +| ---------------------------- | ------------------------------------------ | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `maxTimeToLiveInNanoseconds` | `BigInt(4 * 60 * 60 * 1000 * 1000 * 1000)` | **4 hours** | Maximum lifetime of the user's session in **nanoseconds**. Once expired, the session cannot be extended. | +| `windowed` | `boolean` | `true` | By default, the authentication flow is presented in a popup window on desktop that is automatically centered on the browser. This behavior can be turned off by setting the option to `false`, causing the authentication flow to happen in a separate tab instead. | +| `derivationOrigin` | `string` or `URL` | | The main domain to be used to ensure your users are identified with the same public ID, regardless of which of your satellite's URLs they use to access your application. | +| `allowPin` | `boolean` | `false` | We consider the specific PIN authentication method of [Internet Identity](https://internetcomputer.org/docs/current/references/ii-spec#client-authentication-protocol) as "insecure" because users can easily lose their login information if they do not register a passphrase, particularly as Safari clears the browser cache every two weeks in cases of inactivity. This is why we **disable** it by default. | +| `onProgress` | `(progress) => void` | | Callback for provider sign-in and user creation/loading. | +| `domain` | `internetcomputer.org` or `ic0.app` | `internetcomputer.org` | The domain on which to open Internet Identity. | Example with options: @@ -161,7 +169,7 @@ Example with options: await signIn({ ii: { options: { - maxTimeToLiveInMilliseconds: 1000 * 60 * 30, // 30 minutes + maxTimeToLiveInNanoseconds: BigInt(24 * 60 * 60 * 1000 * 1000 * 1000), // 1 day onProgress: ({ step, state }) => { console.log("Step:", step, "State:", state); }, @@ -211,15 +219,13 @@ await signIn({ NFID sign-in can be customized with following options: -| Option | Default Value | Default | Description | -| ----------------------- | ------------------------------------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| `maxTimeToLiveInMillis` | `BigInt(4 * 60 * 60 * 1000 * 1000 * 1000)` | — | Specifies the duration for the session (defaults to **4 hours**). It's **important** to note that this duration remains constant, whether the users are active or inactive. | -| `windowed` | `true` | — | By default, the authentication flow is presented in a popup window on desktop that is automatically centered on the browser. This behavior can be turned off by setting the option to `false`, causing the authentication flow to happen in a separate tab instead. | -| `derivationOrigin` | — | — | The main domain to be used to ensure your users are identified with the same public ID, regardless of which of your satellite's URLs they use to access your application. | -| `allowPin` | `false` | — | We consider the specific PIN authentication method of [Internet Identity](https://internetcomputer.org/docs/current/references/ii-spec#client-authentication-protocol) as "insecure" because users can easily lose their login information if they do not register a passphrase, particularly as Safari clears the browser cache every two weeks in cases of inactivity. This is why we **disable** it by default. | -| `onProgress` | `(progress) => void` | — | Callback for provider sign-in and user creation/loading. | -| `appName` | `string` | — | The name of your application, shown to the user during sign-in. | -| `logoUrl` | `string` | — | URL of your application's logo, shown to the user during sign-in. | +| Option | Default Value | Default | Description | +| ---------------------------- | ------------------------------------------ | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `maxTimeToLiveInNanoseconds` | `BigInt(4 * 60 * 60 * 1000 * 1000 * 1000)` | **4 hours** | Maximum lifetime of the user's session in **nanoseconds**. Once expired, the session cannot be extended. | +| `windowed` | `boolean` | `true` | By default, the authentication flow is presented in a popup window on desktop that is automatically centered on the browser. This behavior can be turned off by setting the option to `false`, causing the authentication flow to happen in a separate tab instead. | +| `onProgress` | `(progress) => void` | | Callback for provider sign-in and user creation/loading. | +| `appName` | `string` | | The name of your application, shown to the user during sign-in. | +| `logoUrl` | `string` | | URL of your application's logo, shown to the user during sign-in. | Example with options: @@ -229,7 +235,7 @@ import { signIn } from "@junobuild/core"; await signIn({ nfid: { options: { - maxTimeToLiveInMilliseconds: 1000 * 60 * 30, // 30 minutes + maxTimeToLiveInNanoseconds: BigInt(24 * 60 * 60 * 1000 * 1000 * 1000), // 1 day onProgress: ({ step, state }) => { console.log("Step:", step, "State:", state); }, From 350b46418b55f66778d2af8fb4a28ff5f1118ad9 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 3 Sep 2025 16:39:43 +0000 Subject: [PATCH 10/18] =?UTF-8?q?=F0=9F=93=84=20Update=20LLMs.txt=20snapsh?= =?UTF-8?q?ot=20for=20PR=20review?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .llms-snapshots/llms-full.txt | 44 ++++++++++++++++++++--------------- 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/.llms-snapshots/llms-full.txt b/.llms-snapshots/llms-full.txt index 4b9b08e5..1c29bebc 100644 --- a/.llms-snapshots/llms-full.txt +++ b/.llms-snapshots/llms-full.txt @@ -807,9 +807,17 @@ Passkey sign-up can be customized with a handful of options. These let you contr | Option | Type | Default | Description | | --- | --- | --- | --- | -| `maxTimeToLiveInMilliseconds` | `number` | — | Maximum lifetime of the user's session in **milliseconds**. Once expired, the session cannot be extended. | -| `onProgress` | `(progress) => void` | — | Callback fired at each step of the sign-up flow (e.g., creating credential, validating, signing). Useful if you want to show progress indicators in your UI. | -| `passkey` | `CreatePasskeyOptions` | — | Options for how the passkey should be created. For example, you can set a `displayName` to make the passkey recognizable in iCloud Keychain or Google Password Manager. | +| `maxTimeToLiveInMilliseconds` | `number` | **4 hours** | Maximum lifetime of the user's session in **milliseconds**. Once expired, the session cannot be extended. | +| `onProgress` | `(progress) => void` | | Callback fired at each step of the sign-up flow (e.g., creating credential, validating, signing). Useful if you want to show progress indicators in your UI. | +| `passkey` | `CreatePasskeyOptions` | | Options for how the passkey should be created. | + +The `passkey` option accepts the following fields: + +| Option | Type | Default | Description | +| --- | --- | --- | --- | +| `appId.id` | `string` | Current URL `hostname` | Domain your passkeys are tied to (e.g., `example.com` or `login.example.com`). Subdomains are supported. | +| `user.displayName` | `string` | `document.title` | Friendly name for the account (e.g., `"Maria Sanchez"`). Helps the user recognize which passkey belongs to them. | +| `user.name` | `string` | `displayName` | User-recognizable account identifier (e.g., email, username, or phone number). Distinguishes between accounts. | Example with options: @@ -859,8 +867,8 @@ Passkey sign-in can also be customized with options similar to sign-up. These le | Option | Type | Default | Description | | --- | --- | --- | --- | -| `maxTimeToLiveInMilliseconds` | `number` | — | Maximum lifetime of the user's session in **milliseconds**. Once expired, the session cannot be extended. | -| `onProgress` | `(progress) => void` | — | Callback fired at each step of the sign-up flow (e.g., fetching credential, validating, signing). Useful to customize your UI. | +| `maxTimeToLiveInMilliseconds` | `number` | **4 hours** | Maximum lifetime of the user's session in **milliseconds**. Once expired, the session cannot be extended. | +| `onProgress` | `(progress) => void` | | Callback fired at each step of the sign-up flow (e.g., fetching credential, validating, signing). Useful to customize your UI. | Example with options: @@ -882,17 +890,17 @@ Internet Identity sign-in can be customized with options that let you control se | Option | Type | Default | Description | | --- | --- | --- | --- | -| `maxTimeToLiveInMillis` | `BigInt(4 * 60 * 60 * 1000 * 1000 * 1000)` | — | Specifies the duration for the session (defaults to **4 hours**). It's **important** to note that this duration remains constant, whether the users are active or inactive. | -| `windowed` | `true` | — | By default, the authentication flow is presented in a popup window on desktop that is automatically centered on the browser. This behavior can be turned off by setting the option to `false`, causing the authentication flow to happen in a separate tab instead. | -| `derivationOrigin` | — | — | The main domain to be used to ensure your users are identified with the same public ID, regardless of which of your satellite's URLs they use to access your application. | -| `allowPin` | `false` | — | We consider the specific PIN authentication method of [Internet Identity](https://internetcomputer.org/docs/current/references/ii-spec#client-authentication-protocol) as "insecure" because users can easily lose their login information if they do not register a passphrase, particularly as Safari clears the browser cache every two weeks in cases of inactivity. This is why we **disable** it by default. | -| `onProgress` | `(progress) => void` | — | Callback for provider sign-in and user creation/loading. | +| `maxTimeToLiveInNanoseconds` | `BigInt(4 * 60 * 60 * 1000 * 1000 * 1000)` | **4 hours** | Maximum lifetime of the user's session in **nanoseconds**. Once expired, the session cannot be extended. | +| `windowed` | `boolean` | `true` | By default, the authentication flow is presented in a popup window on desktop that is automatically centered on the browser. This behavior can be turned off by setting the option to `false`, causing the authentication flow to happen in a separate tab instead. | +| `derivationOrigin` | `string` or `URL` | | The main domain to be used to ensure your users are identified with the same public ID, regardless of which of your satellite's URLs they use to access your application. | +| `allowPin` | `boolean` | `false` | We consider the specific PIN authentication method of [Internet Identity](https://internetcomputer.org/docs/current/references/ii-spec#client-authentication-protocol) as "insecure" because users can easily lose their login information if they do not register a passphrase, particularly as Safari clears the browser cache every two weeks in cases of inactivity. This is why we **disable** it by default. | +| `onProgress` | `(progress) => void` | | Callback for provider sign-in and user creation/loading. | | `domain` | `internetcomputer.org` or `ic0.app` | `internetcomputer.org` | The domain on which to open Internet Identity. | Example with options: ``` -await signIn({ ii: { options: { maxTimeToLiveInMilliseconds: 1000 * 60 * 30, // 30 minutes onProgress: ({ step, state }) => { console.log("Step:", step, "State:", state); }, derivationOrigin: "https://myapp.com" } }}); +await signIn({ ii: { options: { maxTimeToLiveInNanoseconds: BigInt(24 * 60 * 60 * 1000 * 1000 * 1000), // 1 day onProgress: ({ step, state }) => { console.log("Step:", step, "State:", state); }, derivationOrigin: "https://myapp.com" } }}); ``` #### Handling Errors @@ -919,18 +927,16 @@ NFID sign-in can be customized with following options: | Option | Default Value | Default | Description | | --- | --- | --- | --- | -| `maxTimeToLiveInMillis` | `BigInt(4 * 60 * 60 * 1000 * 1000 * 1000)` | — | Specifies the duration for the session (defaults to **4 hours**). It's **important** to note that this duration remains constant, whether the users are active or inactive. | -| `windowed` | `true` | — | By default, the authentication flow is presented in a popup window on desktop that is automatically centered on the browser. This behavior can be turned off by setting the option to `false`, causing the authentication flow to happen in a separate tab instead. | -| `derivationOrigin` | — | — | The main domain to be used to ensure your users are identified with the same public ID, regardless of which of your satellite's URLs they use to access your application. | -| `allowPin` | `false` | — | We consider the specific PIN authentication method of [Internet Identity](https://internetcomputer.org/docs/current/references/ii-spec#client-authentication-protocol) as "insecure" because users can easily lose their login information if they do not register a passphrase, particularly as Safari clears the browser cache every two weeks in cases of inactivity. This is why we **disable** it by default. | -| `onProgress` | `(progress) => void` | — | Callback for provider sign-in and user creation/loading. | -| `appName` | `string` | — | The name of your application, shown to the user during sign-in. | -| `logoUrl` | `string` | — | URL of your application's logo, shown to the user during sign-in. | +| `maxTimeToLiveInNanoseconds` | `BigInt(4 * 60 * 60 * 1000 * 1000 * 1000)` | **4 hours** | Maximum lifetime of the user's session in **nanoseconds**. Once expired, the session cannot be extended. | +| `windowed` | `boolean` | `true` | By default, the authentication flow is presented in a popup window on desktop that is automatically centered on the browser. This behavior can be turned off by setting the option to `false`, causing the authentication flow to happen in a separate tab instead. | +| `onProgress` | `(progress) => void` | | Callback for provider sign-in and user creation/loading. | +| `appName` | `string` | | The name of your application, shown to the user during sign-in. | +| `logoUrl` | `string` | | URL of your application's logo, shown to the user during sign-in. | Example with options: ``` -import { signIn } from "@junobuild/core";await signIn({ nfid: { options: { maxTimeToLiveInMilliseconds: 1000 * 60 * 30, // 30 minutes onProgress: ({ step, state }) => { console.log("Step:", step, "State:", state); }, appName: "My Cool App", logoUrl: "https://myapp.com/logo.png" } }}); +import { signIn } from "@junobuild/core";await signIn({ nfid: { options: { maxTimeToLiveInNanoseconds: BigInt(24 * 60 * 60 * 1000 * 1000 * 1000), // 1 day onProgress: ({ step, state }) => { console.log("Step:", step, "State:", state); }, appName: "My Cool App", logoUrl: "https://myapp.com/logo.png" } }}); ``` --- From b05bdac78298c7e0522eaf5e7f7d1de59bee3e0d Mon Sep 17 00:00:00 2001 From: David Dal Busco Date: Wed, 3 Sep 2025 18:48:26 +0200 Subject: [PATCH 11/18] docs: remove allowPin - which I really dislike and should not be used - and add derivationOrigin to NFID, seems supported Signed-off-by: David Dal Busco --- docs/build/authentication/development.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/build/authentication/development.md b/docs/build/authentication/development.md index df005d81..b3c055fb 100644 --- a/docs/build/authentication/development.md +++ b/docs/build/authentication/development.md @@ -154,14 +154,13 @@ await signIn({ Internet Identity sign-in can be customized with options that let you control session lifetime, provider configuration, or track progress during the flow. -| Option | Type | Default | Description | -| ---------------------------- | ------------------------------------------ | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| `maxTimeToLiveInNanoseconds` | `BigInt(4 * 60 * 60 * 1000 * 1000 * 1000)` | **4 hours** | Maximum lifetime of the user's session in **nanoseconds**. Once expired, the session cannot be extended. | -| `windowed` | `boolean` | `true` | By default, the authentication flow is presented in a popup window on desktop that is automatically centered on the browser. This behavior can be turned off by setting the option to `false`, causing the authentication flow to happen in a separate tab instead. | -| `derivationOrigin` | `string` or `URL` | | The main domain to be used to ensure your users are identified with the same public ID, regardless of which of your satellite's URLs they use to access your application. | -| `allowPin` | `boolean` | `false` | We consider the specific PIN authentication method of [Internet Identity](https://internetcomputer.org/docs/current/references/ii-spec#client-authentication-protocol) as "insecure" because users can easily lose their login information if they do not register a passphrase, particularly as Safari clears the browser cache every two weeks in cases of inactivity. This is why we **disable** it by default. | -| `onProgress` | `(progress) => void` | | Callback for provider sign-in and user creation/loading. | -| `domain` | `internetcomputer.org` or `ic0.app` | `internetcomputer.org` | The domain on which to open Internet Identity. | +| Option | Type | Default | Description | +| ---------------------------- | ------------------------------------------ | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `maxTimeToLiveInNanoseconds` | `BigInt(4 * 60 * 60 * 1000 * 1000 * 1000)` | **4 hours** | Maximum lifetime of the user's session in **nanoseconds**. Once expired, the session cannot be extended. | +| `windowed` | `boolean` | `true` | By default, the authentication flow is presented in a popup window on desktop that is automatically centered on the browser. This behavior can be turned off by setting the option to `false`, causing the authentication flow to happen in a separate tab instead. | +| `derivationOrigin` | `string` or `URL` | | The main domain to be used to ensure your users are identified with the same public ID, regardless of which of your satellite's URLs they use to access your application. | +| `onProgress` | `(progress) => void` | | Callback for provider sign-in and user creation/loading. | +| `domain` | `internetcomputer.org` or `ic0.app` | `internetcomputer.org` | The domain on which to open Internet Identity. | Example with options: @@ -223,6 +222,7 @@ NFID sign-in can be customized with following options: | ---------------------------- | ------------------------------------------ | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `maxTimeToLiveInNanoseconds` | `BigInt(4 * 60 * 60 * 1000 * 1000 * 1000)` | **4 hours** | Maximum lifetime of the user's session in **nanoseconds**. Once expired, the session cannot be extended. | | `windowed` | `boolean` | `true` | By default, the authentication flow is presented in a popup window on desktop that is automatically centered on the browser. This behavior can be turned off by setting the option to `false`, causing the authentication flow to happen in a separate tab instead. | +| `derivationOrigin` | `string` or `URL` | | The main domain to be used to ensure your users are identified with the same public ID, regardless of which of your satellite's URLs they use to access your application. | | `onProgress` | `(progress) => void` | | Callback for provider sign-in and user creation/loading. | | `appName` | `string` | | The name of your application, shown to the user during sign-in. | | `logoUrl` | `string` | | URL of your application's logo, shown to the user during sign-in. | From abee2454ba65d4fd2ea2899ea195da3a9d1815b0 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 3 Sep 2025 16:50:07 +0000 Subject: [PATCH 12/18] =?UTF-8?q?=F0=9F=93=84=20Update=20LLMs.txt=20snapsh?= =?UTF-8?q?ot=20for=20PR=20review?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .llms-snapshots/llms-full.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.llms-snapshots/llms-full.txt b/.llms-snapshots/llms-full.txt index 1c29bebc..5c5f1876 100644 --- a/.llms-snapshots/llms-full.txt +++ b/.llms-snapshots/llms-full.txt @@ -893,7 +893,6 @@ Internet Identity sign-in can be customized with options that let you control se | `maxTimeToLiveInNanoseconds` | `BigInt(4 * 60 * 60 * 1000 * 1000 * 1000)` | **4 hours** | Maximum lifetime of the user's session in **nanoseconds**. Once expired, the session cannot be extended. | | `windowed` | `boolean` | `true` | By default, the authentication flow is presented in a popup window on desktop that is automatically centered on the browser. This behavior can be turned off by setting the option to `false`, causing the authentication flow to happen in a separate tab instead. | | `derivationOrigin` | `string` or `URL` | | The main domain to be used to ensure your users are identified with the same public ID, regardless of which of your satellite's URLs they use to access your application. | -| `allowPin` | `boolean` | `false` | We consider the specific PIN authentication method of [Internet Identity](https://internetcomputer.org/docs/current/references/ii-spec#client-authentication-protocol) as "insecure" because users can easily lose their login information if they do not register a passphrase, particularly as Safari clears the browser cache every two weeks in cases of inactivity. This is why we **disable** it by default. | | `onProgress` | `(progress) => void` | | Callback for provider sign-in and user creation/loading. | | `domain` | `internetcomputer.org` or `ic0.app` | `internetcomputer.org` | The domain on which to open Internet Identity. | @@ -929,6 +928,7 @@ NFID sign-in can be customized with following options: | --- | --- | --- | --- | | `maxTimeToLiveInNanoseconds` | `BigInt(4 * 60 * 60 * 1000 * 1000 * 1000)` | **4 hours** | Maximum lifetime of the user's session in **nanoseconds**. Once expired, the session cannot be extended. | | `windowed` | `boolean` | `true` | By default, the authentication flow is presented in a popup window on desktop that is automatically centered on the browser. This behavior can be turned off by setting the option to `false`, causing the authentication flow to happen in a separate tab instead. | +| `derivationOrigin` | `string` or `URL` | | The main domain to be used to ensure your users are identified with the same public ID, regardless of which of your satellite's URLs they use to access your application. | | `onProgress` | `(progress) => void` | | Callback for provider sign-in and user creation/loading. | | `appName` | `string` | | The name of your application, shown to the user during sign-in. | | `logoUrl` | `string` | | URL of your application's logo, shown to the user during sign-in. | From a50754e2a50559b81b1c3e8f99607d3d4f7705a2 Mon Sep 17 00:00:00 2001 From: David Dal Busco Date: Thu, 4 Sep 2025 07:33:00 +0200 Subject: [PATCH 13/18] chore: redo Signed-off-by: David Dal Busco --- docs/build/authentication/development.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/docs/build/authentication/development.md b/docs/build/authentication/development.md index b3c055fb..b526258b 100644 --- a/docs/build/authentication/development.md +++ b/docs/build/authentication/development.md @@ -250,7 +250,7 @@ await signIn({ ## Sign-out -You can end a user's session, no matter which provider they used to sign in, by logging them out. +You can end a user's session by logging them out. ```typescript import { signOut } from "@junobuild/core"; @@ -258,6 +258,12 @@ import { signOut } from "@junobuild/core"; await signOut(); ``` +:::note + +This will clear the sign-in information stored in IndexedDB. + +::: + --- ## Listening to Auth Changes From 59749094c9599a39a4c96c3125362627571670b8 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 4 Sep 2025 05:34:39 +0000 Subject: [PATCH 14/18] =?UTF-8?q?=F0=9F=93=84=20Update=20LLMs.txt=20snapsh?= =?UTF-8?q?ot=20for=20PR=20review?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .llms-snapshots/llms-full.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.llms-snapshots/llms-full.txt b/.llms-snapshots/llms-full.txt index 5c5f1876..5e41d6d4 100644 --- a/.llms-snapshots/llms-full.txt +++ b/.llms-snapshots/llms-full.txt @@ -943,12 +943,16 @@ import { signIn } from "@junobuild/core";await signIn({ nfid: { options: { ## Sign-out -You can end a user's session, no matter which provider they used to sign in, by logging them out. +You can end a user's session by logging them out. ``` import { signOut } from "@junobuild/core";await signOut(); ``` +**Note:** + +This will clear the sign-in information stored in IndexedDB. + --- ## Listening to Auth Changes From ade45796f9d7dc607a460c798b4990253138c7e6 Mon Sep 17 00:00:00 2001 From: David Dal Busco Date: Thu, 4 Sep 2025 07:52:30 +0200 Subject: [PATCH 15/18] docs: links and wording Signed-off-by: David Dal Busco --- docs/build/authentication/development.md | 16 ++++++++++++++-- docs/build/authentication/index.md | 5 +---- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/docs/build/authentication/development.md b/docs/build/authentication/development.md index b526258b..55680dcf 100644 --- a/docs/build/authentication/development.md +++ b/docs/build/authentication/development.md @@ -28,6 +28,12 @@ await signUp({ }); ``` +:::note + +Returning users don't need to go through sign-up again. They can simply use [sign-in](#passkeys-1) with their existing passkey to authenticate. + +::: + #### Options Passkey sign-up can be customized with a handful of options. These let you control how long a session lasts, how the passkey is displayed to the user, and whether you want to track progress in your own UI. @@ -100,9 +106,9 @@ If your app provides features that require authentication, your users need to si ### Passkeys -With Passkeys, sign-in uses the digital key previously created on the user's device — for example in the browser, iCloud Keychain, Google Password Manager, etc. +With Passkeys, returning users sign in using the digital key previously created on their device — for example in the browser, iCloud Keychain, Google Password Manager, etc. -During sign-in, the user will be asked to use their authenticator to prove possession of the passkey and re-establish a valid session with your satellite. +The user will be asked to use their authenticator to prove possession of the passkey and re-establish a valid session with your satellite. ```typescript import { signIn } from "@junobuild/core"; @@ -112,6 +118,12 @@ await signIn({ }); ``` +:::note + +New users must first go through [sign-up](#passkeys) to create a passkey before they can sign in. + +::: + #### Options Passkey sign-in can also be customized with options similar to sign-up. These let you control how long a session lasts and whether you want to track progress in your own UI. diff --git a/docs/build/authentication/index.md b/docs/build/authentication/index.md index 26fa21a5..e130ce2d 100644 --- a/docs/build/authentication/index.md +++ b/docs/build/authentication/index.md @@ -16,7 +16,7 @@ keywords: Juno allows you to securely identify users anonymously, without passwords and without tracking. -You can choose between [Passkeys] for built-in authentication, or integrate third-party providers like [Internet Identity] or [NFID]. +You can choose between [Passkeys](development.md#passkeys) for built-in authentication method, or integrate third-party providers like [Internet Identity](development.md#internet-identity) or [NFID](development.md#nfid). Authentication works hand-in-hand with other Juno services like [Datastore](../datastore/index.mdx) and [Storage](../storage/index.mdx). @@ -75,6 +75,3 @@ If you're unsure which domain to use as the primary domain, here are two common - You plan to host multiple satellites under different domains and don't want to tie user identity to just one. Choosing the right derivation origin early helps avoid identity issues later, but both approaches are valid depending on your goals. - -[Internet Identity]: ../../terminology.md#internet-identity -[NFID]: ../../terminology.md#nfid From 6c4d515433bb102d990b43a5d2fc55cea9bab095 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 4 Sep 2025 05:54:04 +0000 Subject: [PATCH 16/18] =?UTF-8?q?=F0=9F=93=84=20Update=20LLMs.txt=20snapsh?= =?UTF-8?q?ot=20for=20PR=20review?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .llms-snapshots/llms-full.txt | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/.llms-snapshots/llms-full.txt b/.llms-snapshots/llms-full.txt index 5e41d6d4..e8aacd9c 100644 --- a/.llms-snapshots/llms-full.txt +++ b/.llms-snapshots/llms-full.txt @@ -801,6 +801,10 @@ During sign-up, the user will be asked to use their authenticator twice: once to import { signUp } from "@junobuild/core";await signUp({ webauthn: {}}); ``` +**Note:** + +Returning users don't need to go through sign-up again. They can simply use ([sign-in](#passkeys-1)) with their existing passkey to authenticate. + #### Options Passkey sign-up can be customized with a handful of options. These let you control how long a session lasts, how the passkey is displayed to the user, and whether you want to track progress in your own UI. @@ -853,14 +857,18 @@ If your app provides features that require authentication, your users need to si ### Passkeys -With Passkeys, sign-in uses the digital key previously created on the user's device — for example in the browser, iCloud Keychain, Google Password Manager, etc. +With Passkeys, returning users sign in using the digital key previously created on their device — for example in the browser, iCloud Keychain, Google Password Manager, etc. -During sign-in, the user will be asked to use their authenticator to prove possession of the passkey and re-establish a valid session with your satellite. +The user will be asked to use their authenticator to prove possession of the passkey and re-establish a valid session with your satellite. ``` import { signIn } from "@junobuild/core";await signIn({ webauthn: {}}); ``` +**Note:** + +New users must first go through ([sign-up](#passkeys)) to create a passkey before they can sign in. + #### Options Passkey sign-in can also be customized with options similar to sign-up. These let you control how long a session lasts and whether you want to track progress in your own UI. From 0a15e61ff752a3ba1b7f6a7bc4b6394d22755406 Mon Sep 17 00:00:00 2001 From: David Dal Busco Date: Thu, 4 Sep 2025 11:33:57 +0200 Subject: [PATCH 17/18] docs: choose provider Signed-off-by: David Dal Busco --- docs/build/authentication/index.md | 31 ++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/docs/build/authentication/index.md b/docs/build/authentication/index.md index e130ce2d..3cc2da8f 100644 --- a/docs/build/authentication/index.md +++ b/docs/build/authentication/index.md @@ -75,3 +75,34 @@ If you're unsure which domain to use as the primary domain, here are two common - You plan to host multiple satellites under different domains and don't want to tie user identity to just one. Choosing the right derivation origin early helps avoid identity issues later, but both approaches are valid depending on your goals. + +--- + +## Choosing a Provider + +Each authentication method has its strengths. The right choice depends not only on your app's technical needs, but also on what your users expect and feel comfortable with. + +- **Passkeys**: + - ✅ Best for mainstream users who expect a familiar, frictionless login with Face ID, Touch ID, or device unlock. + - ✅ Great when you want a Web2-like UX but with stronger security. + - 🤔 Users must explicitly choose between sign-up and sign-in, which can add friction if not guided. + - ❌ Without syncing to iCloud or Google Password Manager, a passkey stored only in the browser can be lost if the browser is reset or uninstalled. + - ❌ When using a manager, users must trust Apple/Google and other big tech for privacy preservation and safekeeping of their passkey. + +- **Internet Identity**: + - ✅ Best if you want users to authenticate with a fully decentralized and privacy-preserving identity. + - ✅ Provides strong guarantees against tracking between domains. + - 🤔 Requires context switching to an external window. + - ❌ Limited awareness among mainstream users beyond the Internet Computer community. + - ❌ Domain scoping can be confusing if misconfigured. + +- **NFID**: + - ✅ Good for users already onboarded with a NFID Wallet. + - ✅ Offers an alternative on the Internet Computer. + - 🤔 Requires context switching to an external window. + - ❌ Limited awareness among mainstream users beyond the Internet Computer community. + - ❌ Smaller user base compared to Passkeys or Internet Identity. + +In practice, many developers implement both Passkeys and Internet Identity side by side. This gives users the choice between a device-native login flow and an Internet Computer–native identity, covering a wider range of expectations. + +Ultimately, the choice should be guided by the audience you're targeting and how strongly you weigh the considerations outlined above. From 9e72e10e4d5f9b62164c26fce088b4c574ff39fb Mon Sep 17 00:00:00 2001 From: David Dal Busco Date: Thu, 4 Sep 2025 11:37:13 +0200 Subject: [PATCH 18/18] docs: review Signed-off-by: David Dal Busco --- docs/build/authentication/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/build/authentication/index.md b/docs/build/authentication/index.md index 3cc2da8f..c41b12cd 100644 --- a/docs/build/authentication/index.md +++ b/docs/build/authentication/index.md @@ -103,6 +103,6 @@ Each authentication method has its strengths. The right choice depends not only - ❌ Limited awareness among mainstream users beyond the Internet Computer community. - ❌ Smaller user base compared to Passkeys or Internet Identity. -In practice, many developers implement both Passkeys and Internet Identity side by side. This gives users the choice between a device-native login flow and an Internet Computer–native identity, covering a wider range of expectations. +In practice, we expect many developers will implement both Passkeys and Internet Identity side by side. This approach gives users the choice between a device-native login flow and an Internet Computer–native identity, covering a wider range of expectations. Ultimately, the choice should be guided by the audience you're targeting and how strongly you weigh the considerations outlined above.