@cedarjs/auth-dbauth-web 0.5.0 → 0.5.1-next.38
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/dist/dbAuth.d.ts +4 -4
- package/dist/dbAuth.d.ts.map +1 -1
- package/dist/dbAuth.js +44 -89
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -20
- package/dist/webAuthn.d.ts +1 -1
- package/dist/webAuthn.js +73 -60
- package/package.json +31 -14
- package/webAuthn/index.js +2 -1
- package/webAuthn/package.json +1 -1
|
@@ -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;;wCAEA,eAAgC,+BACb,OAAO;;EAI5B;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/dist/dbAuth.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { CurrentUser } from '@cedarjs/auth';
|
|
2
|
-
import type { WebAuthnClientType } from './webAuthn';
|
|
2
|
+
import type { WebAuthnClientType } from './webAuthn.js';
|
|
3
3
|
export interface LoginAttributes {
|
|
4
4
|
username: string;
|
|
5
5
|
password: string;
|
|
@@ -13,9 +13,9 @@ export declare function createAuth(dbAuthClient: ReturnType<typeof createDbAuthC
|
|
|
13
13
|
useCurrentUser?: () => Promise<CurrentUser>;
|
|
14
14
|
useHasRole?: (currentUser: CurrentUser | null) => (rolesToCheck: string | string[]) => boolean;
|
|
15
15
|
}): {
|
|
16
|
-
AuthContext: import("react").Context<import("@cedarjs/auth").AuthContextInterface<string | (() => void), LoginAttributes, any, unknown, boolean, SignupAttributes, any, any, ResetPasswordAttributes, any, any, import("./webAuthn").default> | undefined>;
|
|
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
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").default>;
|
|
18
|
+
useAuth: () => import("@cedarjs/auth").AuthContextInterface<string | (() => void), LoginAttributes, any, unknown, boolean, SignupAttributes, any, any, ResetPasswordAttributes, any, any, import("./webAuthn.js").default>;
|
|
19
19
|
};
|
|
20
20
|
export interface DbAuthClientArgs {
|
|
21
21
|
webAuthn?: InstanceType<WebAuthnClientType>;
|
|
@@ -27,7 +27,7 @@ export interface DbAuthClientArgs {
|
|
|
27
27
|
}
|
|
28
28
|
export declare function createDbAuthClient({ webAuthn, dbAuthUrl, fetchConfig, middleware, }?: DbAuthClientArgs): {
|
|
29
29
|
type: string;
|
|
30
|
-
client: import("./webAuthn").default | undefined;
|
|
30
|
+
client: import("./webAuthn.js").default | undefined;
|
|
31
31
|
login: ({ username, password }: LoginAttributes) => Promise<any>;
|
|
32
32
|
logout: () => Promise<boolean>;
|
|
33
33
|
signup: (attributes: SignupAttributes) => Promise<any>;
|
package/dist/dbAuth.d.ts.map
CHANGED
|
@@ -1 +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,
|
|
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;;wCAEA,eAAgC,+BACb,OAAO;;EAI5B;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"}
|
package/dist/dbAuth.js
CHANGED
|
@@ -1,29 +1,19 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
value: true
|
|
7
|
-
});
|
|
8
|
-
exports.createAuth = createAuth;
|
|
9
|
-
exports.createDbAuthClient = createDbAuthClient;
|
|
10
|
-
var _stringify = _interopRequireDefault(require("@babel/runtime-corejs3/core-js/json/stringify"));
|
|
11
|
-
var _auth = require("@cedarjs/auth");
|
|
12
|
-
const TOKEN_CACHE_TIME = 5000;
|
|
13
|
-
|
|
14
|
-
// This is the middleware-edition auth function
|
|
15
|
-
// Overrides the default getCurrentUser to fetch it from middleware instead
|
|
1
|
+
import {
|
|
2
|
+
createAuthentication,
|
|
3
|
+
getCurrentUserFromMiddleware
|
|
4
|
+
} from "@cedarjs/auth";
|
|
5
|
+
const TOKEN_CACHE_TIME = 5e3;
|
|
16
6
|
function createMiddlewareAuth(dbAuthClient, customProviderHooks) {
|
|
17
|
-
return
|
|
7
|
+
return createAuthentication(dbAuthClient, {
|
|
18
8
|
...customProviderHooks,
|
|
19
|
-
useCurrentUser: customProviderHooks?.useCurrentUser ?? (() =>
|
|
9
|
+
useCurrentUser: customProviderHooks?.useCurrentUser ?? (() => getCurrentUserFromMiddleware(dbAuthClient.getAuthUrl()))
|
|
20
10
|
});
|
|
21
11
|
}
|
|
22
12
|
function createAuth(dbAuthClient, customProviderHooks) {
|
|
23
13
|
if (dbAuthClient.middlewareAuthEnabled) {
|
|
24
14
|
return createMiddlewareAuth(dbAuthClient, customProviderHooks);
|
|
25
15
|
}
|
|
26
|
-
return
|
|
16
|
+
return createAuthentication(dbAuthClient, customProviderHooks);
|
|
27
17
|
}
|
|
28
18
|
function createDbAuthClient({
|
|
29
19
|
webAuthn,
|
|
@@ -31,10 +21,10 @@ function createDbAuthClient({
|
|
|
31
21
|
fetchConfig,
|
|
32
22
|
middleware = RWJS_ENV.RWJS_EXP_STREAMING_SSR
|
|
33
23
|
} = {}) {
|
|
34
|
-
const credentials = fetchConfig?.credentials ||
|
|
24
|
+
const credentials = fetchConfig?.credentials || "same-origin";
|
|
35
25
|
webAuthn?.setAuthApiUrl(dbAuthUrl);
|
|
36
26
|
let getTokenPromise;
|
|
37
|
-
let lastTokenCheckAt = new Date(
|
|
27
|
+
let lastTokenCheckAt = /* @__PURE__ */ new Date("1970-01-01T00:00:00");
|
|
38
28
|
let cachedToken;
|
|
39
29
|
const getDbAuthUrl = () => {
|
|
40
30
|
if (dbAuthUrl) {
|
|
@@ -47,43 +37,34 @@ function createDbAuthClient({
|
|
|
47
37
|
return fetch(...params);
|
|
48
38
|
};
|
|
49
39
|
const isTokenCacheExpired = () => {
|
|
50
|
-
const now = new Date();
|
|
40
|
+
const now = /* @__PURE__ */ new Date();
|
|
51
41
|
return now.getTime() - lastTokenCheckAt.getTime() > TOKEN_CACHE_TIME;
|
|
52
42
|
};
|
|
53
43
|
const resetTokenCache = () => {
|
|
54
|
-
lastTokenCheckAt = new Date(
|
|
44
|
+
lastTokenCheckAt = /* @__PURE__ */ new Date("1970-01-01T00:00:00");
|
|
55
45
|
cachedToken = null;
|
|
56
46
|
};
|
|
57
|
-
const forgotPassword = async username => {
|
|
47
|
+
const forgotPassword = async (username) => {
|
|
58
48
|
const response = await resetAndFetch(getDbAuthUrl(), {
|
|
59
49
|
credentials,
|
|
60
|
-
method:
|
|
61
|
-
headers: {
|
|
62
|
-
|
|
63
|
-
},
|
|
64
|
-
body: (0, _stringify.default)({
|
|
65
|
-
username,
|
|
66
|
-
method: 'forgotPassword'
|
|
67
|
-
})
|
|
50
|
+
method: "POST",
|
|
51
|
+
headers: { "Content-Type": "application/json" },
|
|
52
|
+
body: JSON.stringify({ username, method: "forgotPassword" })
|
|
68
53
|
});
|
|
69
54
|
return response.json();
|
|
70
55
|
};
|
|
71
56
|
const getToken = async () => {
|
|
72
|
-
// Middleware auth providers doesn't need a token
|
|
73
57
|
if (middleware) {
|
|
74
58
|
return null;
|
|
75
59
|
}
|
|
76
|
-
|
|
77
|
-
// Return the existing fetch promise, so that parallel calls
|
|
78
|
-
// to getToken only cause a single fetch
|
|
79
60
|
if (getTokenPromise) {
|
|
80
61
|
return getTokenPromise;
|
|
81
62
|
}
|
|
82
63
|
if (isTokenCacheExpired()) {
|
|
83
64
|
getTokenPromise = fetch(`${getDbAuthUrl()}?method=getToken`, {
|
|
84
65
|
credentials
|
|
85
|
-
}).then(response => response.text()).then(tokenText => {
|
|
86
|
-
lastTokenCheckAt = new Date();
|
|
66
|
+
}).then((response) => response.text()).then((tokenText) => {
|
|
67
|
+
lastTokenCheckAt = /* @__PURE__ */ new Date();
|
|
87
68
|
cachedToken = tokenText.length === 0 ? null : tokenText;
|
|
88
69
|
return cachedToken;
|
|
89
70
|
}).catch(() => {
|
|
@@ -95,86 +76,56 @@ function createDbAuthClient({
|
|
|
95
76
|
}
|
|
96
77
|
return cachedToken;
|
|
97
78
|
};
|
|
98
|
-
const login = async ({
|
|
99
|
-
username,
|
|
100
|
-
password
|
|
101
|
-
}) => {
|
|
79
|
+
const login = async ({ username, password }) => {
|
|
102
80
|
const response = await resetAndFetch(getDbAuthUrl(), {
|
|
103
81
|
credentials,
|
|
104
|
-
method:
|
|
105
|
-
headers: {
|
|
106
|
-
|
|
107
|
-
},
|
|
108
|
-
body: (0, _stringify.default)({
|
|
109
|
-
username,
|
|
110
|
-
password,
|
|
111
|
-
method: 'login'
|
|
112
|
-
})
|
|
82
|
+
method: "POST",
|
|
83
|
+
headers: { "Content-Type": "application/json" },
|
|
84
|
+
body: JSON.stringify({ username, password, method: "login" })
|
|
113
85
|
});
|
|
114
86
|
return response.json();
|
|
115
87
|
};
|
|
116
88
|
const logout = async () => {
|
|
117
89
|
await resetAndFetch(getDbAuthUrl(), {
|
|
118
90
|
credentials,
|
|
119
|
-
method:
|
|
120
|
-
body: (
|
|
121
|
-
method: 'logout'
|
|
122
|
-
})
|
|
91
|
+
method: "POST",
|
|
92
|
+
body: JSON.stringify({ method: "logout" })
|
|
123
93
|
});
|
|
124
94
|
return true;
|
|
125
95
|
};
|
|
126
|
-
const resetPassword = async attributes => {
|
|
96
|
+
const resetPassword = async (attributes) => {
|
|
127
97
|
const response = await resetAndFetch(getDbAuthUrl(), {
|
|
128
98
|
credentials,
|
|
129
|
-
method:
|
|
130
|
-
headers: {
|
|
131
|
-
|
|
132
|
-
},
|
|
133
|
-
body: (0, _stringify.default)({
|
|
134
|
-
...attributes,
|
|
135
|
-
method: 'resetPassword'
|
|
136
|
-
})
|
|
99
|
+
method: "POST",
|
|
100
|
+
headers: { "Content-Type": "application/json" },
|
|
101
|
+
body: JSON.stringify({ ...attributes, method: "resetPassword" })
|
|
137
102
|
});
|
|
138
103
|
return response.json();
|
|
139
104
|
};
|
|
140
|
-
const signup = async attributes => {
|
|
105
|
+
const signup = async (attributes) => {
|
|
141
106
|
const response = await resetAndFetch(getDbAuthUrl(), {
|
|
142
107
|
credentials,
|
|
143
|
-
method:
|
|
144
|
-
headers: {
|
|
145
|
-
|
|
146
|
-
},
|
|
147
|
-
body: (0, _stringify.default)({
|
|
148
|
-
...attributes,
|
|
149
|
-
method: 'signup'
|
|
150
|
-
})
|
|
108
|
+
method: "POST",
|
|
109
|
+
headers: { "Content-Type": "application/json" },
|
|
110
|
+
body: JSON.stringify({ ...attributes, method: "signup" })
|
|
151
111
|
});
|
|
152
112
|
return response.json();
|
|
153
113
|
};
|
|
154
|
-
const validateResetToken = async resetToken => {
|
|
114
|
+
const validateResetToken = async (resetToken) => {
|
|
155
115
|
const response = await resetAndFetch(getDbAuthUrl(), {
|
|
156
116
|
credentials,
|
|
157
|
-
method:
|
|
158
|
-
headers: {
|
|
159
|
-
|
|
160
|
-
},
|
|
161
|
-
body: (0, _stringify.default)({
|
|
162
|
-
resetToken,
|
|
163
|
-
method: 'validateResetToken'
|
|
164
|
-
})
|
|
117
|
+
method: "POST",
|
|
118
|
+
headers: { "Content-Type": "application/json" },
|
|
119
|
+
body: JSON.stringify({ resetToken, method: "validateResetToken" })
|
|
165
120
|
});
|
|
166
121
|
return response.json();
|
|
167
122
|
};
|
|
168
|
-
|
|
169
|
-
/**
|
|
170
|
-
* dbAuth doesn't implement the concept of userMetadata. We used to return the
|
|
171
|
-
* token (i.e. userId) as the userMetadata.
|
|
172
|
-
*/
|
|
173
123
|
const getUserMetadata = async () => {
|
|
174
|
-
return middleware ? () => {
|
|
124
|
+
return middleware ? () => {
|
|
125
|
+
} : getToken();
|
|
175
126
|
};
|
|
176
127
|
return {
|
|
177
|
-
type:
|
|
128
|
+
type: "dbAuth",
|
|
178
129
|
client: webAuthn,
|
|
179
130
|
login,
|
|
180
131
|
logout,
|
|
@@ -190,4 +141,8 @@ function createDbAuthClient({
|
|
|
190
141
|
// This is so that we can skip fetching getCurrentUser in reauthenticate
|
|
191
142
|
middlewareAuthEnabled: middleware
|
|
192
143
|
};
|
|
193
|
-
}
|
|
144
|
+
}
|
|
145
|
+
export {
|
|
146
|
+
createAuth,
|
|
147
|
+
createDbAuthClient
|
|
148
|
+
};
|
package/dist/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export * from './dbAuth';
|
|
1
|
+
export * from './dbAuth.js';
|
|
2
2
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -1,20 +1 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
var _context;
|
|
4
|
-
var _Object$defineProperty = require("@babel/runtime-corejs3/core-js/object/define-property");
|
|
5
|
-
var _forEachInstanceProperty = require("@babel/runtime-corejs3/core-js/instance/for-each");
|
|
6
|
-
var _Object$keys = require("@babel/runtime-corejs3/core-js/object/keys");
|
|
7
|
-
_Object$defineProperty(exports, "__esModule", {
|
|
8
|
-
value: true
|
|
9
|
-
});
|
|
10
|
-
var _dbAuth = require("./dbAuth");
|
|
11
|
-
_forEachInstanceProperty(_context = _Object$keys(_dbAuth)).call(_context, function (key) {
|
|
12
|
-
if (key === "default" || key === "__esModule") return;
|
|
13
|
-
if (key in exports && exports[key] === _dbAuth[key]) return;
|
|
14
|
-
_Object$defineProperty(exports, key, {
|
|
15
|
-
enumerable: true,
|
|
16
|
-
get: function () {
|
|
17
|
-
return _dbAuth[key];
|
|
18
|
-
}
|
|
19
|
-
});
|
|
20
|
-
});
|
|
1
|
+
export * from "./dbAuth.js";
|
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<any>;
|
|
6
6
|
isEnabled(): boolean;
|
|
7
7
|
private authenticationOptions;
|
|
8
8
|
authenticate(): Promise<boolean>;
|
package/dist/webAuthn.js
CHANGED
|
@@ -1,47 +1,37 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
var _Object$defineProperty = require("@babel/runtime-corejs3/core-js/object/define-property");
|
|
4
|
-
var _interopRequireDefault = require("@babel/runtime-corejs3/helpers/interopRequireDefault").default;
|
|
5
|
-
_Object$defineProperty(exports, "__esModule", {
|
|
6
|
-
value: true
|
|
7
|
-
});
|
|
8
|
-
exports.default = void 0;
|
|
9
|
-
var _stringify = _interopRequireDefault(require("@babel/runtime-corejs3/core-js/json/stringify"));
|
|
10
|
-
require("core-js/modules/esnext.json.parse.js");
|
|
11
1
|
class WebAuthnRegistrationError extends Error {
|
|
12
2
|
constructor(message) {
|
|
13
3
|
super(message);
|
|
14
|
-
this.name =
|
|
4
|
+
this.name = "WebAuthnRegistrationError";
|
|
15
5
|
}
|
|
16
6
|
}
|
|
17
7
|
class WebAuthnAuthenticationError extends Error {
|
|
18
8
|
constructor(message) {
|
|
19
9
|
super(message);
|
|
20
|
-
this.name =
|
|
10
|
+
this.name = "WebAuthnAuthenticationError";
|
|
21
11
|
}
|
|
22
12
|
}
|
|
23
13
|
class WebAuthnAlreadyRegisteredError extends WebAuthnRegistrationError {
|
|
24
14
|
constructor() {
|
|
25
|
-
super(
|
|
26
|
-
this.name =
|
|
15
|
+
super("This device is already registered");
|
|
16
|
+
this.name = "WebAuthnAlreadyRegisteredError";
|
|
27
17
|
}
|
|
28
18
|
}
|
|
29
19
|
class WebAuthnDeviceNotFoundError extends WebAuthnAuthenticationError {
|
|
30
20
|
constructor() {
|
|
31
|
-
super(
|
|
32
|
-
this.name =
|
|
21
|
+
super("WebAuthn device not found");
|
|
22
|
+
this.name = "WebAuthnDeviceNotFoundError";
|
|
33
23
|
}
|
|
34
24
|
}
|
|
35
25
|
class WebAuthnNoAuthenticatorError extends WebAuthnAuthenticationError {
|
|
36
26
|
constructor() {
|
|
37
|
-
super(
|
|
38
|
-
|
|
27
|
+
super(
|
|
28
|
+
"This device was not recognized. Use username/password login, or if you're using iOS you can try reloading this page"
|
|
29
|
+
);
|
|
30
|
+
this.name = "WebAuthnNoAuthenticatorError";
|
|
39
31
|
}
|
|
40
32
|
}
|
|
41
33
|
class WebAuthnClient {
|
|
42
|
-
|
|
43
|
-
this.authApiUrl = '';
|
|
44
|
-
}
|
|
34
|
+
authApiUrl = "";
|
|
45
35
|
getAuthApiUrl() {
|
|
46
36
|
return this.authApiUrl || `${RWJS_API_URL}/auth`;
|
|
47
37
|
}
|
|
@@ -51,13 +41,11 @@ class WebAuthnClient {
|
|
|
51
41
|
}
|
|
52
42
|
}
|
|
53
43
|
async isSupported() {
|
|
54
|
-
const {
|
|
55
|
-
browserSupportsWebAuthn
|
|
56
|
-
} = await import('@simplewebauthn/browser');
|
|
44
|
+
const { browserSupportsWebAuthn } = await import("@simplewebauthn/browser");
|
|
57
45
|
return browserSupportsWebAuthn();
|
|
58
46
|
}
|
|
59
47
|
isEnabled() {
|
|
60
|
-
if (typeof window ===
|
|
48
|
+
if (typeof window === "undefined") {
|
|
61
49
|
return false;
|
|
62
50
|
}
|
|
63
51
|
return !!/\bwebAuthn\b/.test(document.cookie);
|
|
@@ -67,47 +55,61 @@ class WebAuthnClient {
|
|
|
67
55
|
try {
|
|
68
56
|
const xhr = new XMLHttpRequest();
|
|
69
57
|
xhr.withCredentials = true;
|
|
70
|
-
xhr.open(
|
|
71
|
-
|
|
58
|
+
xhr.open(
|
|
59
|
+
"GET",
|
|
60
|
+
`${this.getAuthApiUrl()}?method=webAuthnAuthOptions`,
|
|
61
|
+
false
|
|
62
|
+
);
|
|
63
|
+
xhr.setRequestHeader("content-type", "application/json");
|
|
72
64
|
xhr.send(null);
|
|
73
65
|
options = JSON.parse(xhr.responseText);
|
|
74
66
|
if (xhr.status !== 200) {
|
|
75
67
|
if (options.error?.match(/username and password/)) {
|
|
76
68
|
throw new WebAuthnDeviceNotFoundError();
|
|
77
69
|
} else {
|
|
78
|
-
throw new WebAuthnAuthenticationError(
|
|
70
|
+
throw new WebAuthnAuthenticationError(
|
|
71
|
+
`Could not start authentication: ${options.error}`
|
|
72
|
+
);
|
|
79
73
|
}
|
|
80
74
|
}
|
|
81
75
|
} catch (e) {
|
|
82
76
|
console.error(e.message);
|
|
83
|
-
throw new WebAuthnAuthenticationError(
|
|
77
|
+
throw new WebAuthnAuthenticationError(
|
|
78
|
+
`Could not start authentication: ${e.message}`
|
|
79
|
+
);
|
|
84
80
|
}
|
|
85
81
|
return options;
|
|
86
82
|
}
|
|
87
83
|
async authenticate() {
|
|
88
84
|
const authOptions = await this.authenticationOptions();
|
|
89
|
-
const {
|
|
90
|
-
startAuthentication
|
|
91
|
-
} = await import('@simplewebauthn/browser');
|
|
85
|
+
const { startAuthentication } = await import("@simplewebauthn/browser");
|
|
92
86
|
try {
|
|
93
87
|
const browserResponse = await startAuthentication(authOptions);
|
|
94
88
|
const xhr = new XMLHttpRequest();
|
|
95
89
|
xhr.withCredentials = true;
|
|
96
|
-
xhr.open(
|
|
97
|
-
xhr.setRequestHeader(
|
|
98
|
-
xhr.send(
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
90
|
+
xhr.open("POST", this.getAuthApiUrl(), false);
|
|
91
|
+
xhr.setRequestHeader("content-type", "application/json");
|
|
92
|
+
xhr.send(
|
|
93
|
+
JSON.stringify({
|
|
94
|
+
method: "webAuthnAuthenticate",
|
|
95
|
+
...browserResponse
|
|
96
|
+
})
|
|
97
|
+
);
|
|
102
98
|
const options = JSON.parse(xhr.responseText);
|
|
103
99
|
if (xhr.status !== 200) {
|
|
104
|
-
throw new WebAuthnAuthenticationError(
|
|
100
|
+
throw new WebAuthnAuthenticationError(
|
|
101
|
+
`Could not complete authentication: ${options.error}`
|
|
102
|
+
);
|
|
105
103
|
}
|
|
106
104
|
} catch (e) {
|
|
107
|
-
if (e.message.match(
|
|
105
|
+
if (e.message.match(
|
|
106
|
+
/No available authenticator recognized any of the allowed credentials/
|
|
107
|
+
)) {
|
|
108
108
|
throw new WebAuthnNoAuthenticatorError();
|
|
109
109
|
} else {
|
|
110
|
-
throw new WebAuthnAuthenticationError(
|
|
110
|
+
throw new WebAuthnAuthenticationError(
|
|
111
|
+
`Error while authenticating: ${e.message}`
|
|
112
|
+
);
|
|
111
113
|
}
|
|
112
114
|
}
|
|
113
115
|
return true;
|
|
@@ -117,51 +119,62 @@ class WebAuthnClient {
|
|
|
117
119
|
try {
|
|
118
120
|
const xhr = new XMLHttpRequest();
|
|
119
121
|
xhr.withCredentials = true;
|
|
120
|
-
xhr.open(
|
|
121
|
-
|
|
122
|
+
xhr.open(
|
|
123
|
+
"GET",
|
|
124
|
+
`${this.getAuthApiUrl()}?method=webAuthnRegOptions`,
|
|
125
|
+
false
|
|
126
|
+
);
|
|
127
|
+
xhr.setRequestHeader("content-type", "application/json");
|
|
122
128
|
xhr.send(null);
|
|
123
129
|
options = JSON.parse(xhr.responseText);
|
|
124
130
|
if (xhr.status !== 200) {
|
|
125
|
-
throw new WebAuthnRegistrationError(
|
|
131
|
+
throw new WebAuthnRegistrationError(
|
|
132
|
+
`Could not start registration: ${options.error}`
|
|
133
|
+
);
|
|
126
134
|
}
|
|
127
135
|
} catch (e) {
|
|
128
136
|
console.error(e);
|
|
129
|
-
throw new WebAuthnRegistrationError(
|
|
137
|
+
throw new WebAuthnRegistrationError(
|
|
138
|
+
`Could not start registration: ${e.message}`
|
|
139
|
+
);
|
|
130
140
|
}
|
|
131
141
|
return options;
|
|
132
142
|
}
|
|
133
143
|
async register() {
|
|
134
144
|
const options = await this.registrationOptions();
|
|
135
145
|
let regResponse;
|
|
136
|
-
const {
|
|
137
|
-
startRegistration
|
|
138
|
-
} = await import('@simplewebauthn/browser');
|
|
146
|
+
const { startRegistration } = await import("@simplewebauthn/browser");
|
|
139
147
|
try {
|
|
140
148
|
regResponse = await startRegistration(options);
|
|
141
149
|
} catch (e) {
|
|
142
|
-
if (e.name ===
|
|
150
|
+
if (e.name === "InvalidStateError") {
|
|
143
151
|
throw new WebAuthnAlreadyRegisteredError();
|
|
144
152
|
} else {
|
|
145
|
-
throw new WebAuthnRegistrationError(
|
|
153
|
+
throw new WebAuthnRegistrationError(
|
|
154
|
+
`Error while registering: ${e.message}`
|
|
155
|
+
);
|
|
146
156
|
}
|
|
147
157
|
}
|
|
148
158
|
try {
|
|
149
159
|
const xhr = new XMLHttpRequest();
|
|
150
160
|
xhr.withCredentials = true;
|
|
151
|
-
xhr.open(
|
|
152
|
-
xhr.setRequestHeader(
|
|
153
|
-
xhr.send((
|
|
154
|
-
|
|
155
|
-
...regResponse
|
|
156
|
-
}));
|
|
157
|
-
const options = JSON.parse(xhr.responseText);
|
|
161
|
+
xhr.open("POST", this.getAuthApiUrl(), false);
|
|
162
|
+
xhr.setRequestHeader("content-type", "application/json");
|
|
163
|
+
xhr.send(JSON.stringify({ method: "webAuthnRegister", ...regResponse }));
|
|
164
|
+
const options2 = JSON.parse(xhr.responseText);
|
|
158
165
|
if (xhr.status !== 200) {
|
|
159
|
-
throw new WebAuthnRegistrationError(
|
|
166
|
+
throw new WebAuthnRegistrationError(
|
|
167
|
+
`Could not complete registration: ${options2.error}`
|
|
168
|
+
);
|
|
160
169
|
}
|
|
161
170
|
} catch (e) {
|
|
162
|
-
throw new WebAuthnRegistrationError(
|
|
171
|
+
throw new WebAuthnRegistrationError(
|
|
172
|
+
`Error while registering: ${e.message}`
|
|
173
|
+
);
|
|
163
174
|
}
|
|
164
175
|
return true;
|
|
165
176
|
}
|
|
166
177
|
}
|
|
167
|
-
|
|
178
|
+
export {
|
|
179
|
+
WebAuthnClient as default
|
|
180
|
+
};
|
package/package.json
CHANGED
|
@@ -1,45 +1,62 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cedarjs/auth-dbauth-web",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.1-next.38+78d2119a5",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/cedarjs/cedar.git",
|
|
7
7
|
"directory": "packages/auth-providers/dbAuth/web"
|
|
8
8
|
},
|
|
9
9
|
"license": "MIT",
|
|
10
|
-
"
|
|
10
|
+
"type": "module",
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"import": {
|
|
14
|
+
"types": "./dist/index.d.ts",
|
|
15
|
+
"default": "./dist/index.js"
|
|
16
|
+
},
|
|
17
|
+
"default": {
|
|
18
|
+
"types": "./dist/cjs/index.d.ts",
|
|
19
|
+
"default": "./dist/cjs/index.js"
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
"main": "./dist/cjs/index.js",
|
|
24
|
+
"module": "./dist/index.js",
|
|
11
25
|
"types": "./dist/index.d.ts",
|
|
12
26
|
"files": [
|
|
13
27
|
"dist",
|
|
14
28
|
"webAuthn"
|
|
15
29
|
],
|
|
16
30
|
"scripts": {
|
|
17
|
-
"build": "
|
|
18
|
-
"build:js": "babel src -d dist --extensions \".js,.jsx,.ts,.tsx\" --copy-files --no-copy-ignored",
|
|
31
|
+
"build": "tsx ./build.ts",
|
|
19
32
|
"build:pack": "yarn pack -o cedarjs-auth-dbauth-web.tgz",
|
|
20
|
-
"build:types": "tsc --build --verbose",
|
|
33
|
+
"build:types": "tsc --build --verbose ./tsconfig.build.json",
|
|
34
|
+
"build:types-cjs": "tsc --build --verbose ./tsconfig.cjs.json",
|
|
21
35
|
"build:watch": "nodemon --watch src --ext \"js,jsx,ts,tsx,template\" --ignore dist --exec \"yarn build\"",
|
|
36
|
+
"check:attw": "yarn rw-fwtools-attw",
|
|
37
|
+
"check:package": "concurrently npm:check:attw yarn:publint",
|
|
22
38
|
"prepublishOnly": "NODE_ENV=production yarn build",
|
|
23
|
-
"test": "
|
|
24
|
-
"test:watch": "
|
|
39
|
+
"test": "vitest run",
|
|
40
|
+
"test:watch": "vitest watch"
|
|
25
41
|
},
|
|
26
42
|
"dependencies": {
|
|
27
|
-
"@
|
|
28
|
-
"@
|
|
29
|
-
"@simplewebauthn/browser": "7.4.0",
|
|
30
|
-
"core-js": "3.42.0"
|
|
43
|
+
"@cedarjs/auth": "0.5.1-next.38+78d2119a5",
|
|
44
|
+
"@simplewebauthn/browser": "7.4.0"
|
|
31
45
|
},
|
|
32
46
|
"devDependencies": {
|
|
33
|
-
"@
|
|
34
|
-
"@
|
|
47
|
+
"@arethetypeswrong/cli": "0.18.2",
|
|
48
|
+
"@cedarjs/framework-tools": "0.5.1-next.38",
|
|
35
49
|
"@simplewebauthn/typescript-types": "7.4.0",
|
|
36
50
|
"@types/react": "^18.2.55",
|
|
51
|
+
"concurrently": "8.2.2",
|
|
52
|
+
"publint": "0.3.12",
|
|
37
53
|
"react": "18.3.1",
|
|
54
|
+
"tsx": "4.20.3",
|
|
38
55
|
"typescript": "5.6.2",
|
|
39
56
|
"vitest": "3.2.4"
|
|
40
57
|
},
|
|
41
58
|
"publishConfig": {
|
|
42
59
|
"access": "public"
|
|
43
60
|
},
|
|
44
|
-
"gitHead": "
|
|
61
|
+
"gitHead": "78d2119a507ed80faa9adb94b78d92662f134c4b"
|
|
45
62
|
}
|
package/webAuthn/index.js
CHANGED
package/webAuthn/package.json
CHANGED