@proveanything/smartlinks 2.1.12 → 2.1.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- import type { AuthLoginResponse, AppleLoginOptions, RefreshResponse, LogoutResponse, PhoneSendCodeResponse, PhoneVerifyResponse, PasswordResetRequestResponse, VerifyResetTokenResponse, PasswordResetCompleteResponse, EmailVerificationActionResponse, EmailVerifyTokenResponse, AuthKitConfig, AuthKitConfigInput, AuthKitSetIdentityResponse, AuthKitInviteRequest, AuthKitInviteResponse, MagicLinkSendResponse, MagicLinkVerifyResponse, UserProfile, UpdateProfileResponse, ProfileUpdateData, SuccessResponse, SendWhatsAppRequest, SendWhatsAppResponse, ExchangeWhatsAppSessionResponse, VerifyWhatsAppResponse, WhatsAppStatusResponse, SendSmsVerifyRequest, SendSmsVerifyResponse, VerifySmsResponse, UpsertContactRequest, UpsertContactResponse, MfaChallengeSendResponse, MfaFinalizeResponse, MfaEnrollSendResponse, MfaTotpEnrollResponse, MfaEnrolledResponse, MfaFactor, MfaFactorsResponse, TrustedDevice } from "../types/authKit.js";
1
+ import type { AuthLoginResponse, AppleLoginOptions, MicrosoftLoginOptions, RefreshResponse, LogoutResponse, PhoneSendCodeResponse, PhoneVerifyResponse, PasswordResetRequestResponse, VerifyResetTokenResponse, PasswordResetCompleteResponse, EmailVerificationActionResponse, EmailVerifyTokenResponse, AuthKitConfig, AuthKitConfigInput, AuthKitSetIdentityResponse, AuthKitInviteRequest, AuthKitInviteResponse, MagicLinkSendResponse, MagicLinkVerifyResponse, UserProfile, UpdateProfileResponse, ProfileUpdateData, SuccessResponse, SendWhatsAppRequest, SendWhatsAppResponse, ExchangeWhatsAppSessionResponse, VerifyWhatsAppResponse, WhatsAppStatusResponse, SendSmsVerifyRequest, SendSmsVerifyResponse, VerifySmsResponse, UpsertContactRequest, UpsertContactResponse, MfaChallengeSendResponse, MfaFinalizeResponse, MfaEnrollSendResponse, MfaTotpEnrollResponse, MfaEnrolledResponse, MfaFactor, MfaFactorsResponse, TrustedDevice } from "../types/authKit.js";
2
2
  /**
3
3
  * Namespace containing helper functions for the new AuthKit API.
4
4
  * Legacy collection-based authKit helpers retained (marked as *Legacy*).
@@ -93,6 +93,22 @@ export declare namespace authKit {
93
93
  * @see AppleLoginOptions
94
94
  */
95
95
  function appleLogin(clientId: string, identityToken: string, opts?: AppleLoginOptions): Promise<AuthLoginResponse>;
