@cedarjs/auth-dbauth-web 7.0.0 → 8.0.0-canary.3263
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/dist/oauth.d.ts +58 -0
- package/dist/oauth.d.ts.map +1 -0
- package/dist/oauth.js +52 -0
- package/dist/webAuthn.d.ts +1 -1
- package/dist/webAuthn.d.ts.map +1 -1
- package/dist/webAuthn.js +4 -2
- package/package.json +12 -6
package/dist/oauth.d.ts
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Web client for dbAuth's OAuth routes.
|
|
3
|
+
*
|
|
4
|
+
* The OAuth handler lives in the same auth function as the rest of dbAuth,
|
|
5
|
+
* under the `/oauth` sub-path (e.g. `${RWJS_API_URL}/auth/oauth`). This
|
|
6
|
+
* module derives that base URL exactly the way `dbAuth.ts` does, and offers
|
|
7
|
+
* the same `dbAuthUrl` override affordance.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* The three account flows the server distinguishes between, so a user can
|
|
11
|
+
* never accidentally create a duplicate account by logging in with a
|
|
12
|
+
* provider.
|
|
13
|
+
*/
|
|
14
|
+
export type OAuthFlow = 'login' | 'signup' | 'link';
|
|
15
|
+
/**
|
|
16
|
+
* Error codes the OAuth handler's redirect can carry as `?error=<code>`.
|
|
17
|
+
*/
|
|
18
|
+
export type OAuthErrorCode = 'unknown_provider' | 'invalid_state' | 'provider_error' | 'unknown_identity' | 'email_in_use' | 'identity_in_use' | 'not_authenticated' | 'flow_not_enabled' | 'cannot_unlink_last_identity' | 'untrusted_origin' | 'server_error';
|
|
19
|
+
export interface OAuthClientOptions {
|
|
20
|
+
/**
|
|
21
|
+
* Overrides the derived dbAuth base URL (the same override `dbAuth.ts`
|
|
22
|
+
* offers via `DbAuthClientArgs.dbAuthUrl`).
|
|
23
|
+
*/
|
|
24
|
+
dbAuthUrl?: string;
|
|
25
|
+
}
|
|
26
|
+
export interface GetOAuthUrlOptions extends OAuthClientOptions {
|
|
27
|
+
/** Which account flow to start. Defaults to `'login'`. */
|
|
28
|
+
flow?: OAuthFlow;
|
|
29
|
+
}
|
|
30
|
+
export interface UnlinkOAuthProviderSuccess {
|
|
31
|
+
ok: true;
|
|
32
|
+
}
|
|
33
|
+
export interface UnlinkOAuthProviderFailure {
|
|
34
|
+
error: string;
|
|
35
|
+
}
|
|
36
|
+
export type UnlinkOAuthProviderResult = UnlinkOAuthProviderSuccess | UnlinkOAuthProviderFailure;
|
|
37
|
+
/**
|
|
38
|
+
* Builds the absolute URL for a provider's `authorize` route. Navigate the
|
|
39
|
+
* full page to this URL (e.g. `window.location.href = getOAuthUrl(...)`) —
|
|
40
|
+
* it starts a browser redirect flow, so it must not be `fetch`ed.
|
|
41
|
+
*/
|
|
42
|
+
export declare function getOAuthUrl(provider: string, options?: GetOAuthUrlOptions): string;
|
|
43
|
+
/**
|
|
44
|
+
* Unlinks a provider identity from the current dbAuth session. Requires the
|
|
45
|
+
* dbAuth session cookie, so the request is sent with credentials included.
|
|
46
|
+
*
|
|
47
|
+
* The server only accepts this request from a trusted `Origin` (the app's
|
|
48
|
+
* own origin by default, or one listed in `trustedOrigins`/`cors.origin`) —
|
|
49
|
+
* see the `trustedOrigins` option on `OAuthHandlerOptions`.
|
|
50
|
+
*/
|
|
51
|
+
export declare function unlinkOAuthProvider(provider: string, options?: OAuthClientOptions): Promise<UnlinkOAuthProviderResult>;
|
|
52
|
+
/**
|
|
53
|
+
* Extracts and narrows the `error` query param the OAuth handler's redirect
|
|
54
|
+
* carries after a failed flow. Returns `null` when there is no `error`
|
|
55
|
+
* param, or when its value isn't one of the known OAuth error codes.
|
|
56
|
+
*/
|
|
57
|
+
export declare function getOAuthError(searchParams: URLSearchParams | string): OAuthErrorCode | null;
|
|
58
|
+
//# sourceMappingURL=oauth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth.d.ts","sourceRoot":"","sources":["../src/oauth.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH;;;;GAIG;AACH,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAA;AAEnD;;GAEG;AACH,MAAM,MAAM,cAAc,GACtB,kBAAkB,GAClB,eAAe,GACf,gBAAgB,GAChB,kBAAkB,GAClB,cAAc,GACd,iBAAiB,GACjB,mBAAmB,GACnB,kBAAkB,GAClB,6BAA6B,GAC7B,kBAAkB,GAClB,cAAc,CAAA;AAuBlB,MAAM,WAAW,kBAAkB;IACjC;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,kBAAmB,SAAQ,kBAAkB;IAC5D,0DAA0D;IAC1D,IAAI,CAAC,EAAE,SAAS,CAAA;CACjB;AAED,MAAM,WAAW,0BAA0B;IACzC,EAAE,EAAE,IAAI,CAAA;CACT;AAED,MAAM,WAAW,0BAA0B;IACzC,KAAK,EAAE,MAAM,CAAA;CACd;AAED,MAAM,MAAM,yBAAyB,GACnC,0BAA0B,GAAG,0BAA0B,CAAA;AAMzD;;;;GAIG;AACH,wBAAgB,WAAW,CACzB,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,kBAAkB,GAC3B,MAAM,CAKR;AAED;;;;;;;GAOG;AACH,wBAAsB,mBAAmB,CACvC,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,kBAAkB,GAC3B,OAAO,CAAC,yBAAyB,CAAC,CAoBpC;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAC3B,YAAY,EAAE,eAAe,GAAG,MAAM,GACrC,cAAc,GAAG,IAAI,CAavB"}
|
package/dist/oauth.js
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
const OAUTH_ERROR_CODES = [
|
|
2
|
+
"unknown_provider",
|
|
3
|
+
"invalid_state",
|
|
4
|
+
"provider_error",
|
|
5
|
+
"unknown_identity",
|
|
6
|
+
"email_in_use",
|
|
7
|
+
"identity_in_use",
|
|
8
|
+
"not_authenticated",
|
|
9
|
+
"flow_not_enabled",
|
|
10
|
+
"cannot_unlink_last_identity",
|
|
11
|
+
"untrusted_origin",
|
|
12
|
+
"server_error"
|
|
13
|
+
];
|
|
14
|
+
function isOAuthErrorCode(value) {
|
|
15
|
+
return OAUTH_ERROR_CODES.includes(value);
|
|
16
|
+
}
|
|
17
|
+
function getDbAuthUrl(dbAuthUrl) {
|
|
18
|
+
return dbAuthUrl || `${RWJS_API_URL}/auth`;
|
|
19
|
+
}
|
|
20
|
+
function getOAuthUrl(provider, options) {
|
|
21
|
+
const flow = options?.flow ?? "login";
|
|
22
|
+
const baseUrl = getDbAuthUrl(options?.dbAuthUrl);
|
|
23
|
+
return `${baseUrl}/oauth/${encodeURIComponent(provider)}/authorize?flow=${flow}`;
|
|
24
|
+
}
|
|
25
|
+
async function unlinkOAuthProvider(provider, options) {
|
|
26
|
+
const baseUrl = getDbAuthUrl(options?.dbAuthUrl);
|
|
27
|
+
const response = await fetch(
|
|
28
|
+
`${baseUrl}/oauth/${encodeURIComponent(provider)}/unlink`,
|
|
29
|
+
{
|
|
30
|
+
method: "POST",
|
|
31
|
+
credentials: "include"
|
|
32
|
+
}
|
|
33
|
+
);
|
|
34
|
+
try {
|
|
35
|
+
return await response.json();
|
|
36
|
+
} catch {
|
|
37
|
+
return { error: "server_error" };
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
function getOAuthError(searchParams) {
|
|
41
|
+
const params = typeof searchParams === "string" ? new URLSearchParams(searchParams) : searchParams;
|
|
42
|
+
const error = params.get("error");
|
|
43
|
+
if (error && isOAuthErrorCode(error)) {
|
|
44
|
+
return error;
|
|
45
|
+
}
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
export {
|
|
49
|
+
getOAuthError,
|
|
50
|
+
getOAuthUrl,
|
|
51
|
+
unlinkOAuthProvider
|
|
52
|
+
};
|
package/dist/webAuthn.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ export default class WebAuthnClient {
|
|
|
2
2
|
authApiUrl: string;
|
|
3
3
|
private getAuthApiUrl;
|
|
4
4
|
setAuthApiUrl(authApiUrl?: string): void;
|
|
5
|
-
isSupported(): Promise<
|
|
5
|
+
isSupported(): Promise<boolean>;
|
|
6
6
|
isEnabled(): boolean;
|
|
7
7
|
private authenticationOptions;
|
|
8
8
|
authenticate(): Promise<boolean>;
|
package/dist/webAuthn.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"webAuthn.d.ts","sourceRoot":"","sources":["../src/webAuthn.ts"],"names":[],"mappings":"AAqCA,MAAM,CAAC,OAAO,OAAO,cAAc;IACjC,UAAU,SAAK;IAEf,OAAO,CAAC,aAAa;IAIrB,aAAa,CAAC,UAAU,CAAC,EAAE,MAAM;IAM3B,WAAW;IAKjB,SAAS;YAQK,qBAAqB;IAmC7B,YAAY;
|
|
1
|
+
{"version":3,"file":"webAuthn.d.ts","sourceRoot":"","sources":["../src/webAuthn.ts"],"names":[],"mappings":"AAqCA,MAAM,CAAC,OAAO,OAAO,cAAc;IACjC,UAAU,SAAK;IAEf,OAAO,CAAC,aAAa;IAIrB,aAAa,CAAC,UAAU,CAAC,EAAE,MAAM;IAM3B,WAAW;IAKjB,SAAS;YAQK,qBAAqB;IAmC7B,YAAY;IA4ClB,OAAO,CAAC,mBAAmB;IA+BrB,QAAQ;CAwCf;AAED,MAAM,MAAM,kBAAkB,GAAG,OAAO,cAAc,CAAA"}
|
package/dist/webAuthn.js
CHANGED
|
@@ -84,7 +84,9 @@ class WebAuthnClient {
|
|
|
84
84
|
const authOptions = await this.authenticationOptions();
|
|
85
85
|
const { startAuthentication } = await import("@simplewebauthn/browser");
|
|
86
86
|
try {
|
|
87
|
-
const browserResponse = await startAuthentication(
|
|
87
|
+
const browserResponse = await startAuthentication({
|
|
88
|
+
optionsJSON: authOptions
|
|
89
|
+
});
|
|
88
90
|
const xhr = new XMLHttpRequest();
|
|
89
91
|
xhr.withCredentials = true;
|
|
90
92
|
xhr.open("POST", this.getAuthApiUrl(), false);
|
|
@@ -145,7 +147,7 @@ class WebAuthnClient {
|
|
|
145
147
|
let regResponse;
|
|
146
148
|
const { startRegistration } = await import("@simplewebauthn/browser");
|
|
147
149
|
try {
|
|
148
|
-
regResponse = await startRegistration(options);
|
|
150
|
+
regResponse = await startRegistration({ optionsJSON: options });
|
|
149
151
|
} catch (e) {
|
|
150
152
|
if (e.name === "InvalidStateError") {
|
|
151
153
|
throw new WebAuthnAlreadyRegisteredError();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cedarjs/auth-dbauth-web",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "8.0.0-canary.3263",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/cedarjs/cedar.git",
|
|
@@ -20,6 +20,12 @@
|
|
|
20
20
|
"types": "./dist/webAuthn.d.ts",
|
|
21
21
|
"default": "./dist/webAuthn.js"
|
|
22
22
|
}
|
|
23
|
+
},
|
|
24
|
+
"./oauth": {
|
|
25
|
+
"default": {
|
|
26
|
+
"types": "./dist/oauth.d.ts",
|
|
27
|
+
"default": "./dist/oauth.js"
|
|
28
|
+
}
|
|
23
29
|
}
|
|
24
30
|
},
|
|
25
31
|
"main": "./dist/index.js",
|
|
@@ -39,15 +45,15 @@
|
|
|
39
45
|
"test:watch": "vitest watch"
|
|
40
46
|
},
|
|
41
47
|
"dependencies": {
|
|
42
|
-
"@cedarjs/auth": "
|
|
43
|
-
"@simplewebauthn/browser": "
|
|
48
|
+
"@cedarjs/auth": "8.0.0-canary.3263",
|
|
49
|
+
"@simplewebauthn/browser": "13.3.0"
|
|
44
50
|
},
|
|
45
51
|
"devDependencies": {
|
|
46
|
-
"@cedarjs/framework-tools": "
|
|
47
|
-
"@types/react": "^
|
|
52
|
+
"@cedarjs/framework-tools": "8.0.0-canary.3263",
|
|
53
|
+
"@types/react": "^19.2.0",
|
|
48
54
|
"concurrently": "9.2.4",
|
|
49
55
|
"publint": "0.3.24",
|
|
50
|
-
"react": "
|
|
56
|
+
"react": "19.3.0",
|
|
51
57
|
"typescript": "5.9.3",
|
|
52
58
|
"vitest": "4.1.11"
|
|
53
59
|
},
|