@cedarjs/auth-dbauth-web 5.0.7-next.338 → 5.0.7
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/cjs/dbAuth.d.ts +42 -0
- package/dist/cjs/dbAuth.d.ts.map +1 -0
- package/dist/cjs/dbAuth.js +170 -0
- package/dist/cjs/index.d.ts +2 -0
- package/dist/cjs/index.d.ts.map +1 -0
- package/dist/cjs/index.js +22 -0
- package/dist/cjs/package.json +1 -0
- package/dist/cjs/webAuthn.d.ts +13 -0
- package/dist/cjs/webAuthn.d.ts.map +1 -0
- package/dist/cjs/webAuthn.js +210 -0
- package/package.json +16 -13
- package/webAuthn/index.js +2 -0
- package/webAuthn/package.json +4 -0
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { CurrentUser } from '@cedarjs/auth';
|
|
2
|
+
import type { WebAuthnClientType } from './webAuthn.js';
|
|
3
|
+
export interface LoginAttributes {
|
|
4
|
+
username: string;
|
|
5
|
+
password: string;
|
|
6
|
+
}
|
|
7
|
+
export interface ResetPasswordAttributes {
|
|
8
|
+
resetToken: string;
|
|
9
|
+
password: string;
|
|
10
|
+
}
|
|
11
|
+
export type SignupAttributes = Record<string, unknown> & LoginAttributes;
|
|
12
|
+
export declare function createAuth(dbAuthClient: ReturnType<typeof createDbAuthClient>, customProviderHooks?: {
|
|
13
|
+
useCurrentUser?: () => Promise<CurrentUser>;
|
|
14
|
+
useHasRole?: (currentUser: CurrentUser | null) => (rolesToCheck: string | string[]) => boolean;
|
|
15
|
+
}): {
|
|
16
|
+
AuthContext: import("react").Context<import("@cedarjs/auth").AuthContextInterface<string | (() => void), LoginAttributes, any, unknown, boolean, SignupAttributes, any, any, ResetPasswordAttributes, any, any, import("./webAuthn.js").default> | undefined>;
|
|
17
|
+
AuthProvider: ({ children }: import("@cedarjs/auth").AuthProviderProps) => import("react").JSX.Element;
|
|
18
|
+
useAuth: () => import("@cedarjs/auth").AuthContextInterface<string | (() => void), LoginAttributes, any, unknown, boolean, SignupAttributes, any, any, ResetPasswordAttributes, any, any, import("./webAuthn.js").default>;
|
|
19
|
+
};
|
|
20
|
+
export interface DbAuthClientArgs {
|
|
21
|
+
webAuthn?: InstanceType<WebAuthnClientType>;
|
|
22
|
+
dbAuthUrl?: string;
|
|
23
|
+
fetchConfig?: {
|
|
24
|
+
credentials?: 'include' | 'same-origin';
|
|
25
|
+
};
|
|
26
|
+
middleware?: boolean;
|
|
27
|
+
}
|
|
28
|
+
export declare function createDbAuthClient({ webAuthn, dbAuthUrl, fetchConfig, middleware, }?: DbAuthClientArgs): {
|
|
29
|
+
type: string;
|
|
30
|
+
client: import("./webAuthn.js").default | undefined;
|
|
31
|
+
login: ({ username, password }: LoginAttributes) => Promise<any>;
|
|
32
|
+
logout: () => Promise<boolean>;
|
|
33
|
+
signup: (attributes: SignupAttributes) => Promise<any>;
|
|
34
|
+
getToken: () => Promise<string | null>;
|
|
35
|
+
getUserMetadata: () => Promise<string | (() => void) | null>;
|
|
36
|
+
forgotPassword: (username: string) => Promise<any>;
|
|
37
|
+
resetPassword: (attributes: ResetPasswordAttributes) => Promise<any>;
|
|
38
|
+
validateResetToken: (resetToken: string | null) => Promise<any>;
|
|
39
|
+
getAuthUrl: () => string;
|
|
40
|
+
middlewareAuthEnabled: boolean;
|
|
41
|
+
};
|
|
42
|
+
//# sourceMappingURL=dbAuth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dbAuth.d.ts","sourceRoot":"","sources":["../../src/dbAuth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAuB,MAAM,eAAe,CAAA;AAMrE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAA;AAEvD,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,uBAAuB;IACtC,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,MAAM,gBAAgB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,eAAe,CAAA;AAkBxE,wBAAgB,UAAU,CACxB,YAAY,EAAE,UAAU,CAAC,OAAO,kBAAkB,CAAC,EACnD,mBAAmB,CAAC,EAAE;IACpB,cAAc,CAAC,EAAE,MAAM,OAAO,CAAC,WAAW,CAAC,CAAA;IAC3C,UAAU,CAAC,EAAE,CACX,WAAW,EAAE,WAAW,GAAG,IAAI,KAC5B,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,EAAE,KAAK,OAAO,CAAA;CAClD;;;;EAOF;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,YAAY,CAAC,kBAAkB,CAAC,CAAA;IAC3C,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,WAAW,CAAC,EAAE;QACZ,WAAW,CAAC,EAAE,SAAS,GAAG,aAAa,CAAA;KACxC,CAAA;IACD,UAAU,CAAC,EAAE,OAAO,CAAA;CACrB;AAED,wBAAgB,kBAAkB,CAAC,EACjC,QAAQ,EACR,SAAS,EACT,WAAW,EACX,UAA4C,GAC7C,GAAE,gBAAqB;;;oCA6EuB,eAAe;;yBAgC1B,gBAAgB;;;+BA9EV,MAAM;gCAmEL,uBAAuB;qCAsBlB,MAAM,GAAG,IAAI;;;EAoC5D"}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var dbAuth_exports = {};
|
|
20
|
+
__export(dbAuth_exports, {
|
|
21
|
+
createAuth: () => createAuth,
|
|
22
|
+
createDbAuthClient: () => createDbAuthClient
|
|
23
|
+
});
|
|
24
|
+
module.exports = __toCommonJS(dbAuth_exports);
|
|
25
|
+
var import_auth = require("@cedarjs/auth");
|
|
26
|
+
const TOKEN_CACHE_TIME = 5e3;
|
|
27
|
+
function createMiddlewareAuth(dbAuthClient, customProviderHooks) {
|
|
28
|
+
return (0, import_auth.createAuthentication)(dbAuthClient, {
|
|
29
|
+
...customProviderHooks,
|
|
30
|
+
useCurrentUser: customProviderHooks?.useCurrentUser ?? (() => (0, import_auth.getCurrentUserFromMiddleware)(dbAuthClient.getAuthUrl()))
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
function createAuth(dbAuthClient, customProviderHooks) {
|
|
34
|
+
if (dbAuthClient.middlewareAuthEnabled) {
|
|
35
|
+
return createMiddlewareAuth(dbAuthClient, customProviderHooks);
|
|
36
|
+
}
|
|
37
|
+
return (0, import_auth.createAuthentication)(dbAuthClient, customProviderHooks);
|
|
38
|
+
}
|
|
39
|
+
function createDbAuthClient({
|
|
40
|
+
webAuthn,
|
|
41
|
+
dbAuthUrl,
|
|
42
|
+
fetchConfig,
|
|
43
|
+
middleware = RWJS_ENV.RWJS_EXP_STREAMING_SSR
|
|
44
|
+
} = {}) {
|
|
45
|
+
const credentials = fetchConfig?.credentials || "same-origin";
|
|
46
|
+
webAuthn?.setAuthApiUrl(dbAuthUrl);
|
|
47
|
+
let getTokenPromise;
|
|
48
|
+
let lastTokenCheckAt = /* @__PURE__ */ new Date("1970-01-01T00:00:00");
|
|
49
|
+
let cachedToken;
|
|
50
|
+
const getDbAuthUrl = () => {
|
|
51
|
+
if (dbAuthUrl) {
|
|
52
|
+
return dbAuthUrl;
|
|
53
|
+
}
|
|
54
|
+
return middleware ? `/middleware/dbauth` : `${RWJS_API_URL}/auth`;
|
|
55
|
+
};
|
|
56
|
+
const resetAndFetch = async (...params) => {
|
|
57
|
+
resetTokenCache();
|
|
58
|
+
return fetch(...params);
|
|
59
|
+
};
|
|
60
|
+
const isTokenCacheExpired = () => {
|
|
61
|
+
const now = /* @__PURE__ */ new Date();
|
|
62
|
+
return now.getTime() - lastTokenCheckAt.getTime() > TOKEN_CACHE_TIME;
|
|
63
|
+
};
|
|
64
|
+
const resetTokenCache = () => {
|
|
65
|
+
lastTokenCheckAt = /* @__PURE__ */ new Date("1970-01-01T00:00:00");
|
|
66
|
+
cachedToken = null;
|
|
67
|
+
};
|
|
68
|
+
const forgotPassword = async (username) => {
|
|
69
|
+
const response = await resetAndFetch(getDbAuthUrl(), {
|
|
70
|
+
credentials,
|
|
71
|
+
method: "POST",
|
|
72
|
+
headers: { "Content-Type": "application/json" },
|
|
73
|
+
body: JSON.stringify({ username, method: "forgotPassword" })
|
|
74
|
+
});
|
|
75
|
+
return response.json();
|
|
76
|
+
};
|
|
77
|
+
const getToken = async () => {
|
|
78
|
+
if (middleware) {
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
if (getTokenPromise) {
|
|
82
|
+
return getTokenPromise;
|
|
83
|
+
}
|
|
84
|
+
if (isTokenCacheExpired()) {
|
|
85
|
+
getTokenPromise = fetch(`${getDbAuthUrl()}?method=getToken`, {
|
|
86
|
+
credentials
|
|
87
|
+
}).then((response) => response.text()).then((tokenText) => {
|
|
88
|
+
lastTokenCheckAt = /* @__PURE__ */ new Date();
|
|
89
|
+
cachedToken = tokenText.length === 0 ? null : tokenText;
|
|
90
|
+
return cachedToken;
|
|
91
|
+
}).catch(() => {
|
|
92
|
+
return null;
|
|
93
|
+
}).finally(() => {
|
|
94
|
+
getTokenPromise = null;
|
|
95
|
+
});
|
|
96
|
+
return getTokenPromise;
|
|
97
|
+
}
|
|
98
|
+
return cachedToken;
|
|
99
|
+
};
|
|
100
|
+
const login = async ({ username, password }) => {
|
|
101
|
+
const response = await resetAndFetch(getDbAuthUrl(), {
|
|
102
|
+
credentials,
|
|
103
|
+
method: "POST",
|
|
104
|
+
headers: { "Content-Type": "application/json" },
|
|
105
|
+
body: JSON.stringify({ username, password, method: "login" })
|
|
106
|
+
});
|
|
107
|
+
return response.json();
|
|
108
|
+
};
|
|
109
|
+
const logout = async () => {
|
|
110
|
+
await resetAndFetch(getDbAuthUrl(), {
|
|
111
|
+
credentials,
|
|
112
|
+
method: "POST",
|
|
113
|
+
body: JSON.stringify({ method: "logout" })
|
|
114
|
+
});
|
|
115
|
+
return true;
|
|
116
|
+
};
|
|
117
|
+
const resetPassword = async (attributes) => {
|
|
118
|
+
const response = await resetAndFetch(getDbAuthUrl(), {
|
|
119
|
+
credentials,
|
|
120
|
+
method: "POST",
|
|
121
|
+
headers: { "Content-Type": "application/json" },
|
|
122
|
+
body: JSON.stringify({ ...attributes, method: "resetPassword" })
|
|
123
|
+
});
|
|
124
|
+
return response.json();
|
|
125
|
+
};
|
|
126
|
+
const signup = async (attributes) => {
|
|
127
|
+
const response = await resetAndFetch(getDbAuthUrl(), {
|
|
128
|
+
credentials,
|
|
129
|
+
method: "POST",
|
|
130
|
+
headers: { "Content-Type": "application/json" },
|
|
131
|
+
body: JSON.stringify({ ...attributes, method: "signup" })
|
|
132
|
+
});
|
|
133
|
+
return response.json();
|
|
134
|
+
};
|
|
135
|
+
const validateResetToken = async (resetToken) => {
|
|
136
|
+
const response = await resetAndFetch(getDbAuthUrl(), {
|
|
137
|
+
credentials,
|
|
138
|
+
method: "POST",
|
|
139
|
+
headers: { "Content-Type": "application/json" },
|
|
140
|
+
body: JSON.stringify({ resetToken, method: "validateResetToken" })
|
|
141
|
+
});
|
|
142
|
+
return response.json();
|
|
143
|
+
};
|
|
144
|
+
const getUserMetadata = async () => {
|
|
145
|
+
return middleware ? () => {
|
|
146
|
+
} : getToken();
|
|
147
|
+
};
|
|
148
|
+
return {
|
|
149
|
+
type: "dbAuth",
|
|
150
|
+
client: webAuthn,
|
|
151
|
+
login,
|
|
152
|
+
logout,
|
|
153
|
+
signup,
|
|
154
|
+
getToken,
|
|
155
|
+
getUserMetadata,
|
|
156
|
+
forgotPassword,
|
|
157
|
+
resetPassword,
|
|
158
|
+
validateResetToken,
|
|
159
|
+
// New methods for middleware auth:
|
|
160
|
+
// This is so we can get the dbAuthUrl in getCurrentUserFromMiddleware
|
|
161
|
+
getAuthUrl: getDbAuthUrl,
|
|
162
|
+
// This is so that we can skip fetching getCurrentUser in reauthenticate
|
|
163
|
+
middlewareAuthEnabled: middleware
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
167
|
+
0 && (module.exports = {
|
|
168
|
+
createAuth,
|
|
169
|
+
createDbAuthClient
|
|
170
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAA"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __copyProps = (to, from, except, desc) => {
|
|
7
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
8
|
+
for (let key of __getOwnPropNames(from))
|
|
9
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
10
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
11
|
+
}
|
|
12
|
+
return to;
|
|
13
|
+
};
|
|
14
|
+
var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
|
|
15
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
16
|
+
var index_exports = {};
|
|
17
|
+
module.exports = __toCommonJS(index_exports);
|
|
18
|
+
__reExport(index_exports, require("./dbAuth.js"), module.exports);
|
|
19
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
20
|
+
0 && (module.exports = {
|
|
21
|
+
...require("./dbAuth.js")
|
|
22
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"type":"commonjs"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export default class WebAuthnClient {
|
|
2
|
+
authApiUrl: string;
|
|
3
|
+
private getAuthApiUrl;
|
|
4
|
+
setAuthApiUrl(authApiUrl?: string): void;
|
|
5
|
+
isSupported(): Promise<any>;
|
|
6
|
+
isEnabled(): boolean;
|
|
7
|
+
private authenticationOptions;
|
|
8
|
+
authenticate(): Promise<boolean>;
|
|
9
|
+
private registrationOptions;
|
|
10
|
+
register(): Promise<boolean>;
|
|
11
|
+
}
|
|
12
|
+
export type WebAuthnClientType = typeof WebAuthnClient;
|
|
13
|
+
//# sourceMappingURL=webAuthn.d.ts.map
|
|
@@ -0,0 +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;IA0ClB,OAAO,CAAC,mBAAmB;IA+BrB,QAAQ;CAwCf;AAED,MAAM,MAAM,kBAAkB,GAAG,OAAO,cAAc,CAAA"}
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
var webAuthn_exports = {};
|
|
30
|
+
__export(webAuthn_exports, {
|
|
31
|
+
default: () => WebAuthnClient
|
|
32
|
+
});
|
|
33
|
+
module.exports = __toCommonJS(webAuthn_exports);
|
|
34
|
+
class WebAuthnRegistrationError extends Error {
|
|
35
|
+
constructor(message) {
|
|
36
|
+
super(message);
|
|
37
|
+
this.name = "WebAuthnRegistrationError";
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
class WebAuthnAuthenticationError extends Error {
|
|
41
|
+
constructor(message) {
|
|
42
|
+
super(message);
|
|
43
|
+
this.name = "WebAuthnAuthenticationError";
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
class WebAuthnAlreadyRegisteredError extends WebAuthnRegistrationError {
|
|
47
|
+
constructor() {
|
|
48
|
+
super("This device is already registered");
|
|
49
|
+
this.name = "WebAuthnAlreadyRegisteredError";
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
class WebAuthnDeviceNotFoundError extends WebAuthnAuthenticationError {
|
|
53
|
+
constructor() {
|
|
54
|
+
super("WebAuthn device not found");
|
|
55
|
+
this.name = "WebAuthnDeviceNotFoundError";
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
class WebAuthnNoAuthenticatorError extends WebAuthnAuthenticationError {
|
|
59
|
+
constructor() {
|
|
60
|
+
super(
|
|
61
|
+
"This device was not recognized. Use username/password login, or if you're using iOS you can try reloading this page"
|
|
62
|
+
);
|
|
63
|
+
this.name = "WebAuthnNoAuthenticatorError";
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
class WebAuthnClient {
|
|
67
|
+
authApiUrl = "";
|
|
68
|
+
getAuthApiUrl() {
|
|
69
|
+
return this.authApiUrl || `${RWJS_API_URL}/auth`;
|
|
70
|
+
}
|
|
71
|
+
setAuthApiUrl(authApiUrl) {
|
|
72
|
+
if (authApiUrl) {
|
|
73
|
+
this.authApiUrl = authApiUrl;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
async isSupported() {
|
|
77
|
+
const { browserSupportsWebAuthn } = await import("@simplewebauthn/browser");
|
|
78
|
+
return browserSupportsWebAuthn();
|
|
79
|
+
}
|
|
80
|
+
isEnabled() {
|
|
81
|
+
if (typeof window === "undefined") {
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
return !!/\bwebAuthn\b/.test(document.cookie);
|
|
85
|
+
}
|
|
86
|
+
async authenticationOptions() {
|
|
87
|
+
let options;
|
|
88
|
+
try {
|
|
89
|
+
const xhr = new XMLHttpRequest();
|
|
90
|
+
xhr.withCredentials = true;
|
|
91
|
+
xhr.open(
|
|
92
|
+
"GET",
|
|
93
|
+
`${this.getAuthApiUrl()}?method=webAuthnAuthOptions`,
|
|
94
|
+
false
|
|
95
|
+
);
|
|
96
|
+
xhr.setRequestHeader("content-type", "application/json");
|
|
97
|
+
xhr.send(null);
|
|
98
|
+
options = JSON.parse(xhr.responseText);
|
|
99
|
+
if (xhr.status !== 200) {
|
|
100
|
+
if (options.error?.match(/username and password/)) {
|
|
101
|
+
throw new WebAuthnDeviceNotFoundError();
|
|
102
|
+
} else {
|
|
103
|
+
throw new WebAuthnAuthenticationError(
|
|
104
|
+
`Could not start authentication: ${options.error}`
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
} catch (e) {
|
|
109
|
+
console.error(e.message);
|
|
110
|
+
throw new WebAuthnAuthenticationError(
|
|
111
|
+
`Could not start authentication: ${e.message}`
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
return options;
|
|
115
|
+
}
|
|
116
|
+
async authenticate() {
|
|
117
|
+
const authOptions = await this.authenticationOptions();
|
|
118
|
+
const { startAuthentication } = await import("@simplewebauthn/browser");
|
|
119
|
+
try {
|
|
120
|
+
const browserResponse = await startAuthentication(authOptions);
|
|
121
|
+
const xhr = new XMLHttpRequest();
|
|
122
|
+
xhr.withCredentials = true;
|
|
123
|
+
xhr.open("POST", this.getAuthApiUrl(), false);
|
|
124
|
+
xhr.setRequestHeader("content-type", "application/json");
|
|
125
|
+
xhr.send(
|
|
126
|
+
JSON.stringify({
|
|
127
|
+
method: "webAuthnAuthenticate",
|
|
128
|
+
...browserResponse
|
|
129
|
+
})
|
|
130
|
+
);
|
|
131
|
+
const options = JSON.parse(xhr.responseText);
|
|
132
|
+
if (xhr.status !== 200) {
|
|
133
|
+
throw new WebAuthnAuthenticationError(
|
|
134
|
+
`Could not complete authentication: ${options.error}`
|
|
135
|
+
);
|
|
136
|
+
}
|
|
137
|
+
} catch (e) {
|
|
138
|
+
if (e.message.match(
|
|
139
|
+
/No available authenticator recognized any of the allowed credentials/
|
|
140
|
+
)) {
|
|
141
|
+
throw new WebAuthnNoAuthenticatorError();
|
|
142
|
+
} else {
|
|
143
|
+
throw new WebAuthnAuthenticationError(
|
|
144
|
+
`Error while authenticating: ${e.message}`
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
return true;
|
|
149
|
+
}
|
|
150
|
+
registrationOptions() {
|
|
151
|
+
let options;
|
|
152
|
+
try {
|
|
153
|
+
const xhr = new XMLHttpRequest();
|
|
154
|
+
xhr.withCredentials = true;
|
|
155
|
+
xhr.open(
|
|
156
|
+
"GET",
|
|
157
|
+
`${this.getAuthApiUrl()}?method=webAuthnRegOptions`,
|
|
158
|
+
false
|
|
159
|
+
);
|
|
160
|
+
xhr.setRequestHeader("content-type", "application/json");
|
|
161
|
+
xhr.send(null);
|
|
162
|
+
options = JSON.parse(xhr.responseText);
|
|
163
|
+
if (xhr.status !== 200) {
|
|
164
|
+
throw new WebAuthnRegistrationError(
|
|
165
|
+
`Could not start registration: ${options.error}`
|
|
166
|
+
);
|
|
167
|
+
}
|
|
168
|
+
} catch (e) {
|
|
169
|
+
console.error(e);
|
|
170
|
+
throw new WebAuthnRegistrationError(
|
|
171
|
+
`Could not start registration: ${e.message}`
|
|
172
|
+
);
|
|
173
|
+
}
|
|
174
|
+
return options;
|
|
175
|
+
}
|
|
176
|
+
async register() {
|
|
177
|
+
const options = await this.registrationOptions();
|
|
178
|
+
let regResponse;
|
|
179
|
+
const { startRegistration } = await import("@simplewebauthn/browser");
|
|
180
|
+
try {
|
|
181
|
+
regResponse = await startRegistration(options);
|
|
182
|
+
} catch (e) {
|
|
183
|
+
if (e.name === "InvalidStateError") {
|
|
184
|
+
throw new WebAuthnAlreadyRegisteredError();
|
|
185
|
+
} else {
|
|
186
|
+
throw new WebAuthnRegistrationError(
|
|
187
|
+
`Error while registering: ${e.message}`
|
|
188
|
+
);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
try {
|
|
192
|
+
const xhr = new XMLHttpRequest();
|
|
193
|
+
xhr.withCredentials = true;
|
|
194
|
+
xhr.open("POST", this.getAuthApiUrl(), false);
|
|
195
|
+
xhr.setRequestHeader("content-type", "application/json");
|
|
196
|
+
xhr.send(JSON.stringify({ method: "webAuthnRegister", ...regResponse }));
|
|
197
|
+
const options2 = JSON.parse(xhr.responseText);
|
|
198
|
+
if (xhr.status !== 200) {
|
|
199
|
+
throw new WebAuthnRegistrationError(
|
|
200
|
+
`Could not complete registration: ${options2.error}`
|
|
201
|
+
);
|
|
202
|
+
}
|
|
203
|
+
} catch (e) {
|
|
204
|
+
throw new WebAuthnRegistrationError(
|
|
205
|
+
`Error while registering: ${e.message}`
|
|
206
|
+
);
|
|
207
|
+
}
|
|
208
|
+
return true;
|
|
209
|
+
}
|
|
210
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cedarjs/auth-dbauth-web",
|
|
3
|
-
"version": "5.0.7
|
|
3
|
+
"version": "5.0.7",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/cedarjs/cedar.git",
|
|
@@ -10,27 +10,28 @@
|
|
|
10
10
|
"type": "module",
|
|
11
11
|
"exports": {
|
|
12
12
|
".": {
|
|
13
|
-
"
|
|
13
|
+
"import": {
|
|
14
14
|
"types": "./dist/index.d.ts",
|
|
15
15
|
"default": "./dist/index.js"
|
|
16
|
-
}
|
|
17
|
-
},
|
|
18
|
-
"./webAuthn": {
|
|
16
|
+
},
|
|
19
17
|
"default": {
|
|
20
|
-
"types": "./dist/
|
|
21
|
-
"default": "./dist/
|
|
18
|
+
"types": "./dist/cjs/index.d.ts",
|
|
19
|
+
"default": "./dist/cjs/index.js"
|
|
22
20
|
}
|
|
23
21
|
}
|
|
24
22
|
},
|
|
25
|
-
"main": "./dist/index.js",
|
|
23
|
+
"main": "./dist/cjs/index.js",
|
|
24
|
+
"module": "./dist/index.js",
|
|
26
25
|
"types": "./dist/index.d.ts",
|
|
27
26
|
"files": [
|
|
28
|
-
"dist"
|
|
27
|
+
"dist",
|
|
28
|
+
"webAuthn"
|
|
29
29
|
],
|
|
30
30
|
"scripts": {
|
|
31
31
|
"build": "node ./build.ts",
|
|
32
32
|
"build:pack": "yarn pack -o cedarjs-auth-dbauth-web.tgz",
|
|
33
33
|
"build:types": "tsc --build --verbose ./tsconfig.build.json",
|
|
34
|
+
"build:types-cjs": "tsc --build --verbose ./tsconfig.cjs.json",
|
|
34
35
|
"build:watch": "nodemon --watch src --ext \"js,jsx,ts,tsx,template\" --ignore dist --exec \"yarn build\"",
|
|
35
36
|
"check:attw": "yarn cedar-fwtools-attw",
|
|
36
37
|
"check:package": "concurrently npm:check:attw yarn:publint",
|
|
@@ -39,17 +40,19 @@
|
|
|
39
40
|
"test:watch": "vitest watch"
|
|
40
41
|
},
|
|
41
42
|
"dependencies": {
|
|
42
|
-
"@cedarjs/auth": "5.0.7
|
|
43
|
+
"@cedarjs/auth": "5.0.7",
|
|
43
44
|
"@simplewebauthn/browser": "10.0.0"
|
|
44
45
|
},
|
|
45
46
|
"devDependencies": {
|
|
46
|
-
"@
|
|
47
|
+
"@arethetypeswrong/cli": "0.18.4",
|
|
48
|
+
"@cedarjs/framework-tools": "5.0.7",
|
|
49
|
+
"@simplewebauthn/types": "10.0.0",
|
|
47
50
|
"@types/react": "^18.2.55",
|
|
48
51
|
"concurrently": "9.2.4",
|
|
49
|
-
"publint": "0.3.
|
|
52
|
+
"publint": "0.3.21",
|
|
50
53
|
"react": "18.3.1",
|
|
51
54
|
"typescript": "5.9.3",
|
|
52
|
-
"vitest": "
|
|
55
|
+
"vitest": "3.2.6"
|
|
53
56
|
},
|
|
54
57
|
"engines": {
|
|
55
58
|
"node": ">=24"
|