96
+ /**
97
+ * Sign in with Microsoft — work or school accounts from any organisation, and personal Microsoft
98
+ * accounts — via a Microsoft ID token (public). Mirrors {@link appleLogin}: on success the bearer
99
+ * token is stored and the cache invalidated.
100
+ *
101
+ * Get the ID token from Microsoft's sign-in (response_type `id_token`, scope `openid profile email`)
102
+ * against the app in the public config's `microsoftClientId`. A site on its own domain can't be a
103
+ * registered address of that app, so the SmartLinks sign-in UI opens SmartLinks' Microsoft sign-in
104
+ * page in a popup, which calls this with `opts.returnOrigin` and hands the result back.
105
+ *
106
+ * Notable error codes: `MISSING_MICROSOFT_TOKEN` (400), `MICROSOFT_AUTH_NOT_CONFIGURED` (400),
107
+ * `INVALID_MICROSOFT_TOKEN` (401), `MICROSOFT_ORIGIN_NOT_ALLOWED` (403), `NOT_IN_ORGANISATION` (403 —
108
+ * the login setup's {@link AuthKitAccess} rule), `ACCOUNT_EXISTS_UNVERIFIED` (409),
109
+ * `MICROSOFT_AUTH_FAILED` (500). Gated by step-up MFA like every sign-in.
110
+ */
111
+ function microsoftLogin(clientId: string, idToken: string, opts?: MicrosoftLoginOptions): Promise<AuthLoginResponse>;
96
112
  /**
97
113
  * Exchange a refresh token for a fresh access token (public — the refresh token IS
98
114
  * the credential). **Native sessions only**; refresh tokens are issued only when the
@@ -139,6 +139,30 @@ export var authKit;
139
139
  return res;
140
140
  }
141
141
  authKit.appleLogin = appleLogin;
142
+ /**
143
+ * Sign in with Microsoft — work or school accounts from any organisation, and personal Microsoft
144
+ * accounts — via a Microsoft ID token (public). Mirrors {@link appleLogin}: on success the bearer
145
+ * token is stored and the cache invalidated.
146
+ *
147
+ * Get the ID token from Microsoft's sign-in (response_type `id_token`, scope `openid profile email`)
148
+ * against the app in the public config's `microsoftClientId`. A site on its own domain can't be a
149
+ * registered address of that app, so the SmartLinks sign-in UI opens SmartLinks' Microsoft sign-in
150
+ * page in a popup, which calls this with `opts.returnOrigin` and hands the result back.
151
+ *
152
+ * Notable error codes: `MISSING_MICROSOFT_TOKEN` (400), `MICROSOFT_AUTH_NOT_CONFIGURED` (400),
153
+ * `INVALID_MICROSOFT_TOKEN` (401), `MICROSOFT_ORIGIN_NOT_ALLOWED` (403), `NOT_IN_ORGANISATION` (403 —
154
+ * the login setup's {@link AuthKitAccess} rule), `ACCOUNT_EXISTS_UNVERIFIED` (409),
155
+ * `MICROSOFT_AUTH_FAILED` (500). Gated by step-up MFA like every sign-in.
156
+ */
157
+ async function microsoftLogin(clientId, idToken, opts) {
158
+ const res = await post(`/authkit/${encodeURIComponent(clientId)}/auth/microsoft`, Object.assign({ idToken }, opts));
159
+ if (res.token) {
160
+ setBearerToken(res.token);
161
+ invalidateCache();
162
+ }
163
+ return res;
164
+ }
165
+ authKit.microsoftLogin = microsoftLogin;
142
166
  /* ===================================
143
167
  * Native session refresh (public)
144
168
  * =================================== */
@@ -1,6 +1,6 @@
1
1
  # Smartlinks API Summary
2
2
 
3
- Version: 2.1.12 | Generated: 2026-11-08T14:30:42.034Z
3
+ Version: 2.1.13 | Generated: 2026-11-09T11:51:55.948Z
4
4
 
5
5
  This is a concise summary of all available API functions and types.
6
6
 
@@ -4624,6 +4624,24 @@ interface LogoutResponse {
4624
4624
  }
4625
4625
  ```
4626
4626
 
4627
+ **MicrosoftLoginOptions** (interface)
4628
+ ```typescript
4629
+ interface MicrosoftLoginOptions {
4630
+ returnOrigin?: string
4631
+ trustedDeviceToken?: string
4632
+ }
4633
+ ```
4634
+
4635
+ **AuthKitAccess** (interface)
4636
+ ```typescript
4637
+ interface AuthKitAccess {
4638
+ mode: 'anyone' | 'organisation'
4639
+ domains?: string[]
4640
+ emails?: string[]
4641
+ microsoftTenants?: Record<string, string>
4642
+ }
4643
+ ```
4644
+
4627
4645
  **AppleLoginOptions** (interface)
4628
4646
  ```typescript
