mogh_ui 0.6.0 → 0.7.0
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/auth/index.cjs +10 -1
- package/dist/auth/index.cjs.map +1 -1
- package/dist/auth/index.d.cts +4 -3
- package/dist/auth/index.d.ts +4 -3
- package/dist/auth/index.js +9 -1
- package/dist/auth/index.js.map +1 -1
- package/dist/auth/login/header.d.cts +2 -2
- package/dist/auth/login/header.d.ts +2 -2
- package/dist/auth/login/index.cjs +32 -9
- package/dist/auth/login/index.cjs.map +1 -1
- package/dist/auth/login/index.d.cts +2 -2
- package/dist/auth/login/index.d.ts +2 -2
- package/dist/auth/login/index.js +41 -11
- package/dist/auth/login/index.js.map +1 -1
- package/dist/auth/profile/index.d.cts +1 -1
- package/dist/auth/profile/index.d.ts +1 -1
- package/dist/auth/profile/linked-logins.d.cts +2 -2
- package/dist/auth/profile/linked-logins.d.ts +2 -2
- package/dist/auth/profile/passkey.d.cts +2 -2
- package/dist/auth/profile/passkey.d.ts +2 -2
- package/dist/auth/profile/totp.d.cts +2 -2
- package/dist/auth/profile/totp.d.ts +2 -2
- package/dist/components/back-button.d.cts +2 -2
- package/dist/components/back-button.d.ts +2 -2
- package/dist/components/button-link.d.cts +2 -2
- package/dist/components/button-link.d.ts +2 -2
- package/dist/components/config/confirm.d.cts +2 -2
- package/dist/components/config/confirm.d.ts +2 -2
- package/dist/components/config/group.d.cts +1 -2
- package/dist/components/config/group.d.ts +1 -2
- package/dist/components/config/index.d.cts +3 -3
- package/dist/components/config/index.d.ts +3 -3
- package/dist/components/config/item.d.cts +3 -4
- package/dist/components/config/item.d.ts +3 -4
- package/dist/components/config/layout.d.cts +2 -2
- package/dist/components/config/layout.d.ts +2 -2
- package/dist/components/config/unsaved-changes.d.cts +2 -2
- package/dist/components/config/unsaved-changes.d.ts +2 -2
- package/dist/components/confirm-modal.d.cts +3 -3
- package/dist/components/confirm-modal.d.ts +3 -3
- package/dist/components/copy-button.d.cts +3 -3
- package/dist/components/copy-button.d.ts +3 -3
- package/dist/components/copy-text.d.cts +2 -2
- package/dist/components/copy-text.d.ts +2 -2
- package/dist/components/create-modal.d.cts +3 -3
- package/dist/components/create-modal.d.ts +3 -3
- package/dist/components/data-table.d.cts +3 -3
- package/dist/components/data-table.d.ts +3 -3
- package/dist/components/enable-switch.d.cts +2 -2
- package/dist/components/enable-switch.d.ts +2 -2
- package/dist/components/entity-header.d.cts +2 -2
- package/dist/components/entity-header.d.ts +2 -2
- package/dist/components/entity-page.d.cts +3 -3
- package/dist/components/entity-page.d.ts +3 -3
- package/dist/components/hover-error.d.cts +2 -2
- package/dist/components/hover-error.d.ts +2 -2
- package/dist/components/input-list.d.cts +2 -2
- package/dist/components/input-list.d.ts +2 -2
- package/dist/components/labelled-switch.d.cts +3 -3
- package/dist/components/labelled-switch.d.ts +3 -3
- package/dist/components/labels-group.d.cts +2 -2
- package/dist/components/labels-group.d.ts +2 -2
- package/dist/components/loading-screen.d.cts +2 -2
- package/dist/components/loading-screen.d.ts +2 -2
- package/dist/components/mobile-friendly-tabs.d.cts +5 -5
- package/dist/components/mobile-friendly-tabs.d.ts +5 -5
- package/dist/components/monaco/index.d.cts +3 -3
- package/dist/components/monaco/index.d.ts +3 -3
- package/dist/components/monaco/syntax/yaml.cjs +0 -13
- package/dist/components/monaco/syntax/yaml.cjs.map +1 -1
- package/dist/components/monaco/syntax/yaml.js +0 -13
- package/dist/components/monaco/syntax/yaml.js.map +1 -1
- package/dist/components/page-guard.d.cts +1 -2
- package/dist/components/page-guard.d.ts +1 -2
- package/dist/components/search-input.d.cts +2 -2
- package/dist/components/search-input.d.ts +2 -2
- package/dist/components/shared-text-update.d.cts +3 -3
- package/dist/components/shared-text-update.d.ts +3 -3
- package/dist/components/show-hide-button.d.cts +2 -2
- package/dist/components/show-hide-button.d.ts +2 -2
- package/dist/components/stat-bar.d.cts +3 -3
- package/dist/components/stat-bar.d.ts +3 -3
- package/dist/components/stat-cell.d.cts +3 -3
- package/dist/components/stat-cell.d.ts +3 -3
- package/dist/components/tabbed-page.d.cts +3 -3
- package/dist/components/tabbed-page.d.ts +3 -3
- package/dist/components/table-skeleton.d.cts +2 -2
- package/dist/components/table-skeleton.d.ts +2 -2
- package/dist/components/text-update-modal.d.cts +3 -3
- package/dist/components/text-update-modal.d.ts +3 -3
- package/dist/components/theme-toggle.d.cts +2 -2
- package/dist/components/theme-toggle.d.ts +2 -2
- package/dist/index.d.cts +1 -2
- package/dist/index.d.ts +1 -2
- package/dist/theme.d.cts +3 -3
- package/dist/theme.d.ts +3 -3
- package/package.json +26 -25
package/dist/auth/index.cjs
CHANGED
|
@@ -35,7 +35,8 @@ __export(auth_exports, {
|
|
|
35
35
|
useAuthState: () => useAuthState,
|
|
36
36
|
useLogin: () => useLogin,
|
|
37
37
|
useLoginOptions: () => useLoginOptions,
|
|
38
|
-
useManageAuth: () => useManageAuth
|
|
38
|
+
useManageAuth: () => useManageAuth,
|
|
39
|
+
useUserId: () => useUserId
|
|
39
40
|
});
|
|
40
41
|
module.exports = __toCommonJS(auth_exports);
|
|
41
42
|
var import_notifications = require("@mantine/notifications");
|
|
@@ -80,6 +81,13 @@ function useLogin(type, config) {
|
|
|
80
81
|
...config
|
|
81
82
|
});
|
|
82
83
|
}
|
|
84
|
+
function useUserId() {
|
|
85
|
+
return (0, import_react_query.useQuery)({
|
|
86
|
+
queryKey: [""],
|
|
87
|
+
queryFn: () => authClient().manage("GetUserId", {}),
|
|
88
|
+
enabled: !!MoghAuth.LOGIN_TOKENS.jwt()
|
|
89
|
+
});
|
|
90
|
+
}
|
|
83
91
|
function useManageAuth(type, config) {
|
|
84
92
|
return (0, import_react_query.useMutation)({
|
|
85
93
|
mutationKey: [type],
|
|
@@ -149,6 +157,7 @@ function useAuthState() {
|
|
|
149
157
|
useLogin,
|
|
150
158
|
useLoginOptions,
|
|
151
159
|
useManageAuth,
|
|
160
|
+
useUserId,
|
|
152
161
|
...require("./login"),
|
|
153
162
|
...require("./profile"),
|
|
154
163
|
...require("./utils")
|
package/dist/auth/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/auth/index.ts"],"sourcesContent":["import { notifications } from \"@mantine/notifications\";\nimport {\n useMutation,\n UseMutationOptions,\n useQuery,\n} from \"@tanstack/react-query\";\nimport * as MoghAuth from \"mogh_auth_client\";\nimport { sanitizeQueryInner } from \"./utils\";\n\nexport * from \"./login\";\nexport * from \"./profile\";\nexport * from \"./utils\";\n\nexport let AUTH_URL: string;\n\n/**\n * Set the global auth url.\n * Make sure to call this before first render.\n * @param url The global url\n */\nexport function setAuthUrl(url: string) {\n AUTH_URL = url;\n}\n\nexport function authClient() {\n return MoghAuth.MoghAuthClient(AUTH_URL, MoghAuth.LOGIN_TOKENS.jwt());\n}\n\nexport function useLoginOptions() {\n return useQuery({\n queryKey: [\"GetLoginOptions\"],\n queryFn: () => authClient().login(\"GetLoginOptions\", {}),\n });\n}\n\nexport function useLogin<\n T extends MoghAuth.Types.LoginRequest[\"type\"],\n R extends Extract<MoghAuth.Types.LoginRequest, { type: T }>,\n P extends R[\"params\"],\n C extends Omit<\n UseMutationOptions<MoghAuth.LoginResponses[T], unknown, P, unknown>,\n \"mutationKey\" | \"mutationFn\"\n >,\n>(type: T, config?: C) {\n return useMutation({\n mutationKey: [type],\n mutationFn: (params: P) => authClient().login<T, R>(type, params),\n onError: (e: { result: { error?: string; trace?: string[] } }, ...args) => {\n console.log(\"Login error:\", e);\n const msg = e.result.error ?? \"Unknown error. See console.\";\n const detail = e.result?.trace\n ?.map((msg) => msg[0].toUpperCase() + msg.slice(1))\n .join(\" | \");\n let msg_log = msg ? msg[0].toUpperCase() + msg.slice(1) + \" | \" : \"\";\n if (detail) {\n msg_log += detail + \" | \";\n }\n notifications.show({\n title: `Login request ${type} failed`,\n message: `${msg_log}See console for details`,\n color: \"red\",\n });\n config?.onError && config.onError(e, ...args);\n },\n ...config,\n });\n}\n\nexport function useManageAuth<\n T extends MoghAuth.Types.ManageRequest[\"type\"],\n R extends Extract<MoghAuth.Types.ManageRequest, { type: T }>,\n P extends R[\"params\"],\n C extends Omit<\n UseMutationOptions<MoghAuth.ManageResponses[T], unknown, P, unknown>,\n \"mutationKey\" | \"mutationFn\"\n >,\n>(type: T, config?: C) {\n return useMutation({\n mutationKey: [type],\n mutationFn: (params: P) => authClient().manage<T, R>(type, params),\n onError: (e: { result: { error?: string; trace?: string[] } }, ...args) => {\n console.log(\"Manage auth error:\", e);\n const msg = e.result.error ?? \"Unknown error. See console.\";\n const detail = e.result?.trace\n ?.map((msg) => msg[0].toUpperCase() + msg.slice(1))\n .join(\" | \");\n let msg_log = msg ? msg[0].toUpperCase() + msg.slice(1) + \" | \" : \"\";\n if (detail) {\n msg_log += detail + \" | \";\n }\n notifications.show({\n title: `Manage auth request ${type} failed`,\n message: `${msg_log}See console for details`,\n color: \"red\",\n });\n config?.onError && config.onError(e, ...args);\n },\n ...config,\n });\n}\n\nlet jwt_redeem_sent = false;\nlet passkey_sent = false;\n\n/// returns whether to show login / loading screen depending on state of exchange token loop\nexport function useAuthState() {\n const onSuccess = ({ jwt }: MoghAuth.Types.JwtResponse) => {\n MoghAuth.LOGIN_TOKENS.add_and_change(jwt);\n sanitizeQueryInner(search);\n };\n const { mutate: redeemJwt } = useLogin(\"ExchangeForJwt\", {\n onSuccess,\n });\n const { mutate: completePasskeyLogin } = useLogin(\"CompletePasskeyLogin\", {\n onSuccess,\n });\n const search = new URLSearchParams(location.search);\n\n const _passkey = search.get(\"passkey\");\n const passkey = _passkey\n ? JSON.parse(MoghAuth.Passkey.base64UrlDecode(_passkey))\n : null;\n\n // guard against multiple reqs sent\n // maybe isPending would do this but not sure about with render loop, this for sure will.\n if (passkey && !passkey_sent) {\n navigator.credentials\n .get(MoghAuth.Passkey.prepareRequestChallengeResponse(passkey))\n .then((credential) => completePasskeyLogin({ credential }))\n .catch((e) => {\n console.error(e);\n notifications.show({\n title: \"Failed to select passkey\",\n message: \"See console for details\",\n color: \"red\",\n });\n });\n passkey_sent = true;\n }\n\n const jwt_redeem_ready = search.get(\"redeem_ready\") === \"true\";\n\n // guard against multiple reqs sent\n // maybe isPending would do this but not sure about with render loop, this for sure will.\n if (jwt_redeem_ready && !jwt_redeem_sent) {\n redeemJwt({});\n jwt_redeem_sent = true;\n }\n\n return {\n jwt_redeem_ready,\n passkey_pending: !!passkey,\n totp: search.get(\"totp\") === \"true\",\n };\n}\n"],"mappings":"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","names":["msg"]}
|
|
1
|
+
{"version":3,"sources":["../../src/auth/index.ts"],"sourcesContent":["import { notifications } from \"@mantine/notifications\";\nimport {\n useMutation,\n UseMutationOptions,\n useQuery,\n} from \"@tanstack/react-query\";\nimport * as MoghAuth from \"mogh_auth_client\";\nimport { sanitizeQueryInner } from \"./utils\";\n\nexport * from \"./login\";\nexport * from \"./profile\";\nexport * from \"./utils\";\n\nexport let AUTH_URL: string;\n\n/**\n * Set the global auth url.\n * Make sure to call this before first render.\n * @param url The global url\n */\nexport function setAuthUrl(url: string) {\n AUTH_URL = url;\n}\n\nexport function authClient() {\n return MoghAuth.MoghAuthClient(AUTH_URL, MoghAuth.LOGIN_TOKENS.jwt());\n}\n\nexport function useLoginOptions() {\n return useQuery({\n queryKey: [\"GetLoginOptions\"],\n queryFn: () => authClient().login(\"GetLoginOptions\", {}),\n });\n}\n\nexport function useLogin<\n T extends MoghAuth.Types.LoginRequest[\"type\"],\n R extends Extract<MoghAuth.Types.LoginRequest, { type: T }>,\n P extends R[\"params\"],\n C extends Omit<\n UseMutationOptions<MoghAuth.LoginResponses[T], unknown, P, unknown>,\n \"mutationKey\" | \"mutationFn\"\n >,\n>(type: T, config?: C) {\n return useMutation({\n mutationKey: [type],\n mutationFn: (params: P) => authClient().login<T, R>(type, params),\n onError: (e: { result: { error?: string; trace?: string[] } }, ...args) => {\n console.log(\"Login error:\", e);\n const msg = e.result.error ?? \"Unknown error. See console.\";\n const detail = e.result?.trace\n ?.map((msg) => msg[0].toUpperCase() + msg.slice(1))\n .join(\" | \");\n let msg_log = msg ? msg[0].toUpperCase() + msg.slice(1) + \" | \" : \"\";\n if (detail) {\n msg_log += detail + \" | \";\n }\n notifications.show({\n title: `Login request ${type} failed`,\n message: `${msg_log}See console for details`,\n color: \"red\",\n });\n config?.onError && config.onError(e, ...args);\n },\n ...config,\n });\n}\n\nexport function useUserId() {\n return useQuery({\n queryKey: [\"\"],\n queryFn: () => authClient().manage(\"GetUserId\", {}),\n enabled: !!MoghAuth.LOGIN_TOKENS.jwt(),\n });\n}\n\nexport function useManageAuth<\n T extends MoghAuth.Types.ManageRequest[\"type\"],\n R extends Extract<MoghAuth.Types.ManageRequest, { type: T }>,\n P extends R[\"params\"],\n C extends Omit<\n UseMutationOptions<MoghAuth.ManageResponses[T], unknown, P, unknown>,\n \"mutationKey\" | \"mutationFn\"\n >,\n>(type: T, config?: C) {\n return useMutation({\n mutationKey: [type],\n mutationFn: (params: P) => authClient().manage<T, R>(type, params),\n onError: (e: { result: { error?: string; trace?: string[] } }, ...args) => {\n console.log(\"Manage auth error:\", e);\n const msg = e.result.error ?? \"Unknown error. See console.\";\n const detail = e.result?.trace\n ?.map((msg) => msg[0].toUpperCase() + msg.slice(1))\n .join(\" | \");\n let msg_log = msg ? msg[0].toUpperCase() + msg.slice(1) + \" | \" : \"\";\n if (detail) {\n msg_log += detail + \" | \";\n }\n notifications.show({\n title: `Manage auth request ${type} failed`,\n message: `${msg_log}See console for details`,\n color: \"red\",\n });\n config?.onError && config.onError(e, ...args);\n },\n ...config,\n });\n}\n\nlet jwt_redeem_sent = false;\nlet passkey_sent = false;\n\n/// returns whether to show login / loading screen depending on state of exchange token loop\nexport function useAuthState() {\n const onSuccess = ({ jwt }: MoghAuth.Types.JwtResponse) => {\n MoghAuth.LOGIN_TOKENS.add_and_change(jwt);\n sanitizeQueryInner(search);\n };\n const { mutate: redeemJwt } = useLogin(\"ExchangeForJwt\", {\n onSuccess,\n });\n const { mutate: completePasskeyLogin } = useLogin(\"CompletePasskeyLogin\", {\n onSuccess,\n });\n const search = new URLSearchParams(location.search);\n\n const _passkey = search.get(\"passkey\");\n const passkey = _passkey\n ? JSON.parse(MoghAuth.Passkey.base64UrlDecode(_passkey))\n : null;\n\n // guard against multiple reqs sent\n // maybe isPending would do this but not sure about with render loop, this for sure will.\n if (passkey && !passkey_sent) {\n navigator.credentials\n .get(MoghAuth.Passkey.prepareRequestChallengeResponse(passkey))\n .then((credential) => completePasskeyLogin({ credential }))\n .catch((e) => {\n console.error(e);\n notifications.show({\n title: \"Failed to select passkey\",\n message: \"See console for details\",\n color: \"red\",\n });\n });\n passkey_sent = true;\n }\n\n const jwt_redeem_ready = search.get(\"redeem_ready\") === \"true\";\n\n // guard against multiple reqs sent\n // maybe isPending would do this but not sure about with render loop, this for sure will.\n if (jwt_redeem_ready && !jwt_redeem_sent) {\n redeemJwt({});\n jwt_redeem_sent = true;\n }\n\n return {\n jwt_redeem_ready,\n passkey_pending: !!passkey,\n totp: search.get(\"totp\") === \"true\",\n };\n}\n"],"mappings":"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","names":["msg"]}
|
package/dist/auth/index.d.cts
CHANGED
|
@@ -6,7 +6,7 @@ export { LinkedLogins } from './profile/linked-logins.cjs';
|
|
|
6
6
|
export { EnrollPasskey } from './profile/passkey.cjs';
|
|
7
7
|
export { EnrollTotp } from './profile/totp.cjs';
|
|
8
8
|
export { sanitizeQuery, sanitizeQueryInner } from './utils.cjs';
|
|
9
|
-
import 'react
|
|
9
|
+
import 'react';
|
|
10
10
|
|
|
11
11
|
declare let AUTH_URL: string;
|
|
12
12
|
/**
|
|
@@ -24,7 +24,7 @@ declare function authClient(): {
|
|
|
24
24
|
}>>(type: T, params: Req["params"]) => Promise<MoghAuth.ManageResponses[Req["type"]]>;
|
|
25
25
|
externalLogin: (provider: MoghAuth.Types.ExternalLoginProvider) => void;
|
|
26
26
|
};
|
|
27
|
-
declare function useLoginOptions(): _tanstack_react_query.UseQueryResult<MoghAuth.Types.GetLoginOptionsResponse
|
|
27
|
+
declare function useLoginOptions(): _tanstack_react_query.UseQueryResult<NoInfer<MoghAuth.Types.GetLoginOptionsResponse>, Error>;
|
|
28
28
|
declare function useLogin<T extends MoghAuth.Types.LoginRequest["type"], R extends Extract<MoghAuth.Types.LoginRequest, {
|
|
29
29
|
type: T;
|
|
30
30
|
}>, P extends R["params"], C extends Omit<UseMutationOptions<MoghAuth.LoginResponses[T], unknown, P, unknown>, "mutationKey" | "mutationFn">>(type: T, config?: C): _tanstack_react_query.UseMutationResult<MoghAuth.LoginResponses[R["type"]], {
|
|
@@ -33,6 +33,7 @@ declare function useLogin<T extends MoghAuth.Types.LoginRequest["type"], R exten
|
|
|
33
33
|
trace?: string[];
|
|
34
34
|
};
|
|
35
35
|
}, P, unknown>;
|
|
36
|
+
declare function useUserId(): _tanstack_react_query.UseQueryResult<NoInfer<MoghAuth.Types.GetUserIdResponse>, Error>;
|
|
36
37
|
declare function useManageAuth<T extends MoghAuth.Types.ManageRequest["type"], R extends Extract<MoghAuth.Types.ManageRequest, {
|
|
37
38
|
type: T;
|
|
38
39
|
}>, P extends R["params"], C extends Omit<UseMutationOptions<MoghAuth.ManageResponses[T], unknown, P, unknown>, "mutationKey" | "mutationFn">>(type: T, config?: C): _tanstack_react_query.UseMutationResult<MoghAuth.ManageResponses[R["type"]], {
|
|
@@ -47,4 +48,4 @@ declare function useAuthState(): {
|
|
|
47
48
|
totp: boolean;
|
|
48
49
|
};
|
|
49
50
|
|
|
50
|
-
export { AUTH_URL, authClient, setAuthUrl, useAuthState, useLogin, useLoginOptions, useManageAuth };
|
|
51
|
+
export { AUTH_URL, authClient, setAuthUrl, useAuthState, useLogin, useLoginOptions, useManageAuth, useUserId };
|
package/dist/auth/index.d.ts
CHANGED
|
@@ -6,7 +6,7 @@ export { LinkedLogins } from './profile/linked-logins.js';
|
|
|
6
6
|
export { EnrollPasskey } from './profile/passkey.js';
|
|
7
7
|
export { EnrollTotp } from './profile/totp.js';
|
|
8
8
|
export { sanitizeQuery, sanitizeQueryInner } from './utils.js';
|
|
9
|
-
import 'react
|
|
9
|
+
import 'react';
|
|
10
10
|
|
|
11
11
|
declare let AUTH_URL: string;
|
|
12
12
|
/**
|
|
@@ -24,7 +24,7 @@ declare function authClient(): {
|
|
|
24
24
|
}>>(type: T, params: Req["params"]) => Promise<MoghAuth.ManageResponses[Req["type"]]>;
|
|
25
25
|
externalLogin: (provider: MoghAuth.Types.ExternalLoginProvider) => void;
|
|
26
26
|
};
|
|
27
|
-
declare function useLoginOptions(): _tanstack_react_query.UseQueryResult<MoghAuth.Types.GetLoginOptionsResponse
|
|
27
|
+
declare function useLoginOptions(): _tanstack_react_query.UseQueryResult<NoInfer<MoghAuth.Types.GetLoginOptionsResponse>, Error>;
|
|
28
28
|
declare function useLogin<T extends MoghAuth.Types.LoginRequest["type"], R extends Extract<MoghAuth.Types.LoginRequest, {
|
|
29
29
|
type: T;
|
|
30
30
|
}>, P extends R["params"], C extends Omit<UseMutationOptions<MoghAuth.LoginResponses[T], unknown, P, unknown>, "mutationKey" | "mutationFn">>(type: T, config?: C): _tanstack_react_query.UseMutationResult<MoghAuth.LoginResponses[R["type"]], {
|
|
@@ -33,6 +33,7 @@ declare function useLogin<T extends MoghAuth.Types.LoginRequest["type"], R exten
|
|
|
33
33
|
trace?: string[];
|
|
34
34
|
};
|
|
35
35
|
}, P, unknown>;
|
|
36
|
+
declare function useUserId(): _tanstack_react_query.UseQueryResult<NoInfer<MoghAuth.Types.GetUserIdResponse>, Error>;
|
|
36
37
|
declare function useManageAuth<T extends MoghAuth.Types.ManageRequest["type"], R extends Extract<MoghAuth.Types.ManageRequest, {
|
|
37
38
|
type: T;
|
|
38
39
|
}>, P extends R["params"], C extends Omit<UseMutationOptions<MoghAuth.ManageResponses[T], unknown, P, unknown>, "mutationKey" | "mutationFn">>(type: T, config?: C): _tanstack_react_query.UseMutationResult<MoghAuth.ManageResponses[R["type"]], {
|
|
@@ -47,4 +48,4 @@ declare function useAuthState(): {
|
|
|
47
48
|
totp: boolean;
|
|
48
49
|
};
|
|
49
50
|
|
|
50
|
-
export { AUTH_URL, authClient, setAuthUrl, useAuthState, useLogin, useLoginOptions, useManageAuth };
|
|
51
|
+
export { AUTH_URL, authClient, setAuthUrl, useAuthState, useLogin, useLoginOptions, useManageAuth, useUserId };
|
package/dist/auth/index.js
CHANGED
|
@@ -43,6 +43,13 @@ function useLogin(type, config) {
|
|
|
43
43
|
...config
|
|
44
44
|
});
|
|
45
45
|
}
|
|
46
|
+
function useUserId() {
|
|
47
|
+
return useQuery({
|
|
48
|
+
queryKey: [""],
|
|
49
|
+
queryFn: () => authClient().manage("GetUserId", {}),
|
|
50
|
+
enabled: !!MoghAuth.LOGIN_TOKENS.jwt()
|
|
51
|
+
});
|
|
52
|
+
}
|
|
46
53
|
function useManageAuth(type, config) {
|
|
47
54
|
return useMutation({
|
|
48
55
|
mutationKey: [type],
|
|
@@ -110,6 +117,7 @@ export {
|
|
|
110
117
|
useAuthState,
|
|
111
118
|
useLogin,
|
|
112
119
|
useLoginOptions,
|
|
113
|
-
useManageAuth
|
|
120
|
+
useManageAuth,
|
|
121
|
+
useUserId
|
|
114
122
|
};
|
|
115
123
|
//# sourceMappingURL=index.js.map
|
package/dist/auth/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/auth/index.ts"],"sourcesContent":["import { notifications } from \"@mantine/notifications\";\nimport {\n useMutation,\n UseMutationOptions,\n useQuery,\n} from \"@tanstack/react-query\";\nimport * as MoghAuth from \"mogh_auth_client\";\nimport { sanitizeQueryInner } from \"./utils\";\n\nexport * from \"./login\";\nexport * from \"./profile\";\nexport * from \"./utils\";\n\nexport let AUTH_URL: string;\n\n/**\n * Set the global auth url.\n * Make sure to call this before first render.\n * @param url The global url\n */\nexport function setAuthUrl(url: string) {\n AUTH_URL = url;\n}\n\nexport function authClient() {\n return MoghAuth.MoghAuthClient(AUTH_URL, MoghAuth.LOGIN_TOKENS.jwt());\n}\n\nexport function useLoginOptions() {\n return useQuery({\n queryKey: [\"GetLoginOptions\"],\n queryFn: () => authClient().login(\"GetLoginOptions\", {}),\n });\n}\n\nexport function useLogin<\n T extends MoghAuth.Types.LoginRequest[\"type\"],\n R extends Extract<MoghAuth.Types.LoginRequest, { type: T }>,\n P extends R[\"params\"],\n C extends Omit<\n UseMutationOptions<MoghAuth.LoginResponses[T], unknown, P, unknown>,\n \"mutationKey\" | \"mutationFn\"\n >,\n>(type: T, config?: C) {\n return useMutation({\n mutationKey: [type],\n mutationFn: (params: P) => authClient().login<T, R>(type, params),\n onError: (e: { result: { error?: string; trace?: string[] } }, ...args) => {\n console.log(\"Login error:\", e);\n const msg = e.result.error ?? \"Unknown error. See console.\";\n const detail = e.result?.trace\n ?.map((msg) => msg[0].toUpperCase() + msg.slice(1))\n .join(\" | \");\n let msg_log = msg ? msg[0].toUpperCase() + msg.slice(1) + \" | \" : \"\";\n if (detail) {\n msg_log += detail + \" | \";\n }\n notifications.show({\n title: `Login request ${type} failed`,\n message: `${msg_log}See console for details`,\n color: \"red\",\n });\n config?.onError && config.onError(e, ...args);\n },\n ...config,\n });\n}\n\nexport function useManageAuth<\n T extends MoghAuth.Types.ManageRequest[\"type\"],\n R extends Extract<MoghAuth.Types.ManageRequest, { type: T }>,\n P extends R[\"params\"],\n C extends Omit<\n UseMutationOptions<MoghAuth.ManageResponses[T], unknown, P, unknown>,\n \"mutationKey\" | \"mutationFn\"\n >,\n>(type: T, config?: C) {\n return useMutation({\n mutationKey: [type],\n mutationFn: (params: P) => authClient().manage<T, R>(type, params),\n onError: (e: { result: { error?: string; trace?: string[] } }, ...args) => {\n console.log(\"Manage auth error:\", e);\n const msg = e.result.error ?? \"Unknown error. See console.\";\n const detail = e.result?.trace\n ?.map((msg) => msg[0].toUpperCase() + msg.slice(1))\n .join(\" | \");\n let msg_log = msg ? msg[0].toUpperCase() + msg.slice(1) + \" | \" : \"\";\n if (detail) {\n msg_log += detail + \" | \";\n }\n notifications.show({\n title: `Manage auth request ${type} failed`,\n message: `${msg_log}See console for details`,\n color: \"red\",\n });\n config?.onError && config.onError(e, ...args);\n },\n ...config,\n });\n}\n\nlet jwt_redeem_sent = false;\nlet passkey_sent = false;\n\n/// returns whether to show login / loading screen depending on state of exchange token loop\nexport function useAuthState() {\n const onSuccess = ({ jwt }: MoghAuth.Types.JwtResponse) => {\n MoghAuth.LOGIN_TOKENS.add_and_change(jwt);\n sanitizeQueryInner(search);\n };\n const { mutate: redeemJwt } = useLogin(\"ExchangeForJwt\", {\n onSuccess,\n });\n const { mutate: completePasskeyLogin } = useLogin(\"CompletePasskeyLogin\", {\n onSuccess,\n });\n const search = new URLSearchParams(location.search);\n\n const _passkey = search.get(\"passkey\");\n const passkey = _passkey\n ? JSON.parse(MoghAuth.Passkey.base64UrlDecode(_passkey))\n : null;\n\n // guard against multiple reqs sent\n // maybe isPending would do this but not sure about with render loop, this for sure will.\n if (passkey && !passkey_sent) {\n navigator.credentials\n .get(MoghAuth.Passkey.prepareRequestChallengeResponse(passkey))\n .then((credential) => completePasskeyLogin({ credential }))\n .catch((e) => {\n console.error(e);\n notifications.show({\n title: \"Failed to select passkey\",\n message: \"See console for details\",\n color: \"red\",\n });\n });\n passkey_sent = true;\n }\n\n const jwt_redeem_ready = search.get(\"redeem_ready\") === \"true\";\n\n // guard against multiple reqs sent\n // maybe isPending would do this but not sure about with render loop, this for sure will.\n if (jwt_redeem_ready && !jwt_redeem_sent) {\n redeemJwt({});\n jwt_redeem_sent = true;\n }\n\n return {\n jwt_redeem_ready,\n passkey_pending: !!passkey,\n totp: search.get(\"totp\") === \"true\",\n };\n}\n"],"mappings":"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","names":["msg"]}
|
|
1
|
+
{"version":3,"sources":["../../src/auth/index.ts"],"sourcesContent":["import { notifications } from \"@mantine/notifications\";\nimport {\n useMutation,\n UseMutationOptions,\n useQuery,\n} from \"@tanstack/react-query\";\nimport * as MoghAuth from \"mogh_auth_client\";\nimport { sanitizeQueryInner } from \"./utils\";\n\nexport * from \"./login\";\nexport * from \"./profile\";\nexport * from \"./utils\";\n\nexport let AUTH_URL: string;\n\n/**\n * Set the global auth url.\n * Make sure to call this before first render.\n * @param url The global url\n */\nexport function setAuthUrl(url: string) {\n AUTH_URL = url;\n}\n\nexport function authClient() {\n return MoghAuth.MoghAuthClient(AUTH_URL, MoghAuth.LOGIN_TOKENS.jwt());\n}\n\nexport function useLoginOptions() {\n return useQuery({\n queryKey: [\"GetLoginOptions\"],\n queryFn: () => authClient().login(\"GetLoginOptions\", {}),\n });\n}\n\nexport function useLogin<\n T extends MoghAuth.Types.LoginRequest[\"type\"],\n R extends Extract<MoghAuth.Types.LoginRequest, { type: T }>,\n P extends R[\"params\"],\n C extends Omit<\n UseMutationOptions<MoghAuth.LoginResponses[T], unknown, P, unknown>,\n \"mutationKey\" | \"mutationFn\"\n >,\n>(type: T, config?: C) {\n return useMutation({\n mutationKey: [type],\n mutationFn: (params: P) => authClient().login<T, R>(type, params),\n onError: (e: { result: { error?: string; trace?: string[] } }, ...args) => {\n console.log(\"Login error:\", e);\n const msg = e.result.error ?? \"Unknown error. See console.\";\n const detail = e.result?.trace\n ?.map((msg) => msg[0].toUpperCase() + msg.slice(1))\n .join(\" | \");\n let msg_log = msg ? msg[0].toUpperCase() + msg.slice(1) + \" | \" : \"\";\n if (detail) {\n msg_log += detail + \" | \";\n }\n notifications.show({\n title: `Login request ${type} failed`,\n message: `${msg_log}See console for details`,\n color: \"red\",\n });\n config?.onError && config.onError(e, ...args);\n },\n ...config,\n });\n}\n\nexport function useUserId() {\n return useQuery({\n queryKey: [\"\"],\n queryFn: () => authClient().manage(\"GetUserId\", {}),\n enabled: !!MoghAuth.LOGIN_TOKENS.jwt(),\n });\n}\n\nexport function useManageAuth<\n T extends MoghAuth.Types.ManageRequest[\"type\"],\n R extends Extract<MoghAuth.Types.ManageRequest, { type: T }>,\n P extends R[\"params\"],\n C extends Omit<\n UseMutationOptions<MoghAuth.ManageResponses[T], unknown, P, unknown>,\n \"mutationKey\" | \"mutationFn\"\n >,\n>(type: T, config?: C) {\n return useMutation({\n mutationKey: [type],\n mutationFn: (params: P) => authClient().manage<T, R>(type, params),\n onError: (e: { result: { error?: string; trace?: string[] } }, ...args) => {\n console.log(\"Manage auth error:\", e);\n const msg = e.result.error ?? \"Unknown error. See console.\";\n const detail = e.result?.trace\n ?.map((msg) => msg[0].toUpperCase() + msg.slice(1))\n .join(\" | \");\n let msg_log = msg ? msg[0].toUpperCase() + msg.slice(1) + \" | \" : \"\";\n if (detail) {\n msg_log += detail + \" | \";\n }\n notifications.show({\n title: `Manage auth request ${type} failed`,\n message: `${msg_log}See console for details`,\n color: \"red\",\n });\n config?.onError && config.onError(e, ...args);\n },\n ...config,\n });\n}\n\nlet jwt_redeem_sent = false;\nlet passkey_sent = false;\n\n/// returns whether to show login / loading screen depending on state of exchange token loop\nexport function useAuthState() {\n const onSuccess = ({ jwt }: MoghAuth.Types.JwtResponse) => {\n MoghAuth.LOGIN_TOKENS.add_and_change(jwt);\n sanitizeQueryInner(search);\n };\n const { mutate: redeemJwt } = useLogin(\"ExchangeForJwt\", {\n onSuccess,\n });\n const { mutate: completePasskeyLogin } = useLogin(\"CompletePasskeyLogin\", {\n onSuccess,\n });\n const search = new URLSearchParams(location.search);\n\n const _passkey = search.get(\"passkey\");\n const passkey = _passkey\n ? JSON.parse(MoghAuth.Passkey.base64UrlDecode(_passkey))\n : null;\n\n // guard against multiple reqs sent\n // maybe isPending would do this but not sure about with render loop, this for sure will.\n if (passkey && !passkey_sent) {\n navigator.credentials\n .get(MoghAuth.Passkey.prepareRequestChallengeResponse(passkey))\n .then((credential) => completePasskeyLogin({ credential }))\n .catch((e) => {\n console.error(e);\n notifications.show({\n title: \"Failed to select passkey\",\n message: \"See console for details\",\n color: \"red\",\n });\n });\n passkey_sent = true;\n }\n\n const jwt_redeem_ready = search.get(\"redeem_ready\") === \"true\";\n\n // guard against multiple reqs sent\n // maybe isPending would do this but not sure about with render loop, this for sure will.\n if (jwt_redeem_ready && !jwt_redeem_sent) {\n redeemJwt({});\n jwt_redeem_sent = true;\n }\n\n return {\n jwt_redeem_ready,\n passkey_pending: !!passkey,\n totp: search.get(\"totp\") === \"true\",\n };\n}\n"],"mappings":"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","names":["msg"]}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as react from 'react';
|
|
2
2
|
import { LoginBrandingProps } from './index.cjs';
|
|
3
3
|
|
|
4
4
|
declare function LoginHeader({ secondFactorPending, appName, iconLink, iconLinkAlt, }: {
|
|
5
5
|
secondFactorPending: boolean;
|
|
6
|
-
} & LoginBrandingProps):
|
|
6
|
+
} & LoginBrandingProps): react.JSX.Element;
|
|
7
7
|
|
|
8
8
|
export { LoginHeader as default };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as react from 'react';
|
|
2
2
|
import { LoginBrandingProps } from './index.js';
|
|
3
3
|
|
|
4
4
|
declare function LoginHeader({ secondFactorPending, appName, iconLink, iconLinkAlt, }: {
|
|
5
5
|
secondFactorPending: boolean;
|
|
6
|
-
} & LoginBrandingProps):
|
|
6
|
+
} & LoginBrandingProps): react.JSX.Element;
|
|
7
7
|
|
|
8
8
|
export { LoginHeader as default };
|
|
@@ -54,6 +54,15 @@ function LoginPage({
|
|
|
54
54
|
);
|
|
55
55
|
const [totpIsPending, setTotpPending] = (0, import_react2.useState)(_totpIsPending ?? false);
|
|
56
56
|
const secondFactorPending = passkeyIsPending || totpIsPending;
|
|
57
|
+
const alreadyLoggedIn = (0, import__.useUserId)().data?.id;
|
|
58
|
+
(0, import_react2.useEffect)(() => {
|
|
59
|
+
if (options?.oidc_auto_redirect && options?.oidc && !secondFactorPending) {
|
|
60
|
+
const params = new URLSearchParams(location.search);
|
|
61
|
+
if (!params.has("disableAutoLogin")) {
|
|
62
|
+
(0, import__.authClient)().externalLogin(MoghAuth.Types.ExternalLoginProvider.Oidc);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}, [options?.oidc_auto_redirect, options?.oidc, secondFactorPending]);
|
|
57
66
|
const maybeNavigate = location.pathname.startsWith("/login") ? () => location.replace(
|
|
58
67
|
new URLSearchParams(location.search).get("backto") ?? "/"
|
|
59
68
|
) : void 0;
|
|
@@ -168,20 +177,34 @@ function LoginPage({
|
|
|
168
177
|
key: localForm.key("password")
|
|
169
178
|
}
|
|
170
179
|
),
|
|
171
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_core.Group, { mt: "sm", justify: "
|
|
172
|
-
|
|
173
|
-
|
|
180
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_core.Group, { mt: "sm", justify: "space-between", children: [
|
|
181
|
+
alreadyLoggedIn && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
182
|
+
import__.BackButton,
|
|
174
183
|
{
|
|
175
|
-
|
|
176
|
-
w: 110,
|
|
177
|
-
onClick: localForm.onSubmit((form) => signup(form)),
|
|
178
|
-
loading: signupPending,
|
|
179
|
-
children: "Sign Up"
|
|
184
|
+
to: new URLSearchParams(location.search).get("backto") ?? "/"
|
|
180
185
|
}
|
|
181
186
|
),
|
|
182
|
-
/* @__PURE__ */ (0, import_jsx_runtime.
|
|
187
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_core.Group, { justify: "end", children: [
|
|
188
|
+
showSignUp && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
189
|
+
import_core.Button,
|
|
190
|
+
{
|
|
191
|
+
variant: "outline",
|
|
192
|
+
w: 110,
|
|
193
|
+
onClick: localForm.onSubmit((form) => signup(form)),
|
|
194
|
+
loading: signupPending,
|
|
195
|
+
children: "Sign Up"
|
|
196
|
+
}
|
|
197
|
+
),
|
|
198
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_core.Button, { w: 110, type: "submit", loading: loginPending, children: "Log In" })
|
|
199
|
+
] })
|
|
183
200
|
] })
|
|
184
201
|
] }),
|
|
202
|
+
alreadyLoggedIn && !(options?.local && !secondFactorPending) && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_core.Group, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
203
|
+
import__.BackButton,
|
|
204
|
+
{
|
|
205
|
+
to: new URLSearchParams(location.search).get("backto") ?? "/"
|
|
206
|
+
}
|
|
207
|
+
) }),
|
|
185
208
|
passkeyIsPending && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_core.Group, { justify: "center", my: "lg", children: [
|
|
186
209
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.KeyRound, { size: "1.5rem" }),
|
|
187
210
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_core.Text, { size: "lg", children: "Provide your passkey to finish login..." }),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/auth/login/index.tsx"],"sourcesContent":["import {\n Button,\n Center,\n Fieldset,\n Group,\n Loader,\n PasswordInput,\n Text,\n TextInput,\n} from \"@mantine/core\";\nimport { useForm } from \"@mantine/form\";\nimport { notifications } from \"@mantine/notifications\";\nimport * as MoghAuth from \"mogh_auth_client\";\nimport { AlertTriangle, KeyRound } from \"lucide-react\";\nimport { useState } from \"react\";\nimport LoginHeader from \"./header\";\nimport { sanitizeQuery, useLogin, useLoginOptions } from \"../..\";\n\nexport interface LoginBrandingProps {\n appName: string;\n iconLink: string;\n iconLinkAlt: string;\n}\n\nexport function LoginPage({\n passkeyIsPending: _passkeyIsPending,\n totpIsPending: _totpIsPending,\n onLogin,\n exampleConfigLink,\n ...branding\n}: {\n passkeyIsPending?: boolean;\n totpIsPending?: boolean;\n onLogin?: () => void;\n exampleConfigLink: string;\n} & LoginBrandingProps) {\n const options = useLoginOptions().data;\n const [passkeyIsPending, setPasskeyPending] = useState(\n _passkeyIsPending ?? false,\n );\n const [totpIsPending, setTotpPending] = useState(_totpIsPending ?? false);\n const secondFactorPending = passkeyIsPending || totpIsPending;\n\n // If signing in another user, need to redirect away from /login manually\n const maybeNavigate = location.pathname.startsWith(\"/login\")\n ? () =>\n location.replace(\n new URLSearchParams(location.search).get(\"backto\") ?? \"/\",\n )\n : undefined;\n\n const onSuccess = ({ jwt }: MoghAuth.Types.JwtResponse) => {\n MoghAuth.LOGIN_TOKENS.add_and_change(jwt);\n onLogin?.();\n maybeNavigate?.();\n };\n\n const secondFactorOnSuccess = (res: MoghAuth.Types.JwtResponse) => {\n sanitizeQuery();\n onSuccess(res);\n };\n\n const { mutate: signup, isPending: signupPending } = useLogin(\n \"SignUpLocalUser\",\n {\n onSuccess,\n },\n );\n\n const { mutate: completePasskeyLogin } = useLogin(\"CompletePasskeyLogin\", {\n onSuccess: secondFactorOnSuccess,\n });\n\n const { mutate: completeTotpLogin, isPending: totpPending } = useLogin(\n \"CompleteTotpLogin\",\n {\n onSuccess: secondFactorOnSuccess,\n },\n );\n\n const { mutate: login, isPending: loginPending } = useLogin(\n \"LoginLocalUser\",\n {\n onSuccess: ({ type, data }) => {\n switch (type) {\n case \"Jwt\":\n return onSuccess(data);\n case \"Passkey\":\n setPasskeyPending(true);\n return navigator.credentials\n .get(MoghAuth.Passkey.prepareRequestChallengeResponse(data))\n .then((credential) => completePasskeyLogin({ credential }))\n .catch((e) => {\n console.error(e);\n notifications.show({\n title: \"Failed to select passkey\",\n message: \"See console for details\",\n color: \"red\",\n });\n });\n case \"Totp\":\n return setTotpPending(true);\n }\n },\n },\n );\n\n const noAuthConfigured =\n options !== undefined &&\n Object.values(options).every((value) => value === false);\n\n const showSignUp = options !== undefined && !options.registration_disabled;\n\n const localForm = useForm({\n mode: \"uncontrolled\",\n initialValues: {\n username: \"\",\n password: \"\",\n },\n validate: {\n username: (username) =>\n username.length ? null : \"Username cannot be empty\",\n password: (password) =>\n password.length ? null : \"Password cannot be empty\",\n },\n });\n\n const totpForm = useForm({\n mode: \"uncontrolled\",\n initialValues: {\n code: \"\",\n },\n validate: {\n code: (code) => (code.length === 6 ? null : \"Code should be 6 digits\"),\n },\n });\n\n return (\n <Center h=\"80vh\">\n <Fieldset\n legend={\n <LoginHeader\n secondFactorPending={secondFactorPending}\n {...branding}\n />\n }\n component=\"form\"\n onSubmit={\n totpIsPending\n ? totpForm.onSubmit((form) => completeTotpLogin(form))\n : (localForm.onSubmit((form) => login(form)) as any)\n }\n style={{ display: \"flex\", flexDirection: \"column\", gap: \"1rem\" }}\n miw={{ base: \"95vw\", xs: \"530px\" }}\n maw=\"95vw\"\n >\n {options?.local && !secondFactorPending && (\n <>\n <TextInput\n {...localForm.getInputProps(\"username\")}\n autoFocus\n label=\"Username\"\n placeholder=\"Enter username\"\n autoComplete=\"username\"\n autoCapitalize=\"off\"\n autoCorrect=\"off\"\n key={localForm.key(\"username\")}\n />\n <PasswordInput\n {...localForm.getInputProps(\"password\")}\n label=\"Password\"\n placeholder=\"Enter password\"\n autoComplete=\"password\"\n autoCapitalize=\"off\"\n autoCorrect=\"off\"\n key={localForm.key(\"password\")}\n />\n <Group mt=\"sm\" justify=\"end\">\n {showSignUp && (\n <Button\n variant=\"outline\"\n w={110}\n onClick={localForm.onSubmit((form) => signup(form)) as any}\n loading={signupPending}\n >\n Sign Up\n </Button>\n )}\n <Button w={110} type=\"submit\" loading={loginPending}>\n Log In\n </Button>\n </Group>\n </>\n )}\n\n {passkeyIsPending && (\n <Group justify=\"center\" my=\"lg\">\n <KeyRound size=\"1.5rem\" />\n <Text size=\"lg\">Provide your passkey to finish login...</Text>\n <Loader />\n </Group>\n )}\n\n {totpIsPending && (\n <>\n <TextInput\n {...totpForm.getInputProps(\"code\")}\n label={\n <Group gap=\"sm\">\n <KeyRound size=\"1rem\" />\n 2FA Code\n </Group>\n }\n autoComplete=\"code\"\n autoCapitalize=\"none\"\n autoCorrect=\"off\"\n autoFocus\n />\n <Group justify=\"end\">\n <Button\n w={110}\n variant=\"filled\"\n type=\"submit\"\n loading={totpPending}\n >\n Log In\n </Button>\n </Group>\n </>\n )}\n\n {noAuthConfigured && (\n <Group my=\"lg\">\n <AlertTriangle size=\"2rem\" />\n <Text>\n No login methods have been configured. <br />\n See the{\" \"}\n <a\n href={exampleConfigLink}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"hover-underline\"\n >\n <b>example config</b>\n </a>{\" \"}\n for information on configuring auth.\n </Text>\n </Group>\n )}\n </Fieldset>\n </Center>\n );\n}\n"],"mappings":"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","names":["import_react","LoginHeader"]}
|
|
1
|
+
{"version":3,"sources":["../../../src/auth/login/index.tsx"],"sourcesContent":["import {\n Button,\n Center,\n Fieldset,\n Group,\n Loader,\n PasswordInput,\n Text,\n TextInput,\n} from \"@mantine/core\";\nimport { useForm } from \"@mantine/form\";\nimport { notifications } from \"@mantine/notifications\";\nimport * as MoghAuth from \"mogh_auth_client\";\nimport { AlertTriangle, KeyRound } from \"lucide-react\";\nimport { useEffect, useState } from \"react\";\nimport LoginHeader from \"./header\";\nimport {\n authClient,\n BackButton,\n sanitizeQuery,\n useLogin,\n useLoginOptions,\n useUserId,\n} from \"../..\";\n\nexport interface LoginBrandingProps {\n appName: string;\n iconLink: string;\n iconLinkAlt: string;\n}\n\nexport function LoginPage({\n passkeyIsPending: _passkeyIsPending,\n totpIsPending: _totpIsPending,\n onLogin,\n exampleConfigLink,\n ...branding\n}: {\n passkeyIsPending?: boolean;\n totpIsPending?: boolean;\n onLogin?: () => void;\n exampleConfigLink: string;\n} & LoginBrandingProps) {\n const options = useLoginOptions().data;\n const [passkeyIsPending, setPasskeyPending] = useState(\n _passkeyIsPending ?? false,\n );\n const [totpIsPending, setTotpPending] = useState(_totpIsPending ?? false);\n const secondFactorPending = passkeyIsPending || totpIsPending;\n\n const alreadyLoggedIn = useUserId().data?.id!!;\n\n // Auto-redirect to OIDC provider if configured and disableAutoLogin is not set\n useEffect(() => {\n if (options?.oidc_auto_redirect && options?.oidc && !secondFactorPending) {\n const params = new URLSearchParams(location.search);\n if (!params.has(\"disableAutoLogin\")) {\n authClient().externalLogin(MoghAuth.Types.ExternalLoginProvider.Oidc);\n }\n }\n }, [options?.oidc_auto_redirect, options?.oidc, secondFactorPending]);\n\n // If signing in another user, need to redirect away from /login manually\n const maybeNavigate = location.pathname.startsWith(\"/login\")\n ? () =>\n location.replace(\n new URLSearchParams(location.search).get(\"backto\") ?? \"/\",\n )\n : undefined;\n\n const onSuccess = ({ jwt }: MoghAuth.Types.JwtResponse) => {\n MoghAuth.LOGIN_TOKENS.add_and_change(jwt);\n onLogin?.();\n maybeNavigate?.();\n };\n\n const secondFactorOnSuccess = (res: MoghAuth.Types.JwtResponse) => {\n sanitizeQuery();\n onSuccess(res);\n };\n\n const { mutate: signup, isPending: signupPending } = useLogin(\n \"SignUpLocalUser\",\n {\n onSuccess,\n },\n );\n\n const { mutate: completePasskeyLogin } = useLogin(\"CompletePasskeyLogin\", {\n onSuccess: secondFactorOnSuccess,\n });\n\n const { mutate: completeTotpLogin, isPending: totpPending } = useLogin(\n \"CompleteTotpLogin\",\n {\n onSuccess: secondFactorOnSuccess,\n },\n );\n\n const { mutate: login, isPending: loginPending } = useLogin(\n \"LoginLocalUser\",\n {\n onSuccess: ({ type, data }) => {\n switch (type) {\n case \"Jwt\":\n return onSuccess(data);\n case \"Passkey\":\n setPasskeyPending(true);\n return navigator.credentials\n .get(MoghAuth.Passkey.prepareRequestChallengeResponse(data))\n .then((credential) => completePasskeyLogin({ credential }))\n .catch((e) => {\n console.error(e);\n notifications.show({\n title: \"Failed to select passkey\",\n message: \"See console for details\",\n color: \"red\",\n });\n });\n case \"Totp\":\n return setTotpPending(true);\n }\n },\n },\n );\n\n const noAuthConfigured =\n options !== undefined &&\n Object.values(options).every((value) => value === false);\n\n const showSignUp = options !== undefined && !options.registration_disabled;\n\n const localForm = useForm({\n mode: \"uncontrolled\",\n initialValues: {\n username: \"\",\n password: \"\",\n },\n validate: {\n username: (username) =>\n username.length ? null : \"Username cannot be empty\",\n password: (password) =>\n password.length ? null : \"Password cannot be empty\",\n },\n });\n\n const totpForm = useForm({\n mode: \"uncontrolled\",\n initialValues: {\n code: \"\",\n },\n validate: {\n code: (code) => (code.length === 6 ? null : \"Code should be 6 digits\"),\n },\n });\n\n return (\n <Center h=\"80vh\">\n <Fieldset\n legend={\n <LoginHeader\n secondFactorPending={secondFactorPending}\n {...branding}\n />\n }\n component=\"form\"\n onSubmit={\n totpIsPending\n ? totpForm.onSubmit((form) => completeTotpLogin(form))\n : (localForm.onSubmit((form) => login(form)) as any)\n }\n style={{ display: \"flex\", flexDirection: \"column\", gap: \"1rem\" }}\n miw={{ base: \"95vw\", xs: \"530px\" }}\n maw=\"95vw\"\n >\n {options?.local && !secondFactorPending && (\n <>\n <TextInput\n {...localForm.getInputProps(\"username\")}\n autoFocus\n label=\"Username\"\n placeholder=\"Enter username\"\n autoComplete=\"username\"\n autoCapitalize=\"off\"\n autoCorrect=\"off\"\n key={localForm.key(\"username\")}\n />\n <PasswordInput\n {...localForm.getInputProps(\"password\")}\n label=\"Password\"\n placeholder=\"Enter password\"\n autoComplete=\"password\"\n autoCapitalize=\"off\"\n autoCorrect=\"off\"\n key={localForm.key(\"password\")}\n />\n <Group mt=\"sm\" justify=\"space-between\">\n {alreadyLoggedIn && (\n <BackButton\n to={new URLSearchParams(location.search).get(\"backto\") ?? \"/\"}\n />\n )}\n <Group justify=\"end\">\n {showSignUp && (\n <Button\n variant=\"outline\"\n w={110}\n onClick={localForm.onSubmit((form) => signup(form)) as any}\n loading={signupPending}\n >\n Sign Up\n </Button>\n )}\n <Button w={110} type=\"submit\" loading={loginPending}>\n Log In\n </Button>\n </Group>\n </Group>\n </>\n )}\n\n {alreadyLoggedIn && !(options?.local && !secondFactorPending) && (\n <Group>\n <BackButton\n to={new URLSearchParams(location.search).get(\"backto\") ?? \"/\"}\n />\n </Group>\n )}\n\n {passkeyIsPending && (\n <Group justify=\"center\" my=\"lg\">\n <KeyRound size=\"1.5rem\" />\n <Text size=\"lg\">Provide your passkey to finish login...</Text>\n <Loader />\n </Group>\n )}\n\n {totpIsPending && (\n <>\n <TextInput\n {...totpForm.getInputProps(\"code\")}\n label={\n <Group gap=\"sm\">\n <KeyRound size=\"1rem\" />\n 2FA Code\n </Group>\n }\n autoComplete=\"code\"\n autoCapitalize=\"none\"\n autoCorrect=\"off\"\n autoFocus\n />\n <Group justify=\"end\">\n <Button\n w={110}\n variant=\"filled\"\n type=\"submit\"\n loading={totpPending}\n >\n Log In\n </Button>\n </Group>\n </>\n )}\n\n {noAuthConfigured && (\n <Group my=\"lg\">\n <AlertTriangle size=\"2rem\" />\n <Text>\n No login methods have been configured. <br />\n See the{\" \"}\n <a\n href={exampleConfigLink}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"hover-underline\"\n >\n <b>example config</b>\n </a>{\" \"}\n for information on configuring auth.\n </Text>\n </Group>\n )}\n </Fieldset>\n </Center>\n );\n}\n"],"mappings":"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","names":["import_react","LoginHeader"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as react from 'react';
|
|
2
2
|
|
|
3
3
|
interface LoginBrandingProps {
|
|
4
4
|
appName: string;
|
|
@@ -10,6 +10,6 @@ declare function LoginPage({ passkeyIsPending: _passkeyIsPending, totpIsPending:
|
|
|
10
10
|
totpIsPending?: boolean;
|
|
11
11
|
onLogin?: () => void;
|
|
12
12
|
exampleConfigLink: string;
|
|
13
|
-
} & LoginBrandingProps):
|
|
13
|
+
} & LoginBrandingProps): react.JSX.Element;
|
|
14
14
|
|
|
15
15
|
export { type LoginBrandingProps, LoginPage };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as react from 'react';
|
|
2
2
|
|
|
3
3
|
interface LoginBrandingProps {
|
|
4
4
|
appName: string;
|
|
@@ -10,6 +10,6 @@ declare function LoginPage({ passkeyIsPending: _passkeyIsPending, totpIsPending:
|
|
|
10
10
|
totpIsPending?: boolean;
|
|
11
11
|
onLogin?: () => void;
|
|
12
12
|
exampleConfigLink: string;
|
|
13
|
-
} & LoginBrandingProps):
|
|
13
|
+
} & LoginBrandingProps): react.JSX.Element;
|
|
14
14
|
|
|
15
15
|
export { type LoginBrandingProps, LoginPage };
|
package/dist/auth/login/index.js
CHANGED
|
@@ -14,9 +14,16 @@ import { useForm } from "@mantine/form";
|
|
|
14
14
|
import { notifications } from "@mantine/notifications";
|
|
15
15
|
import * as MoghAuth from "mogh_auth_client";
|
|
16
16
|
import { AlertTriangle, KeyRound } from "lucide-react";
|
|
17
|
-
import { useState } from "react";
|
|
17
|
+
import { useEffect, useState } from "react";
|
|
18
18
|
import LoginHeader from "./header";
|
|
19
|
-
import {
|
|
19
|
+
import {
|
|
20
|
+
authClient,
|
|
21
|
+
BackButton,
|
|
22
|
+
sanitizeQuery,
|
|
23
|
+
useLogin,
|
|
24
|
+
useLoginOptions,
|
|
25
|
+
useUserId
|
|
26
|
+
} from "../..";
|
|
20
27
|
function LoginPage({
|
|
21
28
|
passkeyIsPending: _passkeyIsPending,
|
|
22
29
|
totpIsPending: _totpIsPending,
|
|
@@ -30,6 +37,15 @@ function LoginPage({
|
|
|
30
37
|
);
|
|
31
38
|
const [totpIsPending, setTotpPending] = useState(_totpIsPending ?? false);
|
|
32
39
|
const secondFactorPending = passkeyIsPending || totpIsPending;
|
|
40
|
+
const alreadyLoggedIn = useUserId().data?.id;
|
|
41
|
+
useEffect(() => {
|
|
42
|
+
if (options?.oidc_auto_redirect && options?.oidc && !secondFactorPending) {
|
|
43
|
+
const params = new URLSearchParams(location.search);
|
|
44
|
+
if (!params.has("disableAutoLogin")) {
|
|
45
|
+
authClient().externalLogin(MoghAuth.Types.ExternalLoginProvider.Oidc);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}, [options?.oidc_auto_redirect, options?.oidc, secondFactorPending]);
|
|
33
49
|
const maybeNavigate = location.pathname.startsWith("/login") ? () => location.replace(
|
|
34
50
|
new URLSearchParams(location.search).get("backto") ?? "/"
|
|
35
51
|
) : void 0;
|
|
@@ -144,20 +160,34 @@ function LoginPage({
|
|
|
144
160
|
key: localForm.key("password")
|
|
145
161
|
}
|
|
146
162
|
),
|
|
147
|
-
/* @__PURE__ */ jsxs(Group, { mt: "sm", justify: "
|
|
148
|
-
|
|
149
|
-
|
|
163
|
+
/* @__PURE__ */ jsxs(Group, { mt: "sm", justify: "space-between", children: [
|
|
164
|
+
alreadyLoggedIn && /* @__PURE__ */ jsx(
|
|
165
|
+
BackButton,
|
|
150
166
|
{
|
|
151
|
-
|
|
152
|
-
w: 110,
|
|
153
|
-
onClick: localForm.onSubmit((form) => signup(form)),
|
|
154
|
-
loading: signupPending,
|
|
155
|
-
children: "Sign Up"
|
|
167
|
+
to: new URLSearchParams(location.search).get("backto") ?? "/"
|
|
156
168
|
}
|
|
157
169
|
),
|
|
158
|
-
/* @__PURE__ */
|
|
170
|
+
/* @__PURE__ */ jsxs(Group, { justify: "end", children: [
|
|
171
|
+
showSignUp && /* @__PURE__ */ jsx(
|
|
172
|
+
Button,
|
|
173
|
+
{
|
|
174
|
+
variant: "outline",
|
|
175
|
+
w: 110,
|
|
176
|
+
onClick: localForm.onSubmit((form) => signup(form)),
|
|
177
|
+
loading: signupPending,
|
|
178
|
+
children: "Sign Up"
|
|
179
|
+
}
|
|
180
|
+
),
|
|
181
|
+
/* @__PURE__ */ jsx(Button, { w: 110, type: "submit", loading: loginPending, children: "Log In" })
|
|
182
|
+
] })
|
|
159
183
|
] })
|
|
160
184
|
] }),
|
|
185
|
+
alreadyLoggedIn && !(options?.local && !secondFactorPending) && /* @__PURE__ */ jsx(Group, { children: /* @__PURE__ */ jsx(
|
|
186
|
+
BackButton,
|
|
187
|
+
{
|
|
188
|
+
to: new URLSearchParams(location.search).get("backto") ?? "/"
|
|
189
|
+
}
|
|
190
|
+
) }),
|
|
161
191
|
passkeyIsPending && /* @__PURE__ */ jsxs(Group, { justify: "center", my: "lg", children: [
|
|
162
192
|
/* @__PURE__ */ jsx(KeyRound, { size: "1.5rem" }),
|
|
163
193
|
/* @__PURE__ */ jsx(Text, { size: "lg", children: "Provide your passkey to finish login..." }),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/auth/login/index.tsx"],"sourcesContent":["import {\n Button,\n Center,\n Fieldset,\n Group,\n Loader,\n PasswordInput,\n Text,\n TextInput,\n} from \"@mantine/core\";\nimport { useForm } from \"@mantine/form\";\nimport { notifications } from \"@mantine/notifications\";\nimport * as MoghAuth from \"mogh_auth_client\";\nimport { AlertTriangle, KeyRound } from \"lucide-react\";\nimport { useState } from \"react\";\nimport LoginHeader from \"./header\";\nimport { sanitizeQuery, useLogin, useLoginOptions } from \"../..\";\n\nexport interface LoginBrandingProps {\n appName: string;\n iconLink: string;\n iconLinkAlt: string;\n}\n\nexport function LoginPage({\n passkeyIsPending: _passkeyIsPending,\n totpIsPending: _totpIsPending,\n onLogin,\n exampleConfigLink,\n ...branding\n}: {\n passkeyIsPending?: boolean;\n totpIsPending?: boolean;\n onLogin?: () => void;\n exampleConfigLink: string;\n} & LoginBrandingProps) {\n const options = useLoginOptions().data;\n const [passkeyIsPending, setPasskeyPending] = useState(\n _passkeyIsPending ?? false,\n );\n const [totpIsPending, setTotpPending] = useState(_totpIsPending ?? false);\n const secondFactorPending = passkeyIsPending || totpIsPending;\n\n // If signing in another user, need to redirect away from /login manually\n const maybeNavigate = location.pathname.startsWith(\"/login\")\n ? () =>\n location.replace(\n new URLSearchParams(location.search).get(\"backto\") ?? \"/\",\n )\n : undefined;\n\n const onSuccess = ({ jwt }: MoghAuth.Types.JwtResponse) => {\n MoghAuth.LOGIN_TOKENS.add_and_change(jwt);\n onLogin?.();\n maybeNavigate?.();\n };\n\n const secondFactorOnSuccess = (res: MoghAuth.Types.JwtResponse) => {\n sanitizeQuery();\n onSuccess(res);\n };\n\n const { mutate: signup, isPending: signupPending } = useLogin(\n \"SignUpLocalUser\",\n {\n onSuccess,\n },\n );\n\n const { mutate: completePasskeyLogin } = useLogin(\"CompletePasskeyLogin\", {\n onSuccess: secondFactorOnSuccess,\n });\n\n const { mutate: completeTotpLogin, isPending: totpPending } = useLogin(\n \"CompleteTotpLogin\",\n {\n onSuccess: secondFactorOnSuccess,\n },\n );\n\n const { mutate: login, isPending: loginPending } = useLogin(\n \"LoginLocalUser\",\n {\n onSuccess: ({ type, data }) => {\n switch (type) {\n case \"Jwt\":\n return onSuccess(data);\n case \"Passkey\":\n setPasskeyPending(true);\n return navigator.credentials\n .get(MoghAuth.Passkey.prepareRequestChallengeResponse(data))\n .then((credential) => completePasskeyLogin({ credential }))\n .catch((e) => {\n console.error(e);\n notifications.show({\n title: \"Failed to select passkey\",\n message: \"See console for details\",\n color: \"red\",\n });\n });\n case \"Totp\":\n return setTotpPending(true);\n }\n },\n },\n );\n\n const noAuthConfigured =\n options !== undefined &&\n Object.values(options).every((value) => value === false);\n\n const showSignUp = options !== undefined && !options.registration_disabled;\n\n const localForm = useForm({\n mode: \"uncontrolled\",\n initialValues: {\n username: \"\",\n password: \"\",\n },\n validate: {\n username: (username) =>\n username.length ? null : \"Username cannot be empty\",\n password: (password) =>\n password.length ? null : \"Password cannot be empty\",\n },\n });\n\n const totpForm = useForm({\n mode: \"uncontrolled\",\n initialValues: {\n code: \"\",\n },\n validate: {\n code: (code) => (code.length === 6 ? null : \"Code should be 6 digits\"),\n },\n });\n\n return (\n <Center h=\"80vh\">\n <Fieldset\n legend={\n <LoginHeader\n secondFactorPending={secondFactorPending}\n {...branding}\n />\n }\n component=\"form\"\n onSubmit={\n totpIsPending\n ? totpForm.onSubmit((form) => completeTotpLogin(form))\n : (localForm.onSubmit((form) => login(form)) as any)\n }\n style={{ display: \"flex\", flexDirection: \"column\", gap: \"1rem\" }}\n miw={{ base: \"95vw\", xs: \"530px\" }}\n maw=\"95vw\"\n >\n {options?.local && !secondFactorPending && (\n <>\n <TextInput\n {...localForm.getInputProps(\"username\")}\n autoFocus\n label=\"Username\"\n placeholder=\"Enter username\"\n autoComplete=\"username\"\n autoCapitalize=\"off\"\n autoCorrect=\"off\"\n key={localForm.key(\"username\")}\n />\n <PasswordInput\n {...localForm.getInputProps(\"password\")}\n label=\"Password\"\n placeholder=\"Enter password\"\n autoComplete=\"password\"\n autoCapitalize=\"off\"\n autoCorrect=\"off\"\n key={localForm.key(\"password\")}\n />\n <Group mt=\"sm\" justify=\"end\">\n {showSignUp && (\n <Button\n variant=\"outline\"\n w={110}\n onClick={localForm.onSubmit((form) => signup(form)) as any}\n loading={signupPending}\n >\n Sign Up\n </Button>\n )}\n <Button w={110} type=\"submit\" loading={loginPending}>\n Log In\n </Button>\n </Group>\n </>\n )}\n\n {passkeyIsPending && (\n <Group justify=\"center\" my=\"lg\">\n <KeyRound size=\"1.5rem\" />\n <Text size=\"lg\">Provide your passkey to finish login...</Text>\n <Loader />\n </Group>\n )}\n\n {totpIsPending && (\n <>\n <TextInput\n {...totpForm.getInputProps(\"code\")}\n label={\n <Group gap=\"sm\">\n <KeyRound size=\"1rem\" />\n 2FA Code\n </Group>\n }\n autoComplete=\"code\"\n autoCapitalize=\"none\"\n autoCorrect=\"off\"\n autoFocus\n />\n <Group justify=\"end\">\n <Button\n w={110}\n variant=\"filled\"\n type=\"submit\"\n loading={totpPending}\n >\n Log In\n </Button>\n </Group>\n </>\n )}\n\n {noAuthConfigured && (\n <Group my=\"lg\">\n <AlertTriangle size=\"2rem\" />\n <Text>\n No login methods have been configured. <br />\n See the{\" \"}\n <a\n href={exampleConfigLink}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"hover-underline\"\n >\n <b>example config</b>\n </a>{\" \"}\n for information on configuring auth.\n </Text>\n </Group>\n )}\n </Fieldset>\n </Center>\n );\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../src/auth/login/index.tsx"],"sourcesContent":["import {\n Button,\n Center,\n Fieldset,\n Group,\n Loader,\n PasswordInput,\n Text,\n TextInput,\n} from \"@mantine/core\";\nimport { useForm } from \"@mantine/form\";\nimport { notifications } from \"@mantine/notifications\";\nimport * as MoghAuth from \"mogh_auth_client\";\nimport { AlertTriangle, KeyRound } from \"lucide-react\";\nimport { useEffect, useState } from \"react\";\nimport LoginHeader from \"./header\";\nimport {\n authClient,\n BackButton,\n sanitizeQuery,\n useLogin,\n useLoginOptions,\n useUserId,\n} from \"../..\";\n\nexport interface LoginBrandingProps {\n appName: string;\n iconLink: string;\n iconLinkAlt: string;\n}\n\nexport function LoginPage({\n passkeyIsPending: _passkeyIsPending,\n totpIsPending: _totpIsPending,\n onLogin,\n exampleConfigLink,\n ...branding\n}: {\n passkeyIsPending?: boolean;\n totpIsPending?: boolean;\n onLogin?: () => void;\n exampleConfigLink: string;\n} & LoginBrandingProps) {\n const options = useLoginOptions().data;\n const [passkeyIsPending, setPasskeyPending] = useState(\n _passkeyIsPending ?? false,\n );\n const [totpIsPending, setTotpPending] = useState(_totpIsPending ?? false);\n const secondFactorPending = passkeyIsPending || totpIsPending;\n\n const alreadyLoggedIn = useUserId().data?.id!!;\n\n // Auto-redirect to OIDC provider if configured and disableAutoLogin is not set\n useEffect(() => {\n if (options?.oidc_auto_redirect && options?.oidc && !secondFactorPending) {\n const params = new URLSearchParams(location.search);\n if (!params.has(\"disableAutoLogin\")) {\n authClient().externalLogin(MoghAuth.Types.ExternalLoginProvider.Oidc);\n }\n }\n }, [options?.oidc_auto_redirect, options?.oidc, secondFactorPending]);\n\n // If signing in another user, need to redirect away from /login manually\n const maybeNavigate = location.pathname.startsWith(\"/login\")\n ? () =>\n location.replace(\n new URLSearchParams(location.search).get(\"backto\") ?? \"/\",\n )\n : undefined;\n\n const onSuccess = ({ jwt }: MoghAuth.Types.JwtResponse) => {\n MoghAuth.LOGIN_TOKENS.add_and_change(jwt);\n onLogin?.();\n maybeNavigate?.();\n };\n\n const secondFactorOnSuccess = (res: MoghAuth.Types.JwtResponse) => {\n sanitizeQuery();\n onSuccess(res);\n };\n\n const { mutate: signup, isPending: signupPending } = useLogin(\n \"SignUpLocalUser\",\n {\n onSuccess,\n },\n );\n\n const { mutate: completePasskeyLogin } = useLogin(\"CompletePasskeyLogin\", {\n onSuccess: secondFactorOnSuccess,\n });\n\n const { mutate: completeTotpLogin, isPending: totpPending } = useLogin(\n \"CompleteTotpLogin\",\n {\n onSuccess: secondFactorOnSuccess,\n },\n );\n\n const { mutate: login, isPending: loginPending } = useLogin(\n \"LoginLocalUser\",\n {\n onSuccess: ({ type, data }) => {\n switch (type) {\n case \"Jwt\":\n return onSuccess(data);\n case \"Passkey\":\n setPasskeyPending(true);\n return navigator.credentials\n .get(MoghAuth.Passkey.prepareRequestChallengeResponse(data))\n .then((credential) => completePasskeyLogin({ credential }))\n .catch((e) => {\n console.error(e);\n notifications.show({\n title: \"Failed to select passkey\",\n message: \"See console for details\",\n color: \"red\",\n });\n });\n case \"Totp\":\n return setTotpPending(true);\n }\n },\n },\n );\n\n const noAuthConfigured =\n options !== undefined &&\n Object.values(options).every((value) => value === false);\n\n const showSignUp = options !== undefined && !options.registration_disabled;\n\n const localForm = useForm({\n mode: \"uncontrolled\",\n initialValues: {\n username: \"\",\n password: \"\",\n },\n validate: {\n username: (username) =>\n username.length ? null : \"Username cannot be empty\",\n password: (password) =>\n password.length ? null : \"Password cannot be empty\",\n },\n });\n\n const totpForm = useForm({\n mode: \"uncontrolled\",\n initialValues: {\n code: \"\",\n },\n validate: {\n code: (code) => (code.length === 6 ? null : \"Code should be 6 digits\"),\n },\n });\n\n return (\n <Center h=\"80vh\">\n <Fieldset\n legend={\n <LoginHeader\n secondFactorPending={secondFactorPending}\n {...branding}\n />\n }\n component=\"form\"\n onSubmit={\n totpIsPending\n ? totpForm.onSubmit((form) => completeTotpLogin(form))\n : (localForm.onSubmit((form) => login(form)) as any)\n }\n style={{ display: \"flex\", flexDirection: \"column\", gap: \"1rem\" }}\n miw={{ base: \"95vw\", xs: \"530px\" }}\n maw=\"95vw\"\n >\n {options?.local && !secondFactorPending && (\n <>\n <TextInput\n {...localForm.getInputProps(\"username\")}\n autoFocus\n label=\"Username\"\n placeholder=\"Enter username\"\n autoComplete=\"username\"\n autoCapitalize=\"off\"\n autoCorrect=\"off\"\n key={localForm.key(\"username\")}\n />\n <PasswordInput\n {...localForm.getInputProps(\"password\")}\n label=\"Password\"\n placeholder=\"Enter password\"\n autoComplete=\"password\"\n autoCapitalize=\"off\"\n autoCorrect=\"off\"\n key={localForm.key(\"password\")}\n />\n <Group mt=\"sm\" justify=\"space-between\">\n {alreadyLoggedIn && (\n <BackButton\n to={new URLSearchParams(location.search).get(\"backto\") ?? \"/\"}\n />\n )}\n <Group justify=\"end\">\n {showSignUp && (\n <Button\n variant=\"outline\"\n w={110}\n onClick={localForm.onSubmit((form) => signup(form)) as any}\n loading={signupPending}\n >\n Sign Up\n </Button>\n )}\n <Button w={110} type=\"submit\" loading={loginPending}>\n Log In\n </Button>\n </Group>\n </Group>\n </>\n )}\n\n {alreadyLoggedIn && !(options?.local && !secondFactorPending) && (\n <Group>\n <BackButton\n to={new URLSearchParams(location.search).get(\"backto\") ?? \"/\"}\n />\n </Group>\n )}\n\n {passkeyIsPending && (\n <Group justify=\"center\" my=\"lg\">\n <KeyRound size=\"1.5rem\" />\n <Text size=\"lg\">Provide your passkey to finish login...</Text>\n <Loader />\n </Group>\n )}\n\n {totpIsPending && (\n <>\n <TextInput\n {...totpForm.getInputProps(\"code\")}\n label={\n <Group gap=\"sm\">\n <KeyRound size=\"1rem\" />\n 2FA Code\n </Group>\n }\n autoComplete=\"code\"\n autoCapitalize=\"none\"\n autoCorrect=\"off\"\n autoFocus\n />\n <Group justify=\"end\">\n <Button\n w={110}\n variant=\"filled\"\n type=\"submit\"\n loading={totpPending}\n >\n Log In\n </Button>\n </Group>\n </>\n )}\n\n {noAuthConfigured && (\n <Group my=\"lg\">\n <AlertTriangle size=\"2rem\" />\n <Text>\n No login methods have been configured. <br />\n See the{\" \"}\n <a\n href={exampleConfigLink}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"hover-underline\"\n >\n <b>example config</b>\n </a>{\" \"}\n for information on configuring auth.\n </Text>\n </Group>\n )}\n </Fieldset>\n </Center>\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as react from 'react';
|
|
2
2
|
import * as MoghAuth from 'mogh_auth_client';
|
|
3
3
|
|
|
4
4
|
declare function LinkedLogins({ refetchUser, passwordSet, oidcLinkedId, githubLinkedId, googleLinkedId, extraProviderFilter, }: {
|
|
@@ -8,6 +8,6 @@ declare function LinkedLogins({ refetchUser, passwordSet, oidcLinkedId, githubLi
|
|
|
8
8
|
githubLinkedId?: string;
|
|
9
9
|
googleLinkedId?: string;
|
|
10
10
|
extraProviderFilter?: (provider: MoghAuth.Types.LoginProvider) => boolean;
|
|
11
|
-
}):
|
|
11
|
+
}): react.JSX.Element | null;
|
|
12
12
|
|
|
13
13
|
export { LinkedLogins };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as react from 'react';
|
|
2
2
|
import * as MoghAuth from 'mogh_auth_client';
|
|
3
3
|
|
|
4
4
|
declare function LinkedLogins({ refetchUser, passwordSet, oidcLinkedId, githubLinkedId, googleLinkedId, extraProviderFilter, }: {
|
|
@@ -8,6 +8,6 @@ declare function LinkedLogins({ refetchUser, passwordSet, oidcLinkedId, githubLi
|
|
|
8
8
|
githubLinkedId?: string;
|
|
9
9
|
googleLinkedId?: string;
|
|
10
10
|
extraProviderFilter?: (provider: MoghAuth.Types.LoginProvider) => boolean;
|
|
11
|
-
}):
|
|
11
|
+
}): react.JSX.Element | null;
|
|
12
12
|
|
|
13
13
|
export { LinkedLogins };
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as react from 'react';
|
|
2
2
|
|
|
3
3
|
declare function EnrollPasskey({ userInvalidate, passkeyEnrolled, totpEnrolled, }: {
|
|
4
4
|
userInvalidate?: () => void;
|
|
5
5
|
passkeyEnrolled?: boolean;
|
|
6
6
|
totpEnrolled?: boolean;
|
|
7
|
-
}):
|
|
7
|
+
}): react.JSX.Element;
|
|
8
8
|
|
|
9
9
|
export { EnrollPasskey };
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as react from 'react';
|
|
2
2
|
|
|
3
3
|
declare function EnrollPasskey({ userInvalidate, passkeyEnrolled, totpEnrolled, }: {
|
|
4
4
|
userInvalidate?: () => void;
|
|
5
5
|
passkeyEnrolled?: boolean;
|
|
6
6
|
totpEnrolled?: boolean;
|
|
7
|
-
}):
|
|
7
|
+
}): react.JSX.Element;
|
|
8
8
|
|
|
9
9
|
export { EnrollPasskey };
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as react from 'react';
|
|
2
2
|
|
|
3
3
|
declare const EnrollTotp: ({ userInvalidate, passkeyEnrolled, totpEnrolled, }: {
|
|
4
4
|
userInvalidate?: () => void;
|
|
5
5
|
passkeyEnrolled?: boolean;
|
|
6
6
|
totpEnrolled?: boolean;
|
|
7
|
-
}) =>
|
|
7
|
+
}) => react.JSX.Element;
|
|
8
8
|
|
|
9
9
|
export { EnrollTotp };
|