@spfn/auth 0.3.0-beta.17 → 0.3.0-beta.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +155 -0
- package/dist/errors.d.ts +74 -2
- package/dist/errors.js +51 -1
- package/dist/errors.js.map +1 -1
- package/dist/index.d.ts +39 -2
- package/dist/index.js +43 -1
- package/dist/index.js.map +1 -1
- package/dist/{machine-principals-nrpFSvvB.d.ts → machine-principals-BD4tnASp.d.ts} +171 -1
- package/dist/nextjs/api.js +6 -1
- package/dist/nextjs/api.js.map +1 -1
- package/dist/nextjs/server.d.ts +57 -2
- package/dist/nextjs/server.js +18 -0
- package/dist/nextjs/server.js.map +1 -1
- package/dist/server.d.ts +1466 -51
- package/dist/server.js +1862 -398
- package/dist/server.js.map +1 -1
- package/migrations/20260918083158_foamy_roughhouse/migration.sql +55 -0
- package/migrations/20260918083158_foamy_roughhouse/snapshot.json +5271 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -227,6 +227,7 @@ routes use `.skip(['auth'])`; the rest require `Authorization: Bearer <client-si
|
|
|
227
227
|
| `cancelAccountDeletion` | POST `/_auth/deletion/cancel` | public | cancel a pending deletion (credential-based recovery) |
|
|
228
228
|
| `listRoles` / `createAdminRole` / `updateAdminRole` / `deleteAdminRole` / `updateUserRole` | — | superadmin | admin RBAC management |
|
|
229
229
|
| OAuth routes | — | — | see OAuth section |
|
|
230
|
+
| `registerOAuth2Client` / `getOAuth2Authorize` / `createOAuth2AuthorizationCode` / `oauth2Token` / `oauth2Revoke` / `listOAuth2Grants` / `revokeOAuth2Grant` | `/_auth/oauth2/*` | mixed | OAuth 2.1 authorization server for MCP clients — see [Authorization server for MCP clients](#authorization-server-for-mcp-clients). 404 unless configured |
|
|
230
231
|
|
|
231
232
|
There is deliberately **no account-existence endpoint**. `POST /_auth/exists` was removed
|
|
232
233
|
because it answered "does this account exist" directly, which is user enumeration; the
|
|
@@ -1311,6 +1312,27 @@ export default async function AdminPage()
|
|
|
1311
1312
|
Also exported: `getAuthSessionData`, `getUserRole`, `getUserPermissions`, `hasAnyRole`,
|
|
1312
1313
|
`hasAnyPermission`, the OAuth pending-session helpers, and `createOAuthCallbackHandler`.
|
|
1313
1314
|
|
|
1315
|
+
### Emptying the cookie jar from a route handler or middleware
|
|
1316
|
+
|
|
1317
|
+
`clearSession()` works where `next/headers` is writable. The page that answers *the API
|
|
1318
|
+
refused your session* is usually a route handler or middleware holding a `NextResponse`
|
|
1319
|
+
instead — `clearSessionCookies(response)` expires the session, key-id, OAuth-pending and
|
|
1320
|
+
CSRF cookies on it and returns the same response, so the call chains:
|
|
1321
|
+
|
|
1322
|
+
```typescript
|
|
1323
|
+
import { clearSessionCookies } from '@spfn/auth/nextjs/server';
|
|
1324
|
+
|
|
1325
|
+
export function GET(request: NextRequest)
|
|
1326
|
+
{
|
|
1327
|
+
return clearSessionCookies(NextResponse.redirect(new URL('/login', request.url)));
|
|
1328
|
+
}
|
|
1329
|
+
```
|
|
1330
|
+
|
|
1331
|
+
Never spell the names in your app. They carry an `SPFN_PORT` suffix (`spfn_session_4001`),
|
|
1332
|
+
so two dev instances do not overwrite each other's cookies, and a hand-written copy of that
|
|
1333
|
+
rule clears the wrong cookie without failing. Read them from `sessionCookieNames()`, which
|
|
1334
|
+
returns `{ session, keyId, oauthPending, csrf }` at call time.
|
|
1335
|
+
|
|
1314
1336
|
## CSRF protection
|
|
1315
1337
|
|
|
1316
1338
|
Cookie-authenticated mutations carry a CSRF token by default. Nothing to write: the
|
|
@@ -2001,6 +2023,139 @@ x-acme-service-token: <the app's own credential>
|
|
|
2001
2023
|
The field stays informational: downstream permission and tenant code takes one principal shape and
|
|
2002
2024
|
never branches on how it was produced.
|
|
2003
2025
|
|
|
2026
|
+
## Authorization server for MCP clients
|
|
2027
|
+
|
|
2028
|
+
Let Claude Code and Codex connect to your app's `/mcp` endpoint as the user, over the flow
|
|
2029
|
+
they already speak: OAuth 2.1 with dynamic client registration and PKCE.
|
|
2030
|
+
|
|
2031
|
+
```console
|
|
2032
|
+
$ claude mcp add --transport http acme https://api.acme.com/mcp
|
|
2033
|
+
$ claude
|
|
2034
|
+
> /mcp
|
|
2035
|
+
```
|
|
2036
|
+
|
|
2037
|
+
Between those two lines the CLI discovers `/.well-known/oauth-authorization-server`, registers
|
|
2038
|
+
itself, opens a browser at your consent screen, catches the redirect on a loopback port, and
|
|
2039
|
+
exchanges the code for a token. Nobody pastes anything.
|
|
2040
|
+
|
|
2041
|
+
The feature is opt-in and the opt-in is one block:
|
|
2042
|
+
|
|
2043
|
+
```typescript
|
|
2044
|
+
createAuthLifecycle({
|
|
2045
|
+
authorizationServer: {
|
|
2046
|
+
scopes: {
|
|
2047
|
+
'mcp:read': 'Read your projects and tasks',
|
|
2048
|
+
'mcp:write': 'Create and edit your tasks',
|
|
2049
|
+
},
|
|
2050
|
+
defaultScopes: ['mcp:read'], // what a request with no `scope` asks for. default: all of them
|
|
2051
|
+
// issuer: 'https://api.acme.com', // default: SPFN_API_URL
|
|
2052
|
+
// authorizeUrl: 'https://acme.com/oauth/authorize', // default: {app url}/oauth/authorize
|
|
2053
|
+
// allowedRedirectOrigins: [], // https origins a client may register. loopback needs no entry
|
|
2054
|
+
// accessTokenTtlMs: 8 * 60 * 60 * 1000, // default 8 hours
|
|
2055
|
+
// refreshTokenTtlMs: 30 * 24 * 60 * 60 * 1000, // default 30 days
|
|
2056
|
+
// codeTtlMs: 60 * 1000, // default 60 seconds
|
|
2057
|
+
},
|
|
2058
|
+
})
|
|
2059
|
+
```
|
|
2060
|
+
|
|
2061
|
+
Without that block every endpoint below answers 404 and nothing else changes — including the
|
|
2062
|
+
boot check, which does not run. `scopes` is the one setting with no default: the names are
|
|
2063
|
+
your application's vocabulary, they are published in the metadata document and read aloud on
|
|
2064
|
+
the consent screen, and there is nothing to derive them from.
|
|
2065
|
+
|
|
2066
|
+
| Endpoint | Host | Auth | What it is |
|
|
2067
|
+
| --- | --- | --- | --- |
|
|
2068
|
+
| `GET /.well-known/oauth-authorization-server` | API | public | RFC 8414 discovery — the first request any client makes |
|
|
2069
|
+
| `POST /_auth/oauth2/register` | API | public, IP rate limited | RFC 7591 dynamic registration. Public clients only |
|
|
2070
|
+
| `GET /_auth/oauth2/authorize` | API | `authenticate` | What the consent screen should say. Records nothing |
|
|
2071
|
+
| `POST /_auth/oauth2/authorize` | API | `authenticate` | The decision. Mints the code |
|
|
2072
|
+
| `POST /_auth/oauth2/token` | API | public, IP rate limited | `authorization_code` and `refresh_token` |
|
|
2073
|
+
| `POST /_auth/oauth2/revoke` | API | public (RFC 7009) | `client_id` required; 200 for an unknown token as surely as for a real one |
|
|
2074
|
+
| `GET /_auth/oauth2/grants` · `DELETE /_auth/oauth2/grants/:id` | API | `authenticate` | What the user has connected, and the button that disconnects it |
|
|
2075
|
+
| `GET /oauth/authorize` · `POST /oauth/authorize` | web | session | The consent screen itself — see the note at the end |
|
|
2076
|
+
|
|
2077
|
+
Two lines wire it to `@spfn/mcp`:
|
|
2078
|
+
|
|
2079
|
+
```typescript
|
|
2080
|
+
import { verifyAccessToken } from '@spfn/auth/server';
|
|
2081
|
+
|
|
2082
|
+
export const mcp = createMcpRoute({ validateToken: verifyAccessToken, tools: [...] });
|
|
2083
|
+
```
|
|
2084
|
+
|
|
2085
|
+
`verifyAccessToken(token, resource)` answers `{ clientId, scopes, expiresAt, userId }` or
|
|
2086
|
+
`null`, and `null` is a refusal — `@spfn/mcp` ≥ 0.3.0-beta.3 accepts it as one rather than
|
|
2087
|
+
requiring a throw. `expiresAt` is seconds since the epoch, like every other OAuth field here.
|
|
2088
|
+
|
|
2089
|
+
- **Only loopback and origins you allowed.** A client may register `http://localhost:*`,
|
|
2090
|
+
`http://127.0.0.1:*` or `http://[::1]:*` — a CLI cannot know which port the OS will hand it,
|
|
2091
|
+
so the **port** is the one thing allowed to vary. Nothing else does: host, path and query
|
|
2092
|
+
must match the registration exactly, a fragment is refused at registration and at request,
|
|
2093
|
+
and plain `http` anywhere else is refused outright. An `https` redirect URI has to be on an
|
|
2094
|
+
origin listed in `allowedRedirectOrigins`.
|
|
2095
|
+
- **Those three spellings are three registrations.** `localhost`, `127.0.0.1` and `[::1]` do
|
|
2096
|
+
not stand in for one another — they resolve differently on a machine with a split-horizon
|
|
2097
|
+
resolver, and a client answered on a host it did not register is a client something
|
|
2098
|
+
redirected. IPv6 is the one place spelling is folded: `http://[0:0:0:0:0:0:0:1]:5/cb` and
|
|
2099
|
+
`http://[::1]:5/cb` are the same registration, because both sides are read through
|
|
2100
|
+
`new URL(...).hostname`.
|
|
2101
|
+
- **An unknown client or a mismatched redirect URI is shown, never redirected.** There is no
|
|
2102
|
+
vetted URI to send that error to, and sending it to the one the request supplied is the open
|
|
2103
|
+
redirect the whole rule exists to close. Every other authorize-time error —
|
|
2104
|
+
`invalid_request`, `invalid_scope`, `invalid_target`, `access_denied` — goes back to the
|
|
2105
|
+
client on its registered URI, which is the only form the waiting CLI can read.
|
|
2106
|
+
- **PKCE S256, and nothing else.** No `plain`, and no request without a challenge. The code
|
|
2107
|
+
arrives on a loopback port that any process on the machine could have been listening on.
|
|
2108
|
+
- **`resource` is required** (RFC 8707) and the token is only good against it. A token your
|
|
2109
|
+
user approved for your MCP server cannot be replayed against a neighbouring deployment that
|
|
2110
|
+
shares this authorization server.
|
|
2111
|
+
- **A code is spent by the statement that reads it**, so of two exchanges arriving together
|
|
2112
|
+
exactly one gets tokens — and **presenting a code twice revokes the grant**, because by then
|
|
2113
|
+
somebody else may hold what the first exchange produced.
|
|
2114
|
+
- **Refresh tokens rotate, and a rotated one is marked rather than deleted.** Presenting it
|
|
2115
|
+
again revokes the grant, which kills the replacement as well as the replayed token: both
|
|
2116
|
+
hang off the grant and there is no telling which holder is the thief. A refresh may ask for
|
|
2117
|
+
a **subset** of the granted scopes and never for more; narrowing applies to that request and
|
|
2118
|
+
leaves the user's consent record as they gave it.
|
|
2119
|
+
- **Every code and refresh failure is one `invalid_grant`, word for word.** Unknown, expired,
|
|
2120
|
+
spent, wrong verifier, another client's. The endpoint is public, and an error that told
|
|
2121
|
+
those apart would answer the question somebody holding a stolen value is asking.
|
|
2122
|
+
- **Token endpoint errors are RFC 6749 §5.2, not the SPFN envelope** —
|
|
2123
|
+
`{ "error": "invalid_grant", "error_description": "..." }`, status 400,
|
|
2124
|
+
`Cache-Control: no-store`. The client reading it is an OAuth library that knows those two
|
|
2125
|
+
field names and nothing about this framework. Registration refusals are RFC 7591 §3.2.2 the
|
|
2126
|
+
same way (`invalid_redirect_uri`, `invalid_client_metadata`).
|
|
2127
|
+
- **Nothing but a hash is stored.** Codes and tokens are `spfn_at_<64 hex>` /
|
|
2128
|
+
`spfn_rt_<64 hex>` / 43 url-safe characters, and the value exists in the clear exactly once,
|
|
2129
|
+
in the response that issues it. It is never logged and never put in an event.
|
|
2130
|
+
- **A global revocation reaches the grants.** `revoke-all`, a password change, a completed
|
|
2131
|
+
password reset and a deletion request each revoke every grant the account has — so a CLI
|
|
2132
|
+
holding a refresh token through "sign me out everywhere" cannot be back within the hour,
|
|
2133
|
+
which is exactly the client that call was aimed at. The user's own
|
|
2134
|
+
`DELETE /_auth/oauth2/grants/:id` does the same for one client, immediately.
|
|
2135
|
+
- **The issuer is checked at boot.** It must be an absolute URL with no path — the metadata
|
|
2136
|
+
document is served at an origin's root and nowhere else — and it must be `https`, or `http`
|
|
2137
|
+
on `localhost` / `127.0.0.1` / `[::1]` for development. Anything else refuses to start with
|
|
2138
|
+
a message naming `SPFN_API_URL` or `authorizationServer.issuer`, whichever the value came
|
|
2139
|
+
from. An application with no `authorizationServer` block never reaches this check. The one
|
|
2140
|
+
value that is accepted and rewritten is a bare trailing slash: `https://api.acme.com/` is
|
|
2141
|
+
stored as `https://api.acme.com`, the form `@spfn/mcp` derives, so the two documents naming
|
|
2142
|
+
this server agree (RFC 8414 §3.3). That reduction happens where the config is resolved, not
|
|
2143
|
+
in the boot check, so a document read without the lifecycle hook publishes the same issuer.
|
|
2144
|
+
- **Unapproved client rows are swept.** Registration is unauthenticated by necessity, so
|
|
2145
|
+
`auth.oauth2.client-purge` (in `authJobRouter`, daily at 05:00) deletes clients older than a
|
|
2146
|
+
day that no user ever approved. One with a grant against it is never touched. Registration
|
|
2147
|
+
is also capped per IP two ways — a burst rate limit, and a cap on how many unapproved
|
|
2148
|
+
clients one address may have standing, which a rate limit cannot express.
|
|
2149
|
+
- **`/mcp` tokens are not sessions.** An access token issued here authorizes the MCP surface
|
|
2150
|
+
for the resource it names. It is not a user session and is not accepted by ordinary API
|
|
2151
|
+
routes.
|
|
2152
|
+
|
|
2153
|
+
The consent screen itself — `createOAuth2AuthorizeHandlers({ loginPath })`, which renders
|
|
2154
|
+
`GET /oauth/authorize` and handles its POST — ships in the next release. Until then the API
|
|
2155
|
+
side above is complete and a handler can be written against it: `GET /_auth/oauth2/authorize`
|
|
2156
|
+
returns `{ clientName, redirectHost, scopes, resource }` to draw, and
|
|
2157
|
+
`POST /_auth/oauth2/authorize` takes the decision and returns the code to redirect with.
|
|
2158
|
+
|
|
2004
2159
|
## Machine principals (`registerMachineVerifier`)
|
|
2005
2160
|
|
|
2006
2161
|
A machine credential is issued by a service to a non-interactive process, and its subject is
|
package/dist/errors.d.ts
CHANGED
|
@@ -598,6 +598,70 @@ declare class PasskeyConfigError extends HttpError {
|
|
|
598
598
|
details?: Record<string, any>;
|
|
599
599
|
});
|
|
600
600
|
}
|
|
601
|
+
/**
|
|
602
|
+
* OAuth2 Unknown Client Error (400)
|
|
603
|
+
*
|
|
604
|
+
* Thrown by the API authorize endpoints when `client_id` names no registered
|
|
605
|
+
* client. One of the two refusals that must NOT be turned into a redirect: with
|
|
606
|
+
* no client there is no registered redirect URI, so the only place left to send
|
|
607
|
+
* the error is the one the request supplied — which is exactly the open redirect
|
|
608
|
+
* this rule exists to close. The consent screen shows it instead.
|
|
609
|
+
*/
|
|
610
|
+
declare class OAuth2UnknownClientError extends ValidationError {
|
|
611
|
+
constructor(data?: {
|
|
612
|
+
message?: string;
|
|
613
|
+
details?: Record<string, any>;
|
|
614
|
+
});
|
|
615
|
+
}
|
|
616
|
+
/**
|
|
617
|
+
* OAuth2 Redirect URI Mismatch Error (400)
|
|
618
|
+
*
|
|
619
|
+
* Thrown when `redirect_uri` is not one the client registered. The second
|
|
620
|
+
* non-redirectable refusal, for the same reason as the first: redirecting the
|
|
621
|
+
* error to an unregistered URI is the attack.
|
|
622
|
+
*/
|
|
623
|
+
declare class OAuth2RedirectUriMismatchError extends ValidationError {
|
|
624
|
+
constructor(data?: {
|
|
625
|
+
message?: string;
|
|
626
|
+
details?: Record<string, any>;
|
|
627
|
+
});
|
|
628
|
+
}
|
|
629
|
+
/**
|
|
630
|
+
* OAuth2 Authorize Redirect Error (400)
|
|
631
|
+
*
|
|
632
|
+
* Every other authorize-time refusal — `invalid_request`, `invalid_scope`,
|
|
633
|
+
* `invalid_target`, `access_denied`. The client and its redirect URI are both
|
|
634
|
+
* known by the time these are decided, so RFC 6749 §4.1.2.1 says the error goes
|
|
635
|
+
* back to the client as query parameters on that URI rather than to the person.
|
|
636
|
+
*
|
|
637
|
+
* The API cannot perform that redirect — it is answering the web app's consent
|
|
638
|
+
* handler, not the browser — so it carries the pieces in `details` and the
|
|
639
|
+
* handler builds the 302. `redirectUri` is the registered-and-matched value, not
|
|
640
|
+
* the raw parameter, which is what makes it safe to send somebody to.
|
|
641
|
+
*/
|
|
642
|
+
declare class OAuth2AuthorizeRedirectError extends ValidationError {
|
|
643
|
+
constructor(data: {
|
|
644
|
+
error: string;
|
|
645
|
+
redirectUri: string;
|
|
646
|
+
state?: string;
|
|
647
|
+
message?: string;
|
|
648
|
+
details?: Record<string, any>;
|
|
649
|
+
});
|
|
650
|
+
}
|
|
651
|
+
/**
|
|
652
|
+
* OAuth2 Grant Not Found Error (404)
|
|
653
|
+
*
|
|
654
|
+
* Thrown by `DELETE /_auth/oauth2/grants/:id` when the caller owns no live grant
|
|
655
|
+
* of that id. A grant belonging to somebody else answers the same way as one
|
|
656
|
+
* that never existed — the id is a number in a URL, and telling the two apart
|
|
657
|
+
* would let anyone count other people's connected clients.
|
|
658
|
+
*/
|
|
659
|
+
declare class OAuth2GrantNotFoundError extends NotFoundError {
|
|
660
|
+
constructor(data?: {
|
|
661
|
+
message?: string;
|
|
662
|
+
details?: Record<string, any>;
|
|
663
|
+
});
|
|
664
|
+
}
|
|
601
665
|
|
|
602
666
|
type authErrors_AccountAlreadyExistsError = AccountAlreadyExistsError;
|
|
603
667
|
declare const authErrors_AccountAlreadyExistsError: typeof AccountAlreadyExistsError;
|
|
@@ -653,6 +717,14 @@ type authErrors_NativeSignInUnsupportedError = NativeSignInUnsupportedError;
|
|
|
653
717
|
declare const authErrors_NativeSignInUnsupportedError: typeof NativeSignInUnsupportedError;
|
|
654
718
|
type authErrors_NonceKeyBindingError = NonceKeyBindingError;
|
|
655
719
|
declare const authErrors_NonceKeyBindingError: typeof NonceKeyBindingError;
|
|
720
|
+
type authErrors_OAuth2AuthorizeRedirectError = OAuth2AuthorizeRedirectError;
|
|
721
|
+
declare const authErrors_OAuth2AuthorizeRedirectError: typeof OAuth2AuthorizeRedirectError;
|
|
722
|
+
type authErrors_OAuth2GrantNotFoundError = OAuth2GrantNotFoundError;
|
|
723
|
+
declare const authErrors_OAuth2GrantNotFoundError: typeof OAuth2GrantNotFoundError;
|
|
724
|
+
type authErrors_OAuth2RedirectUriMismatchError = OAuth2RedirectUriMismatchError;
|
|
725
|
+
declare const authErrors_OAuth2RedirectUriMismatchError: typeof OAuth2RedirectUriMismatchError;
|
|
726
|
+
type authErrors_OAuth2UnknownClientError = OAuth2UnknownClientError;
|
|
727
|
+
declare const authErrors_OAuth2UnknownClientError: typeof OAuth2UnknownClientError;
|
|
656
728
|
type authErrors_PasskeyAlreadyRegisteredError = PasskeyAlreadyRegisteredError;
|
|
657
729
|
declare const authErrors_PasskeyAlreadyRegisteredError: typeof PasskeyAlreadyRegisteredError;
|
|
658
730
|
type authErrors_PasskeyChallengeError = PasskeyChallengeError;
|
|
@@ -684,7 +756,7 @@ declare const authErrors_VerificationTokenPurposeMismatchError: typeof Verificat
|
|
|
684
756
|
type authErrors_VerificationTokenTargetMismatchError = VerificationTokenTargetMismatchError;
|
|
685
757
|
declare const authErrors_VerificationTokenTargetMismatchError: typeof VerificationTokenTargetMismatchError;
|
|
686
758
|
declare namespace authErrors {
|
|
687
|
-
export { authErrors_AccountAlreadyExistsError as AccountAlreadyExistsError, authErrors_AccountDisabledError as AccountDisabledError, authErrors_AccountPendingDeletionError as AccountPendingDeletionError, authErrors_DeletionAlreadyRequestedError as DeletionAlreadyRequestedError, authErrors_DeletionNotRequestedError as DeletionNotRequestedError, authErrors_DeviceAuthAlreadyHandledError as DeviceAuthAlreadyHandledError, authErrors_DeviceAuthDeniedError as DeviceAuthDeniedError, authErrors_DeviceAuthExpiredError as DeviceAuthExpiredError, authErrors_DeviceAuthNotFoundError as DeviceAuthNotFoundError, authErrors_ImmediateDeletionNotAllowedError as ImmediateDeletionNotAllowedError, authErrors_InsufficientPermissionsError as InsufficientPermissionsError, authErrors_InsufficientRoleError as InsufficientRoleError, authErrors_InvalidCredentialsError as InvalidCredentialsError, authErrors_InvalidKeyFingerprintError as InvalidKeyFingerprintError, authErrors_InvalidSignupLinkError as InvalidSignupLinkError, authErrors_InvalidSignupSetupSessionError as InvalidSignupSetupSessionError, authErrors_InvalidSocialTokenError as InvalidSocialTokenError, authErrors_InvalidTokenError as InvalidTokenError, authErrors_InvalidVerificationCodeError as InvalidVerificationCodeError, authErrors_InvalidVerificationTokenError as InvalidVerificationTokenError, authErrors_KeyAlgorithmMismatchError as KeyAlgorithmMismatchError, authErrors_KeyExpiredError as KeyExpiredError, authErrors_KeyIdAlreadyRegisteredError as KeyIdAlreadyRegisteredError, authErrors_KeyNotFoundError as KeyNotFoundError, authErrors_LastRecoveryCredentialError as LastRecoveryCredentialError, authErrors_NativeSignInUnsupportedError as NativeSignInUnsupportedError, authErrors_NonceKeyBindingError as NonceKeyBindingError, authErrors_PasskeyAlreadyRegisteredError as PasskeyAlreadyRegisteredError, authErrors_PasskeyChallengeError as PasskeyChallengeError, authErrors_PasskeyConfigError as PasskeyConfigError, authErrors_PasskeyNotFoundError as PasskeyNotFoundError, authErrors_PasskeyVerificationError as PasskeyVerificationError, authErrors_PasswordResetLinkError as PasswordResetLinkError, authErrors_PasswordResetSessionError as PasswordResetSessionError, authErrors_RecentAuthenticationRequiredError as RecentAuthenticationRequiredError, authErrors_RegistrationRejectedError as RegistrationRejectedError, authErrors_ReservedUsernameError as ReservedUsernameError, authErrors_TokenExpiredError as TokenExpiredError, authErrors_UnverifiedEmailLinkError as UnverifiedEmailLinkError, authErrors_UsernameAlreadyTakenError as UsernameAlreadyTakenError, authErrors_VerificationTokenPurposeMismatchError as VerificationTokenPurposeMismatchError, authErrors_VerificationTokenTargetMismatchError as VerificationTokenTargetMismatchError };
|
|
759
|
+
export { authErrors_AccountAlreadyExistsError as AccountAlreadyExistsError, authErrors_AccountDisabledError as AccountDisabledError, authErrors_AccountPendingDeletionError as AccountPendingDeletionError, authErrors_DeletionAlreadyRequestedError as DeletionAlreadyRequestedError, authErrors_DeletionNotRequestedError as DeletionNotRequestedError, authErrors_DeviceAuthAlreadyHandledError as DeviceAuthAlreadyHandledError, authErrors_DeviceAuthDeniedError as DeviceAuthDeniedError, authErrors_DeviceAuthExpiredError as DeviceAuthExpiredError, authErrors_DeviceAuthNotFoundError as DeviceAuthNotFoundError, authErrors_ImmediateDeletionNotAllowedError as ImmediateDeletionNotAllowedError, authErrors_InsufficientPermissionsError as InsufficientPermissionsError, authErrors_InsufficientRoleError as InsufficientRoleError, authErrors_InvalidCredentialsError as InvalidCredentialsError, authErrors_InvalidKeyFingerprintError as InvalidKeyFingerprintError, authErrors_InvalidSignupLinkError as InvalidSignupLinkError, authErrors_InvalidSignupSetupSessionError as InvalidSignupSetupSessionError, authErrors_InvalidSocialTokenError as InvalidSocialTokenError, authErrors_InvalidTokenError as InvalidTokenError, authErrors_InvalidVerificationCodeError as InvalidVerificationCodeError, authErrors_InvalidVerificationTokenError as InvalidVerificationTokenError, authErrors_KeyAlgorithmMismatchError as KeyAlgorithmMismatchError, authErrors_KeyExpiredError as KeyExpiredError, authErrors_KeyIdAlreadyRegisteredError as KeyIdAlreadyRegisteredError, authErrors_KeyNotFoundError as KeyNotFoundError, authErrors_LastRecoveryCredentialError as LastRecoveryCredentialError, authErrors_NativeSignInUnsupportedError as NativeSignInUnsupportedError, authErrors_NonceKeyBindingError as NonceKeyBindingError, authErrors_OAuth2AuthorizeRedirectError as OAuth2AuthorizeRedirectError, authErrors_OAuth2GrantNotFoundError as OAuth2GrantNotFoundError, authErrors_OAuth2RedirectUriMismatchError as OAuth2RedirectUriMismatchError, authErrors_OAuth2UnknownClientError as OAuth2UnknownClientError, authErrors_PasskeyAlreadyRegisteredError as PasskeyAlreadyRegisteredError, authErrors_PasskeyChallengeError as PasskeyChallengeError, authErrors_PasskeyConfigError as PasskeyConfigError, authErrors_PasskeyNotFoundError as PasskeyNotFoundError, authErrors_PasskeyVerificationError as PasskeyVerificationError, authErrors_PasswordResetLinkError as PasswordResetLinkError, authErrors_PasswordResetSessionError as PasswordResetSessionError, authErrors_RecentAuthenticationRequiredError as RecentAuthenticationRequiredError, authErrors_RegistrationRejectedError as RegistrationRejectedError, authErrors_ReservedUsernameError as ReservedUsernameError, authErrors_TokenExpiredError as TokenExpiredError, authErrors_UnverifiedEmailLinkError as UnverifiedEmailLinkError, authErrors_UsernameAlreadyTakenError as UsernameAlreadyTakenError, authErrors_VerificationTokenPurposeMismatchError as VerificationTokenPurposeMismatchError, authErrors_VerificationTokenTargetMismatchError as VerificationTokenTargetMismatchError };
|
|
688
760
|
}
|
|
689
761
|
|
|
690
762
|
/**
|
|
@@ -693,4 +765,4 @@ declare namespace authErrors {
|
|
|
693
765
|
|
|
694
766
|
declare const authErrorRegistry: ErrorRegistry;
|
|
695
767
|
|
|
696
|
-
export { AccountAlreadyExistsError, AccountDisabledError, AccountPendingDeletionError, authErrors as AuthError, DeletionAlreadyRequestedError, DeletionNotRequestedError, DeviceAuthAlreadyHandledError, DeviceAuthDeniedError, DeviceAuthExpiredError, DeviceAuthNotFoundError, ImmediateDeletionNotAllowedError, InsufficientPermissionsError, InsufficientRoleError, InvalidCredentialsError, InvalidKeyFingerprintError, InvalidSignupLinkError, InvalidSignupSetupSessionError, InvalidSocialTokenError, InvalidTokenError, InvalidVerificationCodeError, InvalidVerificationTokenError, KeyAlgorithmMismatchError, KeyExpiredError, KeyIdAlreadyRegisteredError, KeyNotFoundError, LastRecoveryCredentialError, NativeSignInUnsupportedError, NonceKeyBindingError, PasskeyAlreadyRegisteredError, PasskeyChallengeError, PasskeyConfigError, PasskeyNotFoundError, PasskeyVerificationError, PasswordResetLinkError, PasswordResetSessionError, RecentAuthenticationRequiredError, RegistrationRejectedError, ReservedUsernameError, TokenExpiredError, UnverifiedEmailLinkError, UsernameAlreadyTakenError, VerificationTokenPurposeMismatchError, VerificationTokenTargetMismatchError, authErrorRegistry };
|
|
768
|
+
export { AccountAlreadyExistsError, AccountDisabledError, AccountPendingDeletionError, authErrors as AuthError, DeletionAlreadyRequestedError, DeletionNotRequestedError, DeviceAuthAlreadyHandledError, DeviceAuthDeniedError, DeviceAuthExpiredError, DeviceAuthNotFoundError, ImmediateDeletionNotAllowedError, InsufficientPermissionsError, InsufficientRoleError, InvalidCredentialsError, InvalidKeyFingerprintError, InvalidSignupLinkError, InvalidSignupSetupSessionError, InvalidSocialTokenError, InvalidTokenError, InvalidVerificationCodeError, InvalidVerificationTokenError, KeyAlgorithmMismatchError, KeyExpiredError, KeyIdAlreadyRegisteredError, KeyNotFoundError, LastRecoveryCredentialError, NativeSignInUnsupportedError, NonceKeyBindingError, OAuth2AuthorizeRedirectError, OAuth2GrantNotFoundError, OAuth2RedirectUriMismatchError, OAuth2UnknownClientError, PasskeyAlreadyRegisteredError, PasskeyChallengeError, PasskeyConfigError, PasskeyNotFoundError, PasskeyVerificationError, PasswordResetLinkError, PasswordResetSessionError, RecentAuthenticationRequiredError, RegistrationRejectedError, ReservedUsernameError, TokenExpiredError, UnverifiedEmailLinkError, UsernameAlreadyTakenError, VerificationTokenPurposeMismatchError, VerificationTokenTargetMismatchError, authErrorRegistry };
|
package/dist/errors.js
CHANGED
|
@@ -37,6 +37,10 @@ __export(auth_errors_exports, {
|
|
|
37
37
|
LastRecoveryCredentialError: () => LastRecoveryCredentialError,
|
|
38
38
|
NativeSignInUnsupportedError: () => NativeSignInUnsupportedError,
|
|
39
39
|
NonceKeyBindingError: () => NonceKeyBindingError,
|
|
40
|
+
OAuth2AuthorizeRedirectError: () => OAuth2AuthorizeRedirectError,
|
|
41
|
+
OAuth2GrantNotFoundError: () => OAuth2GrantNotFoundError,
|
|
42
|
+
OAuth2RedirectUriMismatchError: () => OAuth2RedirectUriMismatchError,
|
|
43
|
+
OAuth2UnknownClientError: () => OAuth2UnknownClientError,
|
|
40
44
|
PasskeyAlreadyRegisteredError: () => PasskeyAlreadyRegisteredError,
|
|
41
45
|
PasskeyChallengeError: () => PasskeyChallengeError,
|
|
42
46
|
PasskeyConfigError: () => PasskeyConfigError,
|
|
@@ -409,6 +413,44 @@ var PasskeyConfigError = class extends HttpError {
|
|
|
409
413
|
this.name = "PasskeyConfigError";
|
|
410
414
|
}
|
|
411
415
|
};
|
|
416
|
+
var OAuth2UnknownClientError = class extends ValidationError {
|
|
417
|
+
constructor(data = {}) {
|
|
418
|
+
super({
|
|
419
|
+
message: data.message || "Unknown OAuth client",
|
|
420
|
+
details: { error: "unknown_client", ...data.details }
|
|
421
|
+
});
|
|
422
|
+
this.name = "OAuth2UnknownClientError";
|
|
423
|
+
}
|
|
424
|
+
};
|
|
425
|
+
var OAuth2RedirectUriMismatchError = class extends ValidationError {
|
|
426
|
+
constructor(data = {}) {
|
|
427
|
+
super({
|
|
428
|
+
message: data.message || "redirect_uri does not match a registered URI for this client",
|
|
429
|
+
details: { error: "redirect_uri_mismatch", ...data.details }
|
|
430
|
+
});
|
|
431
|
+
this.name = "OAuth2RedirectUriMismatchError";
|
|
432
|
+
}
|
|
433
|
+
};
|
|
434
|
+
var OAuth2AuthorizeRedirectError = class extends ValidationError {
|
|
435
|
+
constructor(data) {
|
|
436
|
+
super({
|
|
437
|
+
message: data.message || `OAuth authorize request refused: ${data.error}`,
|
|
438
|
+
details: {
|
|
439
|
+
error: data.error,
|
|
440
|
+
redirectUri: data.redirectUri,
|
|
441
|
+
state: data.state,
|
|
442
|
+
...data.details
|
|
443
|
+
}
|
|
444
|
+
});
|
|
445
|
+
this.name = "OAuth2AuthorizeRedirectError";
|
|
446
|
+
}
|
|
447
|
+
};
|
|
448
|
+
var OAuth2GrantNotFoundError = class extends NotFoundError {
|
|
449
|
+
constructor(data = {}) {
|
|
450
|
+
super({ message: data.message || "No such connected application", details: data.details });
|
|
451
|
+
this.name = "OAuth2GrantNotFoundError";
|
|
452
|
+
}
|
|
453
|
+
};
|
|
412
454
|
|
|
413
455
|
// src/errors/index.ts
|
|
414
456
|
var authErrorRegistry = new ErrorRegistry();
|
|
@@ -454,7 +496,11 @@ authErrorRegistry.append([
|
|
|
454
496
|
PasskeyAlreadyRegisteredError,
|
|
455
497
|
RecentAuthenticationRequiredError,
|
|
456
498
|
LastRecoveryCredentialError,
|
|
457
|
-
PasskeyConfigError
|
|
499
|
+
PasskeyConfigError,
|
|
500
|
+
OAuth2UnknownClientError,
|
|
501
|
+
OAuth2RedirectUriMismatchError,
|
|
502
|
+
OAuth2AuthorizeRedirectError,
|
|
503
|
+
OAuth2GrantNotFoundError
|
|
458
504
|
]);
|
|
459
505
|
export {
|
|
460
506
|
AccountAlreadyExistsError,
|
|
@@ -485,6 +531,10 @@ export {
|
|
|
485
531
|
LastRecoveryCredentialError,
|
|
486
532
|
NativeSignInUnsupportedError,
|
|
487
533
|
NonceKeyBindingError,
|
|
534
|
+
OAuth2AuthorizeRedirectError,
|
|
535
|
+
OAuth2GrantNotFoundError,
|
|
536
|
+
OAuth2RedirectUriMismatchError,
|
|
537
|
+
OAuth2UnknownClientError,
|
|
488
538
|
PasskeyAlreadyRegisteredError,
|
|
489
539
|
PasskeyChallengeError,
|
|
490
540
|
PasskeyConfigError,
|
package/dist/errors.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/errors/index.ts","../src/errors/auth-errors.ts"],"sourcesContent":["/**\n * Auth Error Exports\n */\n\nimport { ErrorRegistry } from '@spfn/core/errors';\n\nimport {\n InvalidCredentialsError,\n InvalidTokenError,\n InvalidSocialTokenError,\n TokenExpiredError,\n KeyExpiredError,\n AccountDisabledError,\n AccountPendingDeletionError,\n DeletionAlreadyRequestedError,\n DeletionNotRequestedError,\n ImmediateDeletionNotAllowedError,\n AccountAlreadyExistsError,\n RegistrationRejectedError,\n ReservedUsernameError,\n UsernameAlreadyTakenError,\n InvalidVerificationCodeError,\n InvalidVerificationTokenError,\n InvalidKeyFingerprintError,\n KeyAlgorithmMismatchError,\n NonceKeyBindingError,\n NativeSignInUnsupportedError,\n UnverifiedEmailLinkError,\n InvalidSignupLinkError,\n InvalidSignupSetupSessionError,\n PasswordResetLinkError,\n PasswordResetSessionError,\n KeyNotFoundError,\n KeyIdAlreadyRegisteredError,\n DeviceAuthNotFoundError,\n DeviceAuthExpiredError,\n DeviceAuthAlreadyHandledError,\n DeviceAuthDeniedError,\n VerificationTokenPurposeMismatchError,\n VerificationTokenTargetMismatchError,\n InsufficientPermissionsError,\n InsufficientRoleError,\n PasskeyChallengeError,\n PasskeyVerificationError,\n PasskeyNotFoundError,\n PasskeyAlreadyRegisteredError,\n RecentAuthenticationRequiredError,\n LastRecoveryCredentialError,\n PasskeyConfigError,\n} from './auth-errors';\n\nexport {\n InvalidCredentialsError,\n InvalidTokenError,\n InvalidSocialTokenError,\n TokenExpiredError,\n KeyExpiredError,\n AccountDisabledError,\n AccountPendingDeletionError,\n DeletionAlreadyRequestedError,\n DeletionNotRequestedError,\n ImmediateDeletionNotAllowedError,\n AccountAlreadyExistsError,\n RegistrationRejectedError,\n ReservedUsernameError,\n UsernameAlreadyTakenError,\n InvalidVerificationCodeError,\n InvalidVerificationTokenError,\n InvalidKeyFingerprintError,\n KeyAlgorithmMismatchError,\n NonceKeyBindingError,\n NativeSignInUnsupportedError,\n UnverifiedEmailLinkError,\n InvalidSignupLinkError,\n InvalidSignupSetupSessionError,\n PasswordResetLinkError,\n PasswordResetSessionError,\n KeyNotFoundError,\n KeyIdAlreadyRegisteredError,\n DeviceAuthNotFoundError,\n DeviceAuthExpiredError,\n DeviceAuthAlreadyHandledError,\n DeviceAuthDeniedError,\n VerificationTokenPurposeMismatchError,\n VerificationTokenTargetMismatchError,\n InsufficientPermissionsError,\n InsufficientRoleError,\n PasskeyChallengeError,\n PasskeyVerificationError,\n PasskeyNotFoundError,\n PasskeyAlreadyRegisteredError,\n RecentAuthenticationRequiredError,\n LastRecoveryCredentialError,\n PasskeyConfigError,\n} from './auth-errors';\n\nexport const authErrorRegistry = new ErrorRegistry();\nauthErrorRegistry.append([\n InvalidCredentialsError,\n InvalidTokenError,\n InvalidSocialTokenError,\n TokenExpiredError,\n KeyExpiredError,\n AccountDisabledError,\n AccountPendingDeletionError,\n DeletionAlreadyRequestedError,\n DeletionNotRequestedError,\n ImmediateDeletionNotAllowedError,\n AccountAlreadyExistsError,\n RegistrationRejectedError,\n ReservedUsernameError,\n UsernameAlreadyTakenError,\n InvalidVerificationCodeError,\n InvalidVerificationTokenError,\n InvalidKeyFingerprintError,\n KeyAlgorithmMismatchError,\n NonceKeyBindingError,\n NativeSignInUnsupportedError,\n UnverifiedEmailLinkError,\n InvalidSignupLinkError,\n InvalidSignupSetupSessionError,\n PasswordResetLinkError,\n PasswordResetSessionError,\n KeyNotFoundError,\n KeyIdAlreadyRegisteredError,\n DeviceAuthNotFoundError,\n DeviceAuthExpiredError,\n DeviceAuthAlreadyHandledError,\n DeviceAuthDeniedError,\n VerificationTokenPurposeMismatchError,\n VerificationTokenTargetMismatchError,\n InsufficientPermissionsError,\n InsufficientRoleError,\n PasskeyChallengeError,\n PasskeyVerificationError,\n PasskeyNotFoundError,\n PasskeyAlreadyRegisteredError,\n RecentAuthenticationRequiredError,\n LastRecoveryCredentialError,\n PasskeyConfigError,\n]);\n\nexport * as AuthError from './auth-errors';\n","/**\n * Authentication & Authorization Error Classes\n *\n * Custom error classes for auth-specific scenarios\n */\n\nimport {\n ValidationError,\n UnauthorizedError,\n ForbiddenError,\n ConflictError,\n NotFoundError,\n HttpError,\n} from '@spfn/core/errors';\n\n/**\n * Invalid Credentials Error (401)\n *\n * Thrown when login credentials are incorrect\n */\nexport class InvalidCredentialsError extends UnauthorizedError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({ message: data.message || 'Invalid credentials', details: data.details });\n this.name = 'InvalidCredentialsError';\n }\n}\n\n/**\n * Invalid Token Error (401)\n *\n * Thrown when authentication token is invalid or malformed\n */\nexport class InvalidTokenError extends UnauthorizedError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({ message: data.message || 'Invalid authentication token', details: data.details });\n this.name = 'InvalidTokenError';\n }\n}\n\n/**\n * Invalid Social Token Error (401)\n *\n * Thrown when a social provider id_token fails verification\n * (bad signature, wrong issuer/audience, expired, or nonce mismatch).\n */\nexport class InvalidSocialTokenError extends UnauthorizedError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({ message: data.message || 'Invalid social id_token', details: data.details });\n this.name = 'InvalidSocialTokenError';\n }\n}\n\n/**\n * Token Expired Error (401)\n *\n * Thrown when authentication token has expired\n */\nexport class TokenExpiredError extends UnauthorizedError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({ message: data.message || 'Authentication token has expired', details: data.details });\n this.name = 'TokenExpiredError';\n }\n}\n\n/**\n * Key Expired Error (401)\n *\n * Thrown when public key has expired\n */\nexport class KeyExpiredError extends UnauthorizedError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({ message: data.message || 'Public key has expired', details: data.details });\n this.name = 'KeyExpiredError';\n }\n}\n\n/**\n * Account Disabled Error (403)\n *\n * Thrown when user account is disabled or inactive\n */\nexport class AccountDisabledError extends ForbiddenError\n{\n constructor(data: { status?: string; message?: string; details?: Record<string, any> } = {})\n {\n const status = data.status || 'disabled';\n super({\n message: data.message || `Account is ${status}`,\n details: { status, ...data.details },\n });\n this.name = 'AccountDisabledError';\n }\n}\n\n/**\n * Account Pending Deletion Error (403)\n *\n * Thrown on login (password/OAuth/authenticate) when the account is within its\n * deletion grace period. Carries `purgeScheduledAt` so the client can offer a\n * recovery flow instead of a generic \"disabled\" message.\n */\nexport class AccountPendingDeletionError extends ForbiddenError\n{\n constructor(data: { purgeScheduledAt?: string; message?: string; details?: Record<string, any> } = {})\n {\n super({\n message: data.message || 'Account is scheduled for deletion',\n details: { status: 'pending_deletion', purgeScheduledAt: data.purgeScheduledAt, ...data.details },\n });\n this.name = 'AccountPendingDeletionError';\n }\n}\n\n/**\n * Deletion Already Requested Error (409)\n *\n * Thrown when requesting deletion for an account that already has a pending\n * deletion request (or has already been purged).\n */\nexport class DeletionAlreadyRequestedError extends ConflictError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({ message: data.message || 'Account deletion has already been requested', details: data.details });\n this.name = 'DeletionAlreadyRequestedError';\n }\n}\n\n/**\n * Deletion Not Requested Error (404)\n *\n * Thrown when trying to cancel/purge a deletion for an account that has no\n * pending deletion request.\n */\nexport class DeletionNotRequestedError extends NotFoundError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({ message: data.message || 'No pending account deletion request found', details: data.details });\n this.name = 'DeletionNotRequestedError';\n }\n}\n\n/**\n * Immediate Deletion Not Allowed Error (403)\n *\n * Thrown when a self-service caller requests `immediate: true` but the server\n * has not enabled `deletion.allowSelfImmediate`.\n */\nexport class ImmediateDeletionNotAllowedError extends ForbiddenError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({ message: data.message || 'Immediate self-service deletion is not enabled', details: data.details });\n this.name = 'ImmediateDeletionNotAllowedError';\n }\n}\n\n/**\n * Account Already Exists Error (409)\n *\n * Thrown when trying to register with existing email/phone\n */\nexport class AccountAlreadyExistsError extends ConflictError\n{\n constructor(data: { identifier?: string; identifierType?: 'email' | 'phone'; message?: string; details?: Record<string, any> } = {})\n {\n super({\n message: data.message || 'Account already exists',\n details: {\n identifier: data.identifier,\n identifierType: data.identifierType,\n ...data.details,\n },\n });\n this.name = 'AccountAlreadyExistsError';\n }\n}\n\n/**\n * Registration Rejected Error (403)\n *\n * Thrown by the app-injected beforeRegister hook to reject a registration\n * (age gate, domain restriction, block list, ...)\n */\nexport class RegistrationRejectedError extends ForbiddenError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({ message: data.message || 'Registration rejected', details: data.details });\n this.name = 'RegistrationRejectedError';\n }\n}\n\n/**\n * Invalid Verification Code Error (400)\n *\n * Thrown when verification code is invalid, expired, or already used\n */\nexport class InvalidVerificationCodeError extends ValidationError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({ message: data.message || 'Invalid verification code', details: data.details });\n this.name = 'InvalidVerificationCodeError';\n }\n}\n\n/**\n * Invalid Verification Token Error (400)\n *\n * Thrown when verification token is invalid or expired\n */\nexport class InvalidVerificationTokenError extends ValidationError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({ message: data.message || 'Invalid or expired verification token', details: data.details });\n this.name = 'InvalidVerificationTokenError';\n }\n}\n\n/**\n * Key ID Already Registered Error (409)\n *\n * Thrown when a sign-in submits a keyId that is already taken — the client's own\n * revoked keyId, or a keyId belonging to another user. `keyId` is unique across\n * all users, so either case would collide on insert.\n *\n * The same error covers both cases on purpose: a distinguishable response would\n * let a caller probe whether an arbitrary keyId exists. Revoked stays revoked —\n * the client must generate a fresh keyId and retry.\n */\nexport class KeyIdAlreadyRegisteredError extends ConflictError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({\n message: data.message || 'This keyId is already registered. Generate a new keyId and retry.',\n details: data.details,\n });\n this.name = 'KeyIdAlreadyRegisteredError';\n }\n}\n\n/**\n * Invalid Key Fingerprint Error (400)\n *\n * Thrown when public key fingerprint doesn't match the public key\n */\nexport class InvalidKeyFingerprintError extends ValidationError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({ message: data.message || 'Invalid key fingerprint', details: data.details });\n this.name = 'InvalidKeyFingerprintError';\n }\n}\n\n/**\n * Key Algorithm Mismatch Error (400)\n *\n * Thrown when the submitted public key's SPKI type is not the one its declared\n * algorithm needs — a P-256 EC key declared RS256, an RSA key declared ES256, a\n * curve other than P-256 declared ES256, or bytes that are no SPKI key at all.\n *\n * The algorithm is stored beside the key and read back at proof verification;\n * nothing re-derives it from the key material. So a mismatch accepted here\n * surfaces only after the device believes it is enrolled, on every request it\n * then makes. It is refused at registration instead, wherever key material is\n * stored: register, login, rotate, invitation acceptance and device start.\n */\nexport class KeyAlgorithmMismatchError extends ValidationError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({\n message: data.message || 'Public key type does not match the declared algorithm',\n details: data.details,\n });\n this.name = 'KeyAlgorithmMismatchError';\n }\n}\n\n/**\n * Key Not Found Error (404)\n *\n * Thrown when a key operation names a keyId the caller does not own. It says\n * nothing about whether that keyId exists on another account — the repository\n * scopes every lookup by userId, so the answer is only ever \"not yours\".\n */\nexport class KeyNotFoundError extends NotFoundError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({ message: data.message || 'Key not found', details: data.details });\n this.name = 'KeyNotFoundError';\n }\n}\n\n/**\n * Device Auth Not Found Error (404)\n *\n * Thrown when a device-code operation names a code the server cannot act on: one\n * that was never issued, and one whose record has already been consumed.\n *\n * Those two are answered identically on purpose. A consumed record is a login\n * that finished, and saying so would tell whoever holds the code that it was\n * real — which is the difference between guessing at random and knowing a guess\n * landed. Every route that accepts a code is rate limited for the same reason.\n */\nexport class DeviceAuthNotFoundError extends NotFoundError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({ message: data.message || 'Device authorization not found', details: data.details });\n this.name = 'DeviceAuthNotFoundError';\n }\n}\n\n/**\n * Device Auth Expired Error (400)\n *\n * Thrown when a device-code operation names a record whose TTL has run out,\n * whatever state it is in. The waiting device starts again; the approver is told\n * the code on the other screen is stale.\n *\n * 400 rather than 401: on the approve and deny routes the caller's own session is\n * fine, and answering 401 would send a signed-in user to a login screen over a\n * code that simply sat too long.\n */\nexport class DeviceAuthExpiredError extends ValidationError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({\n message: data.message || 'This device code has expired. Start again on the other device.',\n details: data.details,\n });\n this.name = 'DeviceAuthExpiredError';\n }\n}\n\n/**\n * Device Auth Already Handled Error (409)\n *\n * Thrown when an approve, deny or info call names a record that has already been\n * approved or denied. A decision on a device is made once — a second approval\n * would let one code be answered twice, and re-approving a record the owner\n * denied would undo the refusal.\n *\n * This is also what the loser of two concurrent approvals sees, since the\n * transition names the state it moves from and only one call can match it.\n */\nexport class DeviceAuthAlreadyHandledError extends ConflictError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({\n message: data.message || 'This device request has already been answered',\n details: data.details,\n });\n this.name = 'DeviceAuthAlreadyHandledError';\n }\n}\n\n/**\n * Device Auth Denied Error (403)\n *\n * Thrown when the waiting device polls a record its owner refused. Distinct from\n * a pending answer, and distinct from a code that does not exist: the device\n * asked a person and the person said no, so it should stop polling and say so\n * rather than time out looking like a network fault.\n */\nexport class DeviceAuthDeniedError extends ForbiddenError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({\n message: data.message || 'This device request was denied',\n details: data.details,\n });\n this.name = 'DeviceAuthDeniedError';\n }\n}\n\n/**\n * Nonce Key Binding Error (400)\n *\n * Thrown when a native id_token sign-in submits a nonce that is not the public\n * key's fingerprint. The nonce is what the provider echoed back inside the\n * id_token, so tying it to the key is what proves the id_token and the key came\n * from the same device — see the native section of the README.\n */\nexport class NonceKeyBindingError extends ValidationError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({\n message: data.message || 'nonce must be the fingerprint of the submitted public key',\n details: data.details,\n });\n this.name = 'NonceKeyBindingError';\n }\n}\n\n/**\n * Native Sign-In Unsupported Error (400)\n *\n * Thrown when a provider is asked for native id_token sign-in and has no\n * implementation for it — a server configuration fact, not something the user\n * did. A client reading this hides that provider's native button instead of\n * asking the user to try again.\n *\n * Split out of ValidationError because the other native-enrollment refusal\n * (linking to an account whose email the provider never verified) needs a\n * different response from the app, and one code cannot ask for two.\n */\nexport class NativeSignInUnsupportedError extends ValidationError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({\n message: data.message || 'This provider does not support native id_token sign-in.',\n details: data.details,\n });\n this.name = 'NativeSignInUnsupportedError';\n }\n}\n\n/**\n * Invalid Signup Link Error (400)\n *\n * Thrown when an emailed signup confirmation link is unknown, expired, already\n * consumed, or superseded by a newer request for the same address.\n *\n * One error for all four states, on purpose. Distinguishing \"expired\" from\n * \"unknown\" tells a caller holding a random token whether it named a real\n * pending signup, which is exactly the enumeration the request step avoids. The\n * specific reason is logged.\n */\nexport class InvalidSignupLinkError extends ValidationError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({\n message: data.message || 'This signup link is no longer valid. Request a new one.',\n details: data.details,\n });\n this.name = 'InvalidSignupLinkError';\n }\n}\n\n/**\n * Invalid Signup Setup Session Error (401)\n *\n * Thrown when the password-setup session backing a verified-email signup is\n * missing, unknown, expired, superseded or already used.\n *\n * One error for every one of those, on purpose: telling a caller which of them\n * applies tells them whether an address is mid-signup, which is the same\n * enumeration the request step is careful not to leak.\n */\nexport class InvalidSignupSetupSessionError extends UnauthorizedError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({\n message: data.message || 'Password setup session is invalid or has expired. Start the signup again.',\n details: data.details,\n });\n this.name = 'InvalidSignupSetupSessionError';\n }\n}\n\n/**\n * Password Reset Link Error (401)\n *\n * Thrown when an emailed password reset link is unknown, expired, already\n * consumed, superseded by a newer request, or belongs to an account that is no\n * longer active.\n *\n * One error for every one of those, on purpose. Distinguishing \"expired\" from\n * \"unknown\" tells a caller holding a random token whether it named a real\n * pending reset, which is exactly the enumeration the request step avoids. The\n * specific reason is logged.\n */\nexport class PasswordResetLinkError extends UnauthorizedError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({\n message: data.message || 'This password reset link is no longer valid. Request a new one.',\n details: data.details,\n });\n this.name = 'PasswordResetLinkError';\n }\n}\n\n/**\n * Password Reset Session Error (401)\n *\n * Thrown when the password-setup session backing a reset is missing, unknown,\n * expired, superseded or already used.\n *\n * One error for every one of those, for the same reason the link error is one\n * error: which of them applies tells a caller whether an account is mid-reset,\n * and that is the enumeration the request step is careful not to leak.\n */\nexport class PasswordResetSessionError extends UnauthorizedError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({\n message: data.message || 'Password reset session is invalid or has expired. Request a new link.',\n details: data.details,\n });\n this.name = 'PasswordResetSessionError';\n }\n}\n\n/**\n * Unverified Email Link Error (400)\n *\n * Thrown when a social identity carries an email that already belongs to an\n * account, but the provider never verified it. Linking on an unverified email\n * is account takeover, so the refusal stands and the user is sent to a path\n * that proves the address.\n *\n * This says an account exists for that address. It is not a leak introduced\n * here: the message this replaces already stated the same fact in prose, and\n * the paths that must not disclose account existence (password login, deletion\n * re-auth, verification issuance) answer uniformly and are untouched.\n */\nexport class UnverifiedEmailLinkError extends ValidationError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({\n message: data.message\n || 'Cannot link to existing account with unverified email. Please verify your email with the provider first.',\n details: data.details,\n });\n this.name = 'UnverifiedEmailLinkError';\n }\n}\n\n/**\n * Verification Token Purpose Mismatch Error (400)\n *\n * Thrown when verification token purpose doesn't match expected purpose\n */\nexport class VerificationTokenPurposeMismatchError extends ValidationError\n{\n constructor(data: { expected?: string; actual?: string; message?: string; details?: Record<string, any> } = {})\n {\n const expected = data.expected || 'unknown';\n const actual = data.actual || 'unknown';\n super({\n message: data.message || `Verification token is for ${actual}, but ${expected} was expected`,\n details: { expected, actual, ...data.details },\n });\n this.name = 'VerificationTokenPurposeMismatchError';\n }\n}\n\n/**\n * Verification Token Target Mismatch Error (400)\n *\n * Thrown when verification token target doesn't match provided email/phone\n */\nexport class VerificationTokenTargetMismatchError extends ValidationError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({\n message: data.message || 'Verification token does not match provided email/phone',\n details: data.details,\n });\n this.name = 'VerificationTokenTargetMismatchError';\n }\n}\n\n/**\n * Reserved Username Error (400)\n *\n * Thrown when trying to use a reserved/prohibited username\n */\nexport class ReservedUsernameError extends ValidationError\n{\n constructor(data: { username?: string; message?: string; details?: Record<string, any> } = {})\n {\n super({\n message: data.message || 'This username is reserved',\n details: { username: data.username, ...data.details },\n });\n this.name = 'ReservedUsernameError';\n }\n}\n\n/**\n * Username Already Taken Error (409)\n *\n * Thrown when trying to set a username that is already in use\n */\nexport class UsernameAlreadyTakenError extends ConflictError\n{\n constructor(data: { username?: string; message?: string; details?: Record<string, any> } = {})\n {\n super({\n message: data.message || 'Username is already taken',\n details: { username: data.username, ...data.details },\n });\n this.name = 'UsernameAlreadyTakenError';\n }\n}\n\n/**\n * Insufficient Permissions Error (403)\n *\n * Thrown when user lacks required permissions for the operation\n */\nexport class InsufficientPermissionsError extends ForbiddenError\n{\n constructor(data: { requiredPermissions?: string[]; message?: string; details?: Record<string, any> } = {})\n {\n const requiredPermissions = data.requiredPermissions || [];\n super({\n message: data.message || `Missing required permissions: ${requiredPermissions.join(', ')}`,\n details: { requiredPermissions, ...data.details },\n });\n this.name = 'InsufficientPermissionsError';\n }\n}\n\n/**\n * Insufficient Role Error (403)\n *\n * Thrown when user lacks required role for the operation\n */\nexport class InsufficientRoleError extends ForbiddenError\n{\n constructor(data: { requiredRoles?: string[]; message?: string; details?: Record<string, any> } = {})\n {\n const requiredRoles = data.requiredRoles || [];\n super({\n message: data.message || `Required roles: ${requiredRoles.join(', ')}`,\n details: { requiredRoles, ...data.details },\n });\n this.name = 'InsufficientRoleError';\n }\n}\n\n/**\n * Passkey Challenge Error (401)\n *\n * Thrown when the challenge a WebAuthn ceremony presents is unknown, expired,\n * already spent, minted for the other ceremony, or minted for another account.\n *\n * One error for all five, on purpose. Telling a caller which applies tells them\n * whether a challenge they did not mint exists and what it was for, and the\n * remedy is the same in every case: start the ceremony again.\n */\nexport class PasskeyChallengeError extends UnauthorizedError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({\n message: data.message || 'This passkey challenge is no longer valid. Try again.',\n details: data.details,\n });\n this.name = 'PasskeyChallengeError';\n }\n}\n\n/**\n * Passkey Verification Error (401)\n *\n * Thrown when an assertion or attestation does not verify: wrong origin, wrong\n * rpId, a bad signature, a regressed signature counter — or, on login, a\n * credential that is unknown or has been revoked.\n *\n * Those last two share this error with the cryptographic failures deliberately.\n * A distinct \"no such passkey\" would answer, to anyone holding a credential id,\n * whether it is enrolled here — and a revoked credential answering differently\n * from an unknown one would say the account once had it.\n */\nexport class PasskeyVerificationError extends UnauthorizedError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({\n message: data.message || 'Passkey verification failed.',\n details: data.details,\n });\n this.name = 'PasskeyVerificationError';\n }\n}\n\n/**\n * Passkey Not Found Error (404)\n *\n * Thrown when a management operation names a passkey the caller does not own,\n * or one already revoked. Every lookup is owner-scoped, so the answer is only\n * ever \"not yours\" and says nothing about other accounts.\n */\nexport class PasskeyNotFoundError extends NotFoundError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({\n message: data.message || 'Passkey not found',\n details: data.details,\n });\n this.name = 'PasskeyNotFoundError';\n }\n}\n\n/**\n * Passkey Already Registered Error (409)\n *\n * Thrown when the credential presented for enrollment is already on file for\n * some account — including one that revoked it. A credential id is reserved for\n * good once used, so this is also the answer to re-enrolling one's own revoked\n * passkey.\n */\nexport class PasskeyAlreadyRegisteredError extends ConflictError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({\n message: data.message || 'This passkey is already registered',\n details: data.details,\n });\n this.name = 'PasskeyAlreadyRegisteredError';\n }\n}\n\n/**\n * Recent Authentication Required Error (403)\n *\n * Thrown when enrolling or revoking a passkey from a session that proved itself\n * too long ago and carried no password. Clients branch on `code` to know to\n * prompt for the password rather than to show a generic refusal, so the code is\n * a stable field rather than a message they would have to match on.\n */\nexport class RecentAuthenticationRequiredError extends ForbiddenError\n{\n readonly code = 'RECENT_AUTH_REQUIRED';\n\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({\n message: data.message || 'Confirm it is you before changing passkeys. Sign in again or send your current password.',\n details: data.details,\n });\n this.name = 'RecentAuthenticationRequiredError';\n }\n}\n\n/**\n * Last Recovery Credential Error (409)\n *\n * Thrown when revoking a passkey would leave the account with no way back in:\n * no other live passkey, no password, and no linked social account. There is no\n * password reset in this package, so that state is not recoverable by support\n * either — the refusal is the only thing standing between the owner and a\n * locked account.\n *\n * Clients branch on `code` to offer \"set a password first\" instead of a generic\n * refusal.\n */\nexport class LastRecoveryCredentialError extends ConflictError\n{\n readonly code = 'LAST_RECOVERY_CREDENTIAL';\n\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({\n message: data.message\n || 'This is the only way you can sign in. Set a password or link a social account before removing it.',\n details: data.details,\n });\n this.name = 'LastRecoveryCredentialError';\n }\n}\n\n/**\n * Passkey Config Error (500)\n *\n * Thrown at boot when the passkey relying-party configuration cannot be honoured\n * — an origin that is not https outside localhost, an origin off the rpId, an\n * unsupported user-verification value.\n *\n * A refusal at boot rather than at the first ceremony: every one of these makes\n * every passkey operation fail, and the drift is between environments, so the\n * deploy that introduces it is where it has to surface.\n */\nexport class PasskeyConfigError extends HttpError\n{\n constructor(data: { message: string; details?: Record<string, any> })\n {\n super({\n message: data.message,\n statusCode: 500,\n details: data.details,\n });\n this.name = 'PasskeyConfigError';\n }\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/errors/index.ts","../src/errors/auth-errors.ts"],"sourcesContent":["/**\n * Auth Error Exports\n */\n\nimport { ErrorRegistry } from '@spfn/core/errors';\n\nimport {\n InvalidCredentialsError,\n InvalidTokenError,\n InvalidSocialTokenError,\n TokenExpiredError,\n KeyExpiredError,\n AccountDisabledError,\n AccountPendingDeletionError,\n DeletionAlreadyRequestedError,\n DeletionNotRequestedError,\n ImmediateDeletionNotAllowedError,\n AccountAlreadyExistsError,\n RegistrationRejectedError,\n ReservedUsernameError,\n UsernameAlreadyTakenError,\n InvalidVerificationCodeError,\n InvalidVerificationTokenError,\n InvalidKeyFingerprintError,\n KeyAlgorithmMismatchError,\n NonceKeyBindingError,\n NativeSignInUnsupportedError,\n UnverifiedEmailLinkError,\n InvalidSignupLinkError,\n InvalidSignupSetupSessionError,\n PasswordResetLinkError,\n PasswordResetSessionError,\n KeyNotFoundError,\n KeyIdAlreadyRegisteredError,\n DeviceAuthNotFoundError,\n DeviceAuthExpiredError,\n DeviceAuthAlreadyHandledError,\n DeviceAuthDeniedError,\n VerificationTokenPurposeMismatchError,\n VerificationTokenTargetMismatchError,\n InsufficientPermissionsError,\n InsufficientRoleError,\n PasskeyChallengeError,\n PasskeyVerificationError,\n PasskeyNotFoundError,\n PasskeyAlreadyRegisteredError,\n RecentAuthenticationRequiredError,\n LastRecoveryCredentialError,\n PasskeyConfigError,\n OAuth2UnknownClientError,\n OAuth2RedirectUriMismatchError,\n OAuth2AuthorizeRedirectError,\n OAuth2GrantNotFoundError,\n} from './auth-errors';\n\nexport {\n InvalidCredentialsError,\n InvalidTokenError,\n InvalidSocialTokenError,\n TokenExpiredError,\n KeyExpiredError,\n AccountDisabledError,\n AccountPendingDeletionError,\n DeletionAlreadyRequestedError,\n DeletionNotRequestedError,\n ImmediateDeletionNotAllowedError,\n AccountAlreadyExistsError,\n RegistrationRejectedError,\n ReservedUsernameError,\n UsernameAlreadyTakenError,\n InvalidVerificationCodeError,\n InvalidVerificationTokenError,\n InvalidKeyFingerprintError,\n KeyAlgorithmMismatchError,\n NonceKeyBindingError,\n NativeSignInUnsupportedError,\n UnverifiedEmailLinkError,\n InvalidSignupLinkError,\n InvalidSignupSetupSessionError,\n PasswordResetLinkError,\n PasswordResetSessionError,\n KeyNotFoundError,\n KeyIdAlreadyRegisteredError,\n DeviceAuthNotFoundError,\n DeviceAuthExpiredError,\n DeviceAuthAlreadyHandledError,\n DeviceAuthDeniedError,\n VerificationTokenPurposeMismatchError,\n VerificationTokenTargetMismatchError,\n InsufficientPermissionsError,\n InsufficientRoleError,\n PasskeyChallengeError,\n PasskeyVerificationError,\n PasskeyNotFoundError,\n PasskeyAlreadyRegisteredError,\n RecentAuthenticationRequiredError,\n LastRecoveryCredentialError,\n PasskeyConfigError,\n OAuth2UnknownClientError,\n OAuth2RedirectUriMismatchError,\n OAuth2AuthorizeRedirectError,\n OAuth2GrantNotFoundError,\n} from './auth-errors';\n\nexport const authErrorRegistry = new ErrorRegistry();\nauthErrorRegistry.append([\n InvalidCredentialsError,\n InvalidTokenError,\n InvalidSocialTokenError,\n TokenExpiredError,\n KeyExpiredError,\n AccountDisabledError,\n AccountPendingDeletionError,\n DeletionAlreadyRequestedError,\n DeletionNotRequestedError,\n ImmediateDeletionNotAllowedError,\n AccountAlreadyExistsError,\n RegistrationRejectedError,\n ReservedUsernameError,\n UsernameAlreadyTakenError,\n InvalidVerificationCodeError,\n InvalidVerificationTokenError,\n InvalidKeyFingerprintError,\n KeyAlgorithmMismatchError,\n NonceKeyBindingError,\n NativeSignInUnsupportedError,\n UnverifiedEmailLinkError,\n InvalidSignupLinkError,\n InvalidSignupSetupSessionError,\n PasswordResetLinkError,\n PasswordResetSessionError,\n KeyNotFoundError,\n KeyIdAlreadyRegisteredError,\n DeviceAuthNotFoundError,\n DeviceAuthExpiredError,\n DeviceAuthAlreadyHandledError,\n DeviceAuthDeniedError,\n VerificationTokenPurposeMismatchError,\n VerificationTokenTargetMismatchError,\n InsufficientPermissionsError,\n InsufficientRoleError,\n PasskeyChallengeError,\n PasskeyVerificationError,\n PasskeyNotFoundError,\n PasskeyAlreadyRegisteredError,\n RecentAuthenticationRequiredError,\n LastRecoveryCredentialError,\n PasskeyConfigError,\n OAuth2UnknownClientError,\n OAuth2RedirectUriMismatchError,\n OAuth2AuthorizeRedirectError,\n OAuth2GrantNotFoundError,\n]);\n\nexport * as AuthError from './auth-errors';\n","/**\n * Authentication & Authorization Error Classes\n *\n * Custom error classes for auth-specific scenarios\n */\n\nimport {\n ValidationError,\n UnauthorizedError,\n ForbiddenError,\n ConflictError,\n NotFoundError,\n HttpError,\n} from '@spfn/core/errors';\n\n/**\n * Invalid Credentials Error (401)\n *\n * Thrown when login credentials are incorrect\n */\nexport class InvalidCredentialsError extends UnauthorizedError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({ message: data.message || 'Invalid credentials', details: data.details });\n this.name = 'InvalidCredentialsError';\n }\n}\n\n/**\n * Invalid Token Error (401)\n *\n * Thrown when authentication token is invalid or malformed\n */\nexport class InvalidTokenError extends UnauthorizedError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({ message: data.message || 'Invalid authentication token', details: data.details });\n this.name = 'InvalidTokenError';\n }\n}\n\n/**\n * Invalid Social Token Error (401)\n *\n * Thrown when a social provider id_token fails verification\n * (bad signature, wrong issuer/audience, expired, or nonce mismatch).\n */\nexport class InvalidSocialTokenError extends UnauthorizedError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({ message: data.message || 'Invalid social id_token', details: data.details });\n this.name = 'InvalidSocialTokenError';\n }\n}\n\n/**\n * Token Expired Error (401)\n *\n * Thrown when authentication token has expired\n */\nexport class TokenExpiredError extends UnauthorizedError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({ message: data.message || 'Authentication token has expired', details: data.details });\n this.name = 'TokenExpiredError';\n }\n}\n\n/**\n * Key Expired Error (401)\n *\n * Thrown when public key has expired\n */\nexport class KeyExpiredError extends UnauthorizedError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({ message: data.message || 'Public key has expired', details: data.details });\n this.name = 'KeyExpiredError';\n }\n}\n\n/**\n * Account Disabled Error (403)\n *\n * Thrown when user account is disabled or inactive\n */\nexport class AccountDisabledError extends ForbiddenError\n{\n constructor(data: { status?: string; message?: string; details?: Record<string, any> } = {})\n {\n const status = data.status || 'disabled';\n super({\n message: data.message || `Account is ${status}`,\n details: { status, ...data.details },\n });\n this.name = 'AccountDisabledError';\n }\n}\n\n/**\n * Account Pending Deletion Error (403)\n *\n * Thrown on login (password/OAuth/authenticate) when the account is within its\n * deletion grace period. Carries `purgeScheduledAt` so the client can offer a\n * recovery flow instead of a generic \"disabled\" message.\n */\nexport class AccountPendingDeletionError extends ForbiddenError\n{\n constructor(data: { purgeScheduledAt?: string; message?: string; details?: Record<string, any> } = {})\n {\n super({\n message: data.message || 'Account is scheduled for deletion',\n details: { status: 'pending_deletion', purgeScheduledAt: data.purgeScheduledAt, ...data.details },\n });\n this.name = 'AccountPendingDeletionError';\n }\n}\n\n/**\n * Deletion Already Requested Error (409)\n *\n * Thrown when requesting deletion for an account that already has a pending\n * deletion request (or has already been purged).\n */\nexport class DeletionAlreadyRequestedError extends ConflictError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({ message: data.message || 'Account deletion has already been requested', details: data.details });\n this.name = 'DeletionAlreadyRequestedError';\n }\n}\n\n/**\n * Deletion Not Requested Error (404)\n *\n * Thrown when trying to cancel/purge a deletion for an account that has no\n * pending deletion request.\n */\nexport class DeletionNotRequestedError extends NotFoundError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({ message: data.message || 'No pending account deletion request found', details: data.details });\n this.name = 'DeletionNotRequestedError';\n }\n}\n\n/**\n * Immediate Deletion Not Allowed Error (403)\n *\n * Thrown when a self-service caller requests `immediate: true` but the server\n * has not enabled `deletion.allowSelfImmediate`.\n */\nexport class ImmediateDeletionNotAllowedError extends ForbiddenError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({ message: data.message || 'Immediate self-service deletion is not enabled', details: data.details });\n this.name = 'ImmediateDeletionNotAllowedError';\n }\n}\n\n/**\n * Account Already Exists Error (409)\n *\n * Thrown when trying to register with existing email/phone\n */\nexport class AccountAlreadyExistsError extends ConflictError\n{\n constructor(data: { identifier?: string; identifierType?: 'email' | 'phone'; message?: string; details?: Record<string, any> } = {})\n {\n super({\n message: data.message || 'Account already exists',\n details: {\n identifier: data.identifier,\n identifierType: data.identifierType,\n ...data.details,\n },\n });\n this.name = 'AccountAlreadyExistsError';\n }\n}\n\n/**\n * Registration Rejected Error (403)\n *\n * Thrown by the app-injected beforeRegister hook to reject a registration\n * (age gate, domain restriction, block list, ...)\n */\nexport class RegistrationRejectedError extends ForbiddenError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({ message: data.message || 'Registration rejected', details: data.details });\n this.name = 'RegistrationRejectedError';\n }\n}\n\n/**\n * Invalid Verification Code Error (400)\n *\n * Thrown when verification code is invalid, expired, or already used\n */\nexport class InvalidVerificationCodeError extends ValidationError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({ message: data.message || 'Invalid verification code', details: data.details });\n this.name = 'InvalidVerificationCodeError';\n }\n}\n\n/**\n * Invalid Verification Token Error (400)\n *\n * Thrown when verification token is invalid or expired\n */\nexport class InvalidVerificationTokenError extends ValidationError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({ message: data.message || 'Invalid or expired verification token', details: data.details });\n this.name = 'InvalidVerificationTokenError';\n }\n}\n\n/**\n * Key ID Already Registered Error (409)\n *\n * Thrown when a sign-in submits a keyId that is already taken — the client's own\n * revoked keyId, or a keyId belonging to another user. `keyId` is unique across\n * all users, so either case would collide on insert.\n *\n * The same error covers both cases on purpose: a distinguishable response would\n * let a caller probe whether an arbitrary keyId exists. Revoked stays revoked —\n * the client must generate a fresh keyId and retry.\n */\nexport class KeyIdAlreadyRegisteredError extends ConflictError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({\n message: data.message || 'This keyId is already registered. Generate a new keyId and retry.',\n details: data.details,\n });\n this.name = 'KeyIdAlreadyRegisteredError';\n }\n}\n\n/**\n * Invalid Key Fingerprint Error (400)\n *\n * Thrown when public key fingerprint doesn't match the public key\n */\nexport class InvalidKeyFingerprintError extends ValidationError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({ message: data.message || 'Invalid key fingerprint', details: data.details });\n this.name = 'InvalidKeyFingerprintError';\n }\n}\n\n/**\n * Key Algorithm Mismatch Error (400)\n *\n * Thrown when the submitted public key's SPKI type is not the one its declared\n * algorithm needs — a P-256 EC key declared RS256, an RSA key declared ES256, a\n * curve other than P-256 declared ES256, or bytes that are no SPKI key at all.\n *\n * The algorithm is stored beside the key and read back at proof verification;\n * nothing re-derives it from the key material. So a mismatch accepted here\n * surfaces only after the device believes it is enrolled, on every request it\n * then makes. It is refused at registration instead, wherever key material is\n * stored: register, login, rotate, invitation acceptance and device start.\n */\nexport class KeyAlgorithmMismatchError extends ValidationError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({\n message: data.message || 'Public key type does not match the declared algorithm',\n details: data.details,\n });\n this.name = 'KeyAlgorithmMismatchError';\n }\n}\n\n/**\n * Key Not Found Error (404)\n *\n * Thrown when a key operation names a keyId the caller does not own. It says\n * nothing about whether that keyId exists on another account — the repository\n * scopes every lookup by userId, so the answer is only ever \"not yours\".\n */\nexport class KeyNotFoundError extends NotFoundError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({ message: data.message || 'Key not found', details: data.details });\n this.name = 'KeyNotFoundError';\n }\n}\n\n/**\n * Device Auth Not Found Error (404)\n *\n * Thrown when a device-code operation names a code the server cannot act on: one\n * that was never issued, and one whose record has already been consumed.\n *\n * Those two are answered identically on purpose. A consumed record is a login\n * that finished, and saying so would tell whoever holds the code that it was\n * real — which is the difference between guessing at random and knowing a guess\n * landed. Every route that accepts a code is rate limited for the same reason.\n */\nexport class DeviceAuthNotFoundError extends NotFoundError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({ message: data.message || 'Device authorization not found', details: data.details });\n this.name = 'DeviceAuthNotFoundError';\n }\n}\n\n/**\n * Device Auth Expired Error (400)\n *\n * Thrown when a device-code operation names a record whose TTL has run out,\n * whatever state it is in. The waiting device starts again; the approver is told\n * the code on the other screen is stale.\n *\n * 400 rather than 401: on the approve and deny routes the caller's own session is\n * fine, and answering 401 would send a signed-in user to a login screen over a\n * code that simply sat too long.\n */\nexport class DeviceAuthExpiredError extends ValidationError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({\n message: data.message || 'This device code has expired. Start again on the other device.',\n details: data.details,\n });\n this.name = 'DeviceAuthExpiredError';\n }\n}\n\n/**\n * Device Auth Already Handled Error (409)\n *\n * Thrown when an approve, deny or info call names a record that has already been\n * approved or denied. A decision on a device is made once — a second approval\n * would let one code be answered twice, and re-approving a record the owner\n * denied would undo the refusal.\n *\n * This is also what the loser of two concurrent approvals sees, since the\n * transition names the state it moves from and only one call can match it.\n */\nexport class DeviceAuthAlreadyHandledError extends ConflictError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({\n message: data.message || 'This device request has already been answered',\n details: data.details,\n });\n this.name = 'DeviceAuthAlreadyHandledError';\n }\n}\n\n/**\n * Device Auth Denied Error (403)\n *\n * Thrown when the waiting device polls a record its owner refused. Distinct from\n * a pending answer, and distinct from a code that does not exist: the device\n * asked a person and the person said no, so it should stop polling and say so\n * rather than time out looking like a network fault.\n */\nexport class DeviceAuthDeniedError extends ForbiddenError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({\n message: data.message || 'This device request was denied',\n details: data.details,\n });\n this.name = 'DeviceAuthDeniedError';\n }\n}\n\n/**\n * Nonce Key Binding Error (400)\n *\n * Thrown when a native id_token sign-in submits a nonce that is not the public\n * key's fingerprint. The nonce is what the provider echoed back inside the\n * id_token, so tying it to the key is what proves the id_token and the key came\n * from the same device — see the native section of the README.\n */\nexport class NonceKeyBindingError extends ValidationError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({\n message: data.message || 'nonce must be the fingerprint of the submitted public key',\n details: data.details,\n });\n this.name = 'NonceKeyBindingError';\n }\n}\n\n/**\n * Native Sign-In Unsupported Error (400)\n *\n * Thrown when a provider is asked for native id_token sign-in and has no\n * implementation for it — a server configuration fact, not something the user\n * did. A client reading this hides that provider's native button instead of\n * asking the user to try again.\n *\n * Split out of ValidationError because the other native-enrollment refusal\n * (linking to an account whose email the provider never verified) needs a\n * different response from the app, and one code cannot ask for two.\n */\nexport class NativeSignInUnsupportedError extends ValidationError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({\n message: data.message || 'This provider does not support native id_token sign-in.',\n details: data.details,\n });\n this.name = 'NativeSignInUnsupportedError';\n }\n}\n\n/**\n * Invalid Signup Link Error (400)\n *\n * Thrown when an emailed signup confirmation link is unknown, expired, already\n * consumed, or superseded by a newer request for the same address.\n *\n * One error for all four states, on purpose. Distinguishing \"expired\" from\n * \"unknown\" tells a caller holding a random token whether it named a real\n * pending signup, which is exactly the enumeration the request step avoids. The\n * specific reason is logged.\n */\nexport class InvalidSignupLinkError extends ValidationError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({\n message: data.message || 'This signup link is no longer valid. Request a new one.',\n details: data.details,\n });\n this.name = 'InvalidSignupLinkError';\n }\n}\n\n/**\n * Invalid Signup Setup Session Error (401)\n *\n * Thrown when the password-setup session backing a verified-email signup is\n * missing, unknown, expired, superseded or already used.\n *\n * One error for every one of those, on purpose: telling a caller which of them\n * applies tells them whether an address is mid-signup, which is the same\n * enumeration the request step is careful not to leak.\n */\nexport class InvalidSignupSetupSessionError extends UnauthorizedError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({\n message: data.message || 'Password setup session is invalid or has expired. Start the signup again.',\n details: data.details,\n });\n this.name = 'InvalidSignupSetupSessionError';\n }\n}\n\n/**\n * Password Reset Link Error (401)\n *\n * Thrown when an emailed password reset link is unknown, expired, already\n * consumed, superseded by a newer request, or belongs to an account that is no\n * longer active.\n *\n * One error for every one of those, on purpose. Distinguishing \"expired\" from\n * \"unknown\" tells a caller holding a random token whether it named a real\n * pending reset, which is exactly the enumeration the request step avoids. The\n * specific reason is logged.\n */\nexport class PasswordResetLinkError extends UnauthorizedError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({\n message: data.message || 'This password reset link is no longer valid. Request a new one.',\n details: data.details,\n });\n this.name = 'PasswordResetLinkError';\n }\n}\n\n/**\n * Password Reset Session Error (401)\n *\n * Thrown when the password-setup session backing a reset is missing, unknown,\n * expired, superseded or already used.\n *\n * One error for every one of those, for the same reason the link error is one\n * error: which of them applies tells a caller whether an account is mid-reset,\n * and that is the enumeration the request step is careful not to leak.\n */\nexport class PasswordResetSessionError extends UnauthorizedError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({\n message: data.message || 'Password reset session is invalid or has expired. Request a new link.',\n details: data.details,\n });\n this.name = 'PasswordResetSessionError';\n }\n}\n\n/**\n * Unverified Email Link Error (400)\n *\n * Thrown when a social identity carries an email that already belongs to an\n * account, but the provider never verified it. Linking on an unverified email\n * is account takeover, so the refusal stands and the user is sent to a path\n * that proves the address.\n *\n * This says an account exists for that address. It is not a leak introduced\n * here: the message this replaces already stated the same fact in prose, and\n * the paths that must not disclose account existence (password login, deletion\n * re-auth, verification issuance) answer uniformly and are untouched.\n */\nexport class UnverifiedEmailLinkError extends ValidationError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({\n message: data.message\n || 'Cannot link to existing account with unverified email. Please verify your email with the provider first.',\n details: data.details,\n });\n this.name = 'UnverifiedEmailLinkError';\n }\n}\n\n/**\n * Verification Token Purpose Mismatch Error (400)\n *\n * Thrown when verification token purpose doesn't match expected purpose\n */\nexport class VerificationTokenPurposeMismatchError extends ValidationError\n{\n constructor(data: { expected?: string; actual?: string; message?: string; details?: Record<string, any> } = {})\n {\n const expected = data.expected || 'unknown';\n const actual = data.actual || 'unknown';\n super({\n message: data.message || `Verification token is for ${actual}, but ${expected} was expected`,\n details: { expected, actual, ...data.details },\n });\n this.name = 'VerificationTokenPurposeMismatchError';\n }\n}\n\n/**\n * Verification Token Target Mismatch Error (400)\n *\n * Thrown when verification token target doesn't match provided email/phone\n */\nexport class VerificationTokenTargetMismatchError extends ValidationError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({\n message: data.message || 'Verification token does not match provided email/phone',\n details: data.details,\n });\n this.name = 'VerificationTokenTargetMismatchError';\n }\n}\n\n/**\n * Reserved Username Error (400)\n *\n * Thrown when trying to use a reserved/prohibited username\n */\nexport class ReservedUsernameError extends ValidationError\n{\n constructor(data: { username?: string; message?: string; details?: Record<string, any> } = {})\n {\n super({\n message: data.message || 'This username is reserved',\n details: { username: data.username, ...data.details },\n });\n this.name = 'ReservedUsernameError';\n }\n}\n\n/**\n * Username Already Taken Error (409)\n *\n * Thrown when trying to set a username that is already in use\n */\nexport class UsernameAlreadyTakenError extends ConflictError\n{\n constructor(data: { username?: string; message?: string; details?: Record<string, any> } = {})\n {\n super({\n message: data.message || 'Username is already taken',\n details: { username: data.username, ...data.details },\n });\n this.name = 'UsernameAlreadyTakenError';\n }\n}\n\n/**\n * Insufficient Permissions Error (403)\n *\n * Thrown when user lacks required permissions for the operation\n */\nexport class InsufficientPermissionsError extends ForbiddenError\n{\n constructor(data: { requiredPermissions?: string[]; message?: string; details?: Record<string, any> } = {})\n {\n const requiredPermissions = data.requiredPermissions || [];\n super({\n message: data.message || `Missing required permissions: ${requiredPermissions.join(', ')}`,\n details: { requiredPermissions, ...data.details },\n });\n this.name = 'InsufficientPermissionsError';\n }\n}\n\n/**\n * Insufficient Role Error (403)\n *\n * Thrown when user lacks required role for the operation\n */\nexport class InsufficientRoleError extends ForbiddenError\n{\n constructor(data: { requiredRoles?: string[]; message?: string; details?: Record<string, any> } = {})\n {\n const requiredRoles = data.requiredRoles || [];\n super({\n message: data.message || `Required roles: ${requiredRoles.join(', ')}`,\n details: { requiredRoles, ...data.details },\n });\n this.name = 'InsufficientRoleError';\n }\n}\n\n/**\n * Passkey Challenge Error (401)\n *\n * Thrown when the challenge a WebAuthn ceremony presents is unknown, expired,\n * already spent, minted for the other ceremony, or minted for another account.\n *\n * One error for all five, on purpose. Telling a caller which applies tells them\n * whether a challenge they did not mint exists and what it was for, and the\n * remedy is the same in every case: start the ceremony again.\n */\nexport class PasskeyChallengeError extends UnauthorizedError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({\n message: data.message || 'This passkey challenge is no longer valid. Try again.',\n details: data.details,\n });\n this.name = 'PasskeyChallengeError';\n }\n}\n\n/**\n * Passkey Verification Error (401)\n *\n * Thrown when an assertion or attestation does not verify: wrong origin, wrong\n * rpId, a bad signature, a regressed signature counter — or, on login, a\n * credential that is unknown or has been revoked.\n *\n * Those last two share this error with the cryptographic failures deliberately.\n * A distinct \"no such passkey\" would answer, to anyone holding a credential id,\n * whether it is enrolled here — and a revoked credential answering differently\n * from an unknown one would say the account once had it.\n */\nexport class PasskeyVerificationError extends UnauthorizedError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({\n message: data.message || 'Passkey verification failed.',\n details: data.details,\n });\n this.name = 'PasskeyVerificationError';\n }\n}\n\n/**\n * Passkey Not Found Error (404)\n *\n * Thrown when a management operation names a passkey the caller does not own,\n * or one already revoked. Every lookup is owner-scoped, so the answer is only\n * ever \"not yours\" and says nothing about other accounts.\n */\nexport class PasskeyNotFoundError extends NotFoundError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({\n message: data.message || 'Passkey not found',\n details: data.details,\n });\n this.name = 'PasskeyNotFoundError';\n }\n}\n\n/**\n * Passkey Already Registered Error (409)\n *\n * Thrown when the credential presented for enrollment is already on file for\n * some account — including one that revoked it. A credential id is reserved for\n * good once used, so this is also the answer to re-enrolling one's own revoked\n * passkey.\n */\nexport class PasskeyAlreadyRegisteredError extends ConflictError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({\n message: data.message || 'This passkey is already registered',\n details: data.details,\n });\n this.name = 'PasskeyAlreadyRegisteredError';\n }\n}\n\n/**\n * Recent Authentication Required Error (403)\n *\n * Thrown when enrolling or revoking a passkey from a session that proved itself\n * too long ago and carried no password. Clients branch on `code` to know to\n * prompt for the password rather than to show a generic refusal, so the code is\n * a stable field rather than a message they would have to match on.\n */\nexport class RecentAuthenticationRequiredError extends ForbiddenError\n{\n readonly code = 'RECENT_AUTH_REQUIRED';\n\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({\n message: data.message || 'Confirm it is you before changing passkeys. Sign in again or send your current password.',\n details: data.details,\n });\n this.name = 'RecentAuthenticationRequiredError';\n }\n}\n\n/**\n * Last Recovery Credential Error (409)\n *\n * Thrown when revoking a passkey would leave the account with no way back in:\n * no other live passkey, no password, and no linked social account. There is no\n * password reset in this package, so that state is not recoverable by support\n * either — the refusal is the only thing standing between the owner and a\n * locked account.\n *\n * Clients branch on `code` to offer \"set a password first\" instead of a generic\n * refusal.\n */\nexport class LastRecoveryCredentialError extends ConflictError\n{\n readonly code = 'LAST_RECOVERY_CREDENTIAL';\n\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({\n message: data.message\n || 'This is the only way you can sign in. Set a password or link a social account before removing it.',\n details: data.details,\n });\n this.name = 'LastRecoveryCredentialError';\n }\n}\n\n/**\n * Passkey Config Error (500)\n *\n * Thrown at boot when the passkey relying-party configuration cannot be honoured\n * — an origin that is not https outside localhost, an origin off the rpId, an\n * unsupported user-verification value.\n *\n * A refusal at boot rather than at the first ceremony: every one of these makes\n * every passkey operation fail, and the drift is between environments, so the\n * deploy that introduces it is where it has to surface.\n */\nexport class PasskeyConfigError extends HttpError\n{\n constructor(data: { message: string; details?: Record<string, any> })\n {\n super({\n message: data.message,\n statusCode: 500,\n details: data.details,\n });\n this.name = 'PasskeyConfigError';\n }\n}\n\n/**\n * OAuth2 Unknown Client Error (400)\n *\n * Thrown by the API authorize endpoints when `client_id` names no registered\n * client. One of the two refusals that must NOT be turned into a redirect: with\n * no client there is no registered redirect URI, so the only place left to send\n * the error is the one the request supplied — which is exactly the open redirect\n * this rule exists to close. The consent screen shows it instead.\n */\nexport class OAuth2UnknownClientError extends ValidationError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({\n message: data.message || 'Unknown OAuth client',\n details: { error: 'unknown_client', ...data.details },\n });\n this.name = 'OAuth2UnknownClientError';\n }\n}\n\n/**\n * OAuth2 Redirect URI Mismatch Error (400)\n *\n * Thrown when `redirect_uri` is not one the client registered. The second\n * non-redirectable refusal, for the same reason as the first: redirecting the\n * error to an unregistered URI is the attack.\n */\nexport class OAuth2RedirectUriMismatchError extends ValidationError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({\n message: data.message || 'redirect_uri does not match a registered URI for this client',\n details: { error: 'redirect_uri_mismatch', ...data.details },\n });\n this.name = 'OAuth2RedirectUriMismatchError';\n }\n}\n\n/**\n * OAuth2 Authorize Redirect Error (400)\n *\n * Every other authorize-time refusal — `invalid_request`, `invalid_scope`,\n * `invalid_target`, `access_denied`. The client and its redirect URI are both\n * known by the time these are decided, so RFC 6749 §4.1.2.1 says the error goes\n * back to the client as query parameters on that URI rather than to the person.\n *\n * The API cannot perform that redirect — it is answering the web app's consent\n * handler, not the browser — so it carries the pieces in `details` and the\n * handler builds the 302. `redirectUri` is the registered-and-matched value, not\n * the raw parameter, which is what makes it safe to send somebody to.\n */\nexport class OAuth2AuthorizeRedirectError extends ValidationError\n{\n constructor(data: {\n error: string;\n redirectUri: string;\n state?: string;\n message?: string;\n details?: Record<string, any>;\n })\n {\n super({\n message: data.message || `OAuth authorize request refused: ${data.error}`,\n details: {\n error: data.error,\n redirectUri: data.redirectUri,\n state: data.state,\n ...data.details,\n },\n });\n this.name = 'OAuth2AuthorizeRedirectError';\n }\n}\n\n/**\n * OAuth2 Grant Not Found Error (404)\n *\n * Thrown by `DELETE /_auth/oauth2/grants/:id` when the caller owns no live grant\n * of that id. A grant belonging to somebody else answers the same way as one\n * that never existed — the id is a number in a URL, and telling the two apart\n * would let anyone count other people's connected clients.\n */\nexport class OAuth2GrantNotFoundError extends NotFoundError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({ message: data.message || 'No such connected application', details: data.details });\n this.name = 'OAuth2GrantNotFoundError';\n }\n}\n"],"mappings":"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","names":[]}
|