4629
4647
  interface AppleLoginOptions {
@@ -4953,6 +4971,8 @@ interface AuthKitConfig {
4953
4971
  collectionIds?: string[]
4954
4972
  identity?: AuthKitIdentity
4955
4973
  signUp?: 'open' | 'invite'
4974
+ access?: AuthKitAccess
4975
+ microsoftClientId?: string
4956
4976
  }
4957
4977
  ```
4958
4978
 
@@ -11937,6 +11957,9 @@ Sign in with LinkedIn (OpenID Connect) via a server-side authorization code (pub
11937
11957
  **appleLogin**(clientId: string, identityToken: string, opts?: AppleLoginOptions) → `Promise<AuthLoginResponse>`
11938
11958
  Sign in with Apple via an Apple identity token (public). Mirrors {@link googleLogin}. On success the returned bearer token is stored automatically and the cache is invalidated. Notable error codes (thrown as `SmartlinksApiError`, read via `err.errorCode`): - `MISSING_APPLE_TOKEN` (400), `APPLE_AUTH_NOT_CONFIGURED` (400), `INVALID_APPLE_TOKEN` (401), `APPLE_AUTH_FAILED` (500) - `ACCOUNT_EXISTS_UNVERIFIED` (409) — an unverified account already owns this email; the server refuses to silently link. `err.details.requiresEmailVerification` is `true`. Recoverable: the user should sign in with their password (or reset it), then link Apple from settings. **The same 409 can now come back from {@link googleLogin}** under the shared verified-to-verified linking policy. Gated by step-up MFA — see {@link login} for the `MFA_REQUIRED` error shape. Pass `opts.trustedDeviceToken` to skip the challenge on a recognized device.
11939
11959
 
11960
+ **microsoftLogin**(clientId: string, idToken: string, opts?: MicrosoftLoginOptions) → `Promise<AuthLoginResponse>`
11961
+ Sign in with Microsoft — work or school accounts from any organisation, and personal Microsoft accounts — via a Microsoft ID token (public). Mirrors {@link appleLogin}: on success the bearer token is stored and the cache invalidated. Get the ID token from Microsoft's sign-in (response_type `id_token`, scope `openid profile email`) against the app in the public config's `microsoftClientId`. A site on its own domain can't be a registered address of that app, so the SmartLinks sign-in UI opens SmartLinks' Microsoft sign-in page in a popup, which calls this with `opts.returnOrigin` and hands the result back. Notable error codes: `MISSING_MICROSOFT_TOKEN` (400), `MICROSOFT_AUTH_NOT_CONFIGURED` (400), `INVALID_MICROSOFT_TOKEN` (401), `MICROSOFT_ORIGIN_NOT_ALLOWED` (403), `NOT_IN_ORGANISATION` (403 — the login setup's {@link AuthKitAccess} rule), `ACCOUNT_EXISTS_UNVERIFIED` (409), `MICROSOFT_AUTH_FAILED` (500). Gated by step-up MFA like every sign-in.
11962
+
11940
11963
  **refreshToken**(clientId: string, refreshToken: string) → `Promise<RefreshResponse>`
11941
11964
  Exchange a refresh token for a fresh access token (public — the refresh token IS the credential). **Native sessions only**; refresh tokens are issued only when the host opted in via `initializeApi({ platform: 'native' })`. On success the new access token is stored automatically (`setBearerToken`). The returned `refreshToken` is **rotated** — the caller must persist it and discard the old one before refreshing again. ⚠️ **Single-use, no retry, serialize calls.** This method issues exactly one request and never retries: replaying a consumed refresh token triggers `REFRESH_TOKEN_REUSE_DETECTED` (the whole session family is revoked). The caller is responsible for ensuring only one refresh is in flight at a time (e.g. across tabs or resume events). Errors (thrown as `SmartlinksApiError`, read via `err.errorCode`): `MISSING_REFRESH_TOKEN` (400), `INVALID_REFRESH_TOKEN` (401), `REFRESH_TOKEN_REUSE_DETECTED` (401) — the last two mean a hard logout.
11942
11965
 
@@ -259,6 +259,56 @@ try {
259
259
  > ⚠️ This is a behaviour change for `googleLogin`, which previously merged silently in
260
260
  > this case. Handle the 409 for both methods.
261
261
 
262
+ ### Sign in with Microsoft
263
+
264
+ Work or school accounts from **any** organisation, and personal Microsoft accounts (Outlook, Hotmail,
265
+ Live). Add `'microsoft'` to `enabledProviders` — that's all: SmartLinks' own Microsoft app serves every
266
+ organisation, so neither you nor your users' IT registers anything.
267
+
268
+ ```ts
269
+ const session = await authKit.microsoftLogin(clientId, microsoftIdToken, { returnOrigin });
270
+ ```
271
+
272
+ - **In the SmartLinks sign-in UI** the Microsoft button opens SmartLinks' Microsoft sign-in page
273
+ (`https://smartlinks.app/apps/account/stable/microsoft-proxy.html`) in a popup — the one address
274
+ registered with Microsoft — which signs in and hands the session back to your site. Your site must be
275
+ one of the login setup's own (its collections' domains or site addresses, or `allowedRedirectDomains`),
276
+ else `MICROSOFT_ORIGIN_NOT_ALLOWED` (403).
277
+ - **Your own UI:** get an ID token from Microsoft (`response_type=id_token`, scope `openid profile email`,
278
+ authority `https://login.microsoftonline.com/common`) for the app in the public config's
279
+ `microsoftClientId`, and pass it here.
280
+ - **Some companies' IT approves new apps for their staff.** The first person from such a company sees
281
+ "needs admin approval"; their IT approves SmartLinks once for the organisation and everyone can sign in.
282
+ - **Your own name on Microsoft's screen (optional):** register your own *multitenant* app in Microsoft
283
+ Entra (Supported account types: any organisation + personal accounts; Web redirect URI as above, with
284
+ "ID tokens" ticked; token configuration: optional claim `xms_edov` on the ID token) and set its
285
+ Application (client) ID as `microsoftClientId`.
286
+ - A Microsoft account's email is trusted only when Microsoft vouches that its organisation owns the
287
+ domain (or for personal accounts): an organisation can give its users any address. Linking to an
288
+ existing account by email follows the same verified-to-verified rule as Google and Apple.
289
+
290
+ ### Who can sign in (`access`)
291
+
292
+ Restrict a login setup to one organisation — no keys, no IT:
293
+
294
+ ```ts
295
+ await authKit.update(collectionId, clientId, {
296
+ access: { mode: 'organisation', domains: ['acme.com'], emails: ['contractor@gmail.com'] },
297
+ });
298
+ ```
299
+
300
+ - Someone is from acme.com when their **verified** email is at acme.com, they're one of `emails`, or they
301
+ signed in with Microsoft from acme's own Microsoft organisation (looked up from the domain when you
302
+ save — `microsoftTenants` is filled in for you).
303
+ - Checked on **every** sign-in method each time a session is issued: everyone else gets
304
+ `NOT_IN_ORGANISATION` (403) with a message naming the domain. Tighten the rule and people already in
305
+ are refused from their next sign-in.
306
+ - `register` refuses outside addresses before making anything, and never signs an unverified address
307
+ straight in (even in `immediate` mode) — it must be verified first.
308
+ - Phone-only and WhatsApp-only accounts have no email to prove an organisation, so they can't get in.
309
+ - The public config (`load`) returns `access: { mode, domains }` so your page can say who it's for; the
310
+ `emails` list is never public. `{ mode: 'anyone' }` (or no `access`) lets everyone in, as before.
311
+
262
312
  ### Refresh tokens (native sessions)
263
313
 
264
314
  Native/Capacitor hosts can hold long-lived sessions via refresh tokens. Opt in **once**
package/dist/openapi.yaml CHANGED
@@ -9641,6 +9641,38 @@ paths:
9641
9641
  description: Unauthorized
9642
9642
  404:
9643
9643
  description: Not found
9644
+ /authkit/{clientId}/auth/microsoft:
9645
+ post:
9646
+ tags:
9647
+ - authKit
9648
+ summary: authKit.microsoftLogin
9649
+ operationId: authKit_microsoftLogin
9650
+ security: []
9651
+ parameters:
9652
+ - name: clientId
9653
+ in: path
9654
+ required: true
9655
+ schema:
9656
+ type: string
9657
+ responses:
9658
+ 200:
9659
+ description: Success
9660
+ content:
9661
+ application/json:
9662
+ schema:
9663
+ $ref: "#/components/schemas/AuthLoginResponse"
9664
+ 400:
9665
+ description: Bad request
9666
+ 401:
9667
+ description: Unauthorized
9668
+ 404:
9669
+ description: Not found
9670
+ requestBody:
9671
+ required: true
9672
+ content:
9673
+ application/json:
9674
+ schema:
9675
+ $ref: "#/components/schemas/MicrosoftLoginOptions"
9644
9676
  /authkit/{clientId}/auth/phone/send-code:
9645
9677
  post:
9646
9678
  tags:
@@ -23933,6 +23965,35 @@ components:
23933
23965
  additionalProperties: true
23934
23966
  required:
23935
23967
  - success
23968
+ MicrosoftLoginOptions:
23969
+ type: object
23970
+ properties:
23971
+ returnOrigin:
23972
+ type: string
23973
+ trustedDeviceToken:
23974
+ type: string
23975
+ AuthKitAccess:
23976
+ type: object
23977
+ properties:
23978
+ mode:
23979
+ type: string
23980
+ enum:
23981
+ - anyone
23982
+ - organisation
23983
+ domains:
23984
+ type: array
23985
+ items:
23986
+ type: string
23987
+ emails:
23988
+ type: array
23989
+ items:
23990
+ type: string
23991
+ microsoftTenants:
23992
+ type: object
23993
+ additionalProperties:
23994
+ type: string
23995
+ required:
23996
+ - mode
23936
23997
  AppleLoginOptions:
23937
23998
  type: object
23938
23999
  properties:
@@ -24449,6 +24510,10 @@ components:
24449
24510
  enum:
24450
24511
  - open
24451
24512
  - invite
24513
+ access:
24514
+ $ref: "#/components/schemas/AuthKitAccess"
24515
+ microsoftClientId:
24516
+ type: string
24452
24517
  required:
24453
24518
  - id
24454
24519
  AuthKitInviteRequest:
@@ -24581,6 +24646,7 @@ components:
24581
24646
  - ACCOUNT_EXISTS_UNVERIFIED
24582
24647
  - APPLE_AUTH_FAILED
24583
24648
  - SIGN_UP_CLOSED
24649
+ - NOT_IN_ORGANISATION
24584
24650
  MfaFactor:
24585
24651
  type: string
24586
24652
  enum:
@@ -98,6 +98,40 @@ export type RefreshErrorCode = 'MISSING_REFRESH_TOKEN' | 'INVALID_REFRESH_TOKEN'
98
98
  * Options for {@link authKit.appleLogin}. All fields are optional — only the
99
99
  * `identityToken` (passed as a positional argument) is required by the server.
100
100
  */
101
+ /** Options for {@link authKit.microsoftLogin}. */
102
+ export interface MicrosoftLoginOptions {
103
+ /**
104
+ * The site the session will be handed to, when signing in through a popup page on another address
105
+ * (the SmartLinks Microsoft sign-in page does this). The server refuses unless it's one of the login
106
+ * setup's own sites (`MICROSOFT_ORIGIN_NOT_ALLOWED`). Leave it out when signing in on the site itself.
107
+ */
108
+ returnOrigin?: string;
109
+ /** Skip the step-up MFA challenge on a recognised device. */
110
+ trustedDeviceToken?: string;
111
+ }
112
+ /**
113
+ * Who can sign in through a login setup, whatever the method (password, magic link, phone, WhatsApp,
114
+ * Google, Apple, LinkedIn, Microsoft):
115
+ * - `anyone` (also: no `access`) — anyone, as before;
116
+ * - `organisation` — people from the listed organisations: a VERIFIED email at one of `domains`, one of
117
+ * the listed `emails`, or signing in with Microsoft from the domain's own Microsoft organisation. A
118
+ * Microsoft email alone doesn't count (an organisation can give its users any address), so on save
119
+ * the server looks up each domain's Microsoft organisation itself — nobody types a tenant id.
120
+ *
121
+ * Checked every time a session is issued (tightening it shuts people out from their next sign-in);
122
+ * refused with `NOT_IN_ORGANISATION` (403). Registration refuses outside addresses up front and never
123
+ * signs an unverified address straight in. Accounts with no email (phone / WhatsApp only) can't show
124
+ * they're from an organisation. The public config returns only `{ mode, domains }`.
125
+ */
126
+ export interface AuthKitAccess {
127
+ mode: 'anyone' | 'organisation';
128
+ /** e.g. `['acme.com']` (no `@`; exact domains — list subsidiaries' domains too). Up to 50. */
129
+ domains?: string[];
130
+ /** Particular people allowed besides the organisations, e.g. a contractor. Up to 50. Never public. */
131
+ emails?: string[];
132
+ /** Server-filled on save: `{ 'acme.com': '<Microsoft tenant id>' }` for domains with a Microsoft organisation. Read-only. */
133
+ microsoftTenants?: Record<string, string>;
134
+ }
101
135
  export interface AppleLoginOptions {
102
136
  /** Apple authorization code. Accepted but ignored by the server for now (reserved for future server-side token exchange). */
103
137
  authorizationCode?: string;
@@ -128,7 +162,7 @@ export interface AppleLoginOptions {
128
162
  * `ACCOUNT_EXISTS_UNVERIFIED` case also carries `requiresEmailVerification: true`
129
163
  * in `SmartlinksApiError.details`.
130
164
  */
131
- export type AuthKitErrorCode = 'MISSING_APPLE_TOKEN' | 'APPLE_AUTH_NOT_CONFIGURED' | 'INVALID_APPLE_TOKEN' | 'ACCOUNT_EXISTS_UNVERIFIED' | 'APPLE_AUTH_FAILED' | 'SIGN_UP_CLOSED';
165
+ export type AuthKitErrorCode = 'MISSING_APPLE_TOKEN' | 'APPLE_AUTH_NOT_CONFIGURED' | 'INVALID_APPLE_TOKEN' | 'ACCOUNT_EXISTS_UNVERIFIED' | 'APPLE_AUTH_FAILED' | 'SIGN_UP_CLOSED' | 'NOT_IN_ORGANISATION' | 'MISSING_MICROSOFT_TOKEN' | 'MICROSOFT_AUTH_NOT_CONFIGURED' | 'INVALID_MICROSOFT_TOKEN' | 'MICROSOFT_ORIGIN_NOT_ALLOWED' | 'MICROSOFT_AUTH_FAILED';
132
166
  /** A second-step method: a code by email or text message, or from an authenticator app. */
133
167
  export type MfaFactor = 'email' | 'sms' | 'totp';
134
168
  /**
@@ -445,6 +479,16 @@ export interface AuthKitConfig {
445
479
  * Setting `invite` needs own logins first (`OWN_LOGINS_REQUIRED`, 409).
446
480
  */
447
481
  signUp?: 'open' | 'invite';
482
+ /** Who can sign in — see {@link AuthKitAccess}. Absent = anyone. */
483
+ access?: AuthKitAccess;
484
+ /**
485
+ * Sign in with Microsoft: add `'microsoft'` to `enabledProviders`. SmartLinks' own Microsoft app serves
486
+ * every organisation and personal Microsoft accounts, so nothing else is needed. Set this only to show
487
+ * your OWN name on Microsoft's sign-in screen: the Application (client) ID of your own multitenant app
488
+ * registration (redirect URI: https://smartlinks.app/apps/account/stable/microsoft-proxy.html). On the
489
+ * public config it's the effective id (yours, else SmartLinks').
490
+ */
491
+ microsoftClientId?: string;
448
492
  }
449
493
  /** Body of {@link authKit.invite}. */
450
494
  export interface AuthKitInviteRequest {
@@ -1,6 +1,6 @@
1
1
  # Smartlinks API Summary
2
2
 
3
- Version: 2.1.12 | Generated: 2026-11-08T14:30:42.034Z
3
+ Version: 2.1.13 | Generated: 2026-11-09T11:51:55.948Z
4
4
 
5
5
  This is a concise summary of all available API functions and types.
6
6
 
@@ -4624,6 +4624,24 @@ interface LogoutResponse {
4624
4624
  }
4625
4625
  ```
4626
4626
 
4627
+ **MicrosoftLoginOptions** (interface)
4628
+ ```typescript
4629
+ interface MicrosoftLoginOptions {
4630
+ returnOrigin?: string
4631
+ trustedDeviceToken?: string
4632
+ }
4633
+ ```
4634
+
4635
+ **AuthKitAccess** (interface)
4636
+ ```typescript
4637
+ interface AuthKitAccess {
4638
+ mode: 'anyone' | 'organisation'
4639
+ domains?: string[]
4640
+ emails?: string[]
4641
+ microsoftTenants?: Record<string, string>
4642
+ }
4643
+ ```
4644
+
4627
4645
  **AppleLoginOptions** (interface)
4628
4646
  ```typescript
4629
4647
  interface AppleLoginOptions {
@@ -4953,6 +4971,8 @@ interface AuthKitConfig {
4953
4971
  collectionIds?: string[]
4954
4972
  identity?: AuthKitIdentity
4955
4973
  signUp?: 'open' | 'invite'
4974
+ access?: AuthKitAccess
4975
+ microsoftClientId?: string
4956
4976
  }
4957
4977
  ```
4958
4978
 
@@ -11937,6 +11957,9 @@ Sign in with LinkedIn (OpenID Connect) via a server-side authorization code (pub
11937
11957
  **appleLogin**(clientId: string, identityToken: string, opts?: AppleLoginOptions) → `Promise<AuthLoginResponse>`
11938
11958
  Sign in with Apple via an Apple identity token (public). Mirrors {@link googleLogin}. On success the returned bearer token is stored automatically and the cache is invalidated. Notable error codes (thrown as `SmartlinksApiError`, read via `err.errorCode`): - `MISSING_APPLE_TOKEN` (400), `APPLE_AUTH_NOT_CONFIGURED` (400), `INVALID_APPLE_TOKEN` (401), `APPLE_AUTH_FAILED` (500) - `ACCOUNT_EXISTS_UNVERIFIED` (409) — an unverified account already owns this email; the server refuses to silently link. `err.details.requiresEmailVerification` is `true`. Recoverable: the user should sign in with their password (or reset it), then link Apple from settings. **The same 409 can now come back from {@link googleLogin}** under the shared verified-to-verified linking policy. Gated by step-up MFA — see {@link login} for the `MFA_REQUIRED` error shape. Pass `opts.trustedDeviceToken` to skip the challenge on a recognized device.
11939
11959
 
11960
+ **microsoftLogin**(clientId: string, idToken: string, opts?: MicrosoftLoginOptions) → `Promise<AuthLoginResponse>`
11961
+ Sign in with Microsoft — work or school accounts from any organisation, and personal Microsoft accounts — via a Microsoft ID token (public). Mirrors {@link appleLogin}: on success the bearer token is stored and the cache invalidated. Get the ID token from Microsoft's sign-in (response_type `id_token`, scope `openid profile email`) against the app in the public config's `microsoftClientId`. A site on its own domain can't be a registered address of that app, so the SmartLinks sign-in UI opens SmartLinks' Microsoft sign-in page in a popup, which calls this with `opts.returnOrigin` and hands the result back. Notable error codes: `MISSING_MICROSOFT_TOKEN` (400), `MICROSOFT_AUTH_NOT_CONFIGURED` (400), `INVALID_MICROSOFT_TOKEN` (401), `MICROSOFT_ORIGIN_NOT_ALLOWED` (403), `NOT_IN_ORGANISATION` (403 — the login setup's {@link AuthKitAccess} rule), `ACCOUNT_EXISTS_UNVERIFIED` (409), `MICROSOFT_AUTH_FAILED` (500). Gated by step-up MFA like every sign-in.
11962
+
11940
11963
  **refreshToken**(clientId: string, refreshToken: string) → `Promise<RefreshResponse>`
11941
11964
  Exchange a refresh token for a fresh access token (public — the refresh token IS the credential). **Native sessions only**; refresh tokens are issued only when the host opted in via `initializeApi({ platform: 'native' })`. On success the new access token is stored automatically (`setBearerToken`). The returned `refreshToken` is **rotated** — the caller must persist it and discard the old one before refreshing again. ⚠️ **Single-use, no retry, serialize calls.** This method issues exactly one request and never retries: replaying a consumed refresh token triggers `REFRESH_TOKEN_REUSE_DETECTED` (the whole session family is revoked). The caller is responsible for ensuring only one refresh is in flight at a time (e.g. across tabs or resume events). Errors (thrown as `SmartlinksApiError`, read via `err.errorCode`): `MISSING_REFRESH_TOKEN` (400), `INVALID_REFRESH_TOKEN` (401), `REFRESH_TOKEN_REUSE_DETECTED` (401) — the last two mean a hard logout.
11942
11965
 
package/docs/auth-kit.md CHANGED
@@ -259,6 +259,56 @@ try {
259
259
  > ⚠️ This is a behaviour change for `googleLogin`, which previously merged silently in
260
260
  > this case. Handle the 409 for both methods.
261
261
 
262
+ ### Sign in with Microsoft
263
+
264
+ Work or school accounts from **any** organisation, and personal Microsoft accounts (Outlook, Hotmail,
265
+ Live). Add `'microsoft'` to `enabledProviders` — that's all: SmartLinks' own Microsoft app serves every
266
+ organisation, so neither you nor your users' IT registers anything.
267
+
268
+ ```ts
269
+ const session = await authKit.microsoftLogin(clientId, microsoftIdToken, { returnOrigin });
270
+ ```
271
+
272
+ - **In the SmartLinks sign-in UI** the Microsoft button opens SmartLinks' Microsoft sign-in page
273
+ (`https://smartlinks.app/apps/account/stable/microsoft-proxy.html`) in a popup — the one address
274
+ registered with Microsoft — which signs in and hands the session back to your site. Your site must be
275
+ one of the login setup's own (its collections' domains or site addresses, or `allowedRedirectDomains`),
276
+ else `MICROSOFT_ORIGIN_NOT_ALLOWED` (403).
277
+ - **Your own UI:** get an ID token from Microsoft (`response_type=id_token`, scope `openid profile email`,
278
+ authority `https://login.microsoftonline.com/common`) for the app in the public config's
279
+ `microsoftClientId`, and pass it here.
280
+ - **Some companies' IT approves new apps for their staff.** The first person from such a company sees
281
+ "needs admin approval"; their IT approves SmartLinks once for the organisation and everyone can sign in.
282
+ - **Your own name on Microsoft's screen (optional):** register your own *multitenant* app in Microsoft
283
+ Entra (Supported account types: any organisation + personal accounts; Web redirect URI as above, with
284
+ "ID tokens" ticked; token configuration: optional claim `xms_edov` on the ID token) and set its
285
+ Application (client) ID as `microsoftClientId`.
286
+ - A Microsoft account's email is trusted only when Microsoft vouches that its organisation owns the
287
+ domain (or for personal accounts): an organisation can give its users any address. Linking to an
288
+ existing account by email follows the same verified-to-verified rule as Google and Apple.
289
+
290
+ ### Who can sign in (`access`)
291
+
292
+ Restrict a login setup to one organisation — no keys, no IT:
293
+
294
+ ```ts
295
+ await authKit.update(collectionId, clientId, {
296
+ access: { mode: 'organisation', domains: ['acme.com'], emails: ['contractor@gmail.com'] },
297
+ });
298
+ ```
299
+
300
+ - Someone is from acme.com when their **verified** email is at acme.com, they're one of `emails`, or they
301
+ signed in with Microsoft from acme's own Microsoft organisation (looked up from the domain when you
302
+ save — `microsoftTenants` is filled in for you).
303
+ - Checked on **every** sign-in method each time a session is issued: everyone else gets
304
+ `NOT_IN_ORGANISATION` (403) with a message naming the domain. Tighten the rule and people already in
305
+ are refused from their next sign-in.
306
+ - `register` refuses outside addresses before making anything, and never signs an unverified address
307
+ straight in (even in `immediate` mode) — it must be verified first.
308
+ - Phone-only and WhatsApp-only accounts have no email to prove an organisation, so they can't get in.
309
+ - The public config (`load`) returns `access: { mode, domains }` so your page can say who it's for; the
310
+ `emails` list is never public. `{ mode: 'anyone' }` (or no `access`) lets everyone in, as before.
311
+
262
312
  ### Refresh tokens (native sessions)
263
313
 
264
314
  Native/Capacitor hosts can hold long-lived sessions via refresh tokens. Opt in **once**
package/openapi.yaml CHANGED
@@ -9641,6 +9641,38 @@ paths:
9641
9641
  description: Unauthorized
9642
9642
  404:
9643
9643
  description: Not found
9644
+ /authkit/{clientId}/auth/microsoft:
9645
+ post:
9646
+ tags:
9647
+ - authKit
9648
+ summary: authKit.microsoftLogin
9649
+ operationId: authKit_microsoftLogin
9650
+ security: []
9651
+ parameters:
9652
+ - name: clientId
9653
+ in: path
9654
+ required: true
9655
+ schema:
9656
+ type: string
9657
+ responses:
9658
+ 200:
9659
+ description: Success
9660
+ content:
9661
+ application/json:
9662
+ schema:
9663
+ $ref: "#/components/schemas/AuthLoginResponse"
9664
+ 400:
9665
+ description: Bad request
9666
+ 401:
9667
+ description: Unauthorized
9668
+ 404:
9669
+ description: Not found
9670
+ requestBody:
9671
+ required: true
9672
+ content:
9673
+ application/json:
9674
+ schema:
9675
+ $ref: "#/components/schemas/MicrosoftLoginOptions"
9644
9676
  /authkit/{clientId}/auth/phone/send-code:
9645
9677
  post:
9646
9678
  tags:
@@ -23933,6 +23965,35 @@ components:
23933
23965
  additionalProperties: true
23934
23966
  required:
23935
23967
  - success
23968
+ MicrosoftLoginOptions:
23969
+ type: object
23970
+ properties:
23971
+ returnOrigin:
23972
+ type: string
23973
+ trustedDeviceToken:
23974
+ type: string
23975
+ AuthKitAccess:
23976
+ type: object
23977
+ properties:
23978
+ mode:
23979
+ type: string
23980
+ enum:
23981
+ - anyone
23982
+ - organisation
23983
+ domains:
23984
+ type: array
23985
+ items:
23986
+ type: string
23987
+ emails:
23988
+ type: array
23989
+ items:
23990
+ type: string
23991
+ microsoftTenants:
23992
+ type: object
23993
+ additionalProperties:
23994
+ type: string
23995
+ required:
23996
+ - mode
23936
23997
  AppleLoginOptions:
23937
23998
  type: object
23938
23999
  properties:
@@ -24449,6 +24510,10 @@ components:
24449
24510
  enum:
24450
24511
  - open
24451
24512
  - invite
24513
+ access:
24514
+ $ref: "#/components/schemas/AuthKitAccess"
24515
+ microsoftClientId:
24516
+ type: string
24452
24517
  required:
24453
24518
  - id
24454
24519
  AuthKitInviteRequest:
@@ -24581,6 +24646,7 @@ components:
24581
24646
  - ACCOUNT_EXISTS_UNVERIFIED
24582
24647
  - APPLE_AUTH_FAILED
24583
24648
  - SIGN_UP_CLOSED
24649
+ - NOT_IN_ORGANISATION
24584
24650
  MfaFactor:
24585
24651
  type: string
24586
24652
  enum:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@proveanything/smartlinks",
3
- "version": "2.1.12",
3
+ "version": "2.1.13",
4
4
  "description": "Official JavaScript/TypeScript SDK for the Smartlinks API",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",