diff --git a/applications/uk.tcsw.console/web/lib/trpc.ts b/applications/uk.tcsw.console/web/lib/trpc.ts index 6ea667f..3f7dad9 100644 --- a/applications/uk.tcsw.console/web/lib/trpc.ts +++ b/applications/uk.tcsw.console/web/lib/trpc.ts @@ -2,23 +2,23 @@ import { createTRPCClient, httpBatchLink, httpSubscriptionLink, splitLink } from import type { TRPCRouter } from "../../backend/index"; const trpc = createTRPCClient({ - links: [ - splitLink({ - condition: (op: { type: string }) => op.type === "subscription", - true: httpSubscriptionLink({ - url: "https://localhost/api/app/uk.tcsw.console", - eventSourceOptions: { - withCredentials: true, - }, - }), - false: httpBatchLink({ - url: "https://localhost/api/app/uk.tcsw.console", - fetch(input, init) { - return fetch(input, { credentials: "include", ...init }); - }, - }), - }), - ], + links: [ + splitLink({ + condition: (op: { type: string }) => op.type === "subscription", + true: httpSubscriptionLink({ + url: `${window.location.origin}/api/app/uk.tcsw.console`, + eventSourceOptions: { + withCredentials: true, + }, + }), + false: httpBatchLink({ + url: `${window.location.origin}/api/app/uk.tcsw.console`, + fetch(input, init) { + return fetch(input, { credentials: "include", ...init }); + }, + }), + }), + ], }); export default trpc; diff --git a/applications/uk.tcsw.dashboard/web/lib/trpc.ts b/applications/uk.tcsw.dashboard/web/lib/trpc.ts index ebf7111..1a2e6a6 100644 --- a/applications/uk.tcsw.dashboard/web/lib/trpc.ts +++ b/applications/uk.tcsw.dashboard/web/lib/trpc.ts @@ -4,7 +4,7 @@ import type { TRPCRouter } from "../../backend/index"; const trpc = createTRPCClient({ links: [ httpBatchLink({ - url: "https://localhost/api/app/uk.tcsw.dashboard", + url: `${window.location.origin}/api/app/uk.tcsw.dashboard`, fetch(input, init) { return fetch(input, { credentials: "include", ...init }); }, diff --git a/applications/uk.tcsw.files/web/lib/trpc.ts b/applications/uk.tcsw.files/web/lib/trpc.ts index 2a2bac7..e1910b5 100644 --- a/applications/uk.tcsw.files/web/lib/trpc.ts +++ b/applications/uk.tcsw.files/web/lib/trpc.ts @@ -8,7 +8,7 @@ import { } from "@trpc/client"; import type { TRPCRouter } from "../../backend/index"; -const ENDPOINT_URL = "https://localhost/api/app/uk.tcsw.files"; +const ENDPOINT_URL = `${window.location.origin}/api/app/uk.tcsw.files`; const trpc = createTRPCClient({ links: [ diff --git a/applications/uk.tcsw.ghostty/web/lib/trpc.ts b/applications/uk.tcsw.ghostty/web/lib/trpc.ts index afa6f53..76b8bcb 100644 --- a/applications/uk.tcsw.ghostty/web/lib/trpc.ts +++ b/applications/uk.tcsw.ghostty/web/lib/trpc.ts @@ -2,14 +2,14 @@ import { createTRPCClient, httpBatchLink } from "@trpc/client"; import type { TRPCRouter } from "../../backend/index"; const trpc = createTRPCClient({ - links: [ - httpBatchLink({ - url: "https://localhost/api/app/uk.tcsw.ghostty", - fetch(input, init) { - return fetch(input, { credentials: "include", ...init }); - }, - }), - ], + links: [ + httpBatchLink({ + url: `${window.location.origin}/api/app/uk.tcsw.ghostty`, + fetch(input, init) { + return fetch(input, { credentials: "include", ...init }); + }, + }), + ], }); export default trpc; diff --git a/applications/uk.tcsw.photos/web/lib/trpc.ts b/applications/uk.tcsw.photos/web/lib/trpc.ts index d244c50..7970115 100644 --- a/applications/uk.tcsw.photos/web/lib/trpc.ts +++ b/applications/uk.tcsw.photos/web/lib/trpc.ts @@ -2,14 +2,14 @@ import { createTRPCClient, httpBatchLink } from "@trpc/client"; import type { TRPCRouter } from "../../backend/index"; const trpc = createTRPCClient({ - links: [ - httpBatchLink({ - url: "https://localhost/api/app/uk.tcsw.photos", - fetch(input, init) { - return fetch(input, { credentials: "include", ...init }); - }, - }), - ], + links: [ + httpBatchLink({ + url: `${window.location.origin}/api/app/uk.tcsw.photos`, + fetch(input, init) { + return fetch(input, { credentials: "include", ...init }); + }, + }), + ], }); export default trpc; diff --git a/applications/uk.tcsw.settings/web/lib/trpc.ts b/applications/uk.tcsw.settings/web/lib/trpc.ts index 6ce3d20..2ecc121 100644 --- a/applications/uk.tcsw.settings/web/lib/trpc.ts +++ b/applications/uk.tcsw.settings/web/lib/trpc.ts @@ -8,7 +8,7 @@ import { } from "@trpc/client"; import type { TRPCRouter } from "../../backend"; -const ENDPOINT_URL = "https://localhost/api/app/uk.tcsw.settings"; +const ENDPOINT_URL = `${window.location.origin}/api/app/uk.tcsw.settings`; const trpc = createTRPCClient({ links: [ diff --git a/applications/uk.tcsw.settings/web/pages/authentication/components/MethodPassword/components/ResetPasswordDialogue/ResetPasswordDialogue.tsx b/applications/uk.tcsw.settings/web/pages/authentication/components/MethodPassword/components/ResetPasswordDialogue/ResetPasswordDialogue.tsx index bc10b16..18bf41c 100644 --- a/applications/uk.tcsw.settings/web/pages/authentication/components/MethodPassword/components/ResetPasswordDialogue/ResetPasswordDialogue.tsx +++ b/applications/uk.tcsw.settings/web/pages/authentication/components/MethodPassword/components/ResetPasswordDialogue/ResetPasswordDialogue.tsx @@ -1,17 +1,15 @@ +import CHECK_ICON from "@material-symbols/svg-700/outlined/check.svg"; +import UKButton from "@tcsw/uikit-solid/src/components/button/UKButton.jsx"; +import UKButtonGroup from "@tcsw/uikit-solid/src/components/buttonGroup/UKButtonGroup.tsx"; import { DividerDirection } from "@tcsw/uikit-solid/src/components/divider/lib/direction.js"; import UKDivider from "@tcsw/uikit-solid/src/components/divider/UKDivider.jsx"; import UKText from "@tcsw/uikit-solid/src/components/text/UKText.jsx"; import UKTextField from "@tcsw/uikit-solid/src/components/textField/UKTextField.jsx"; -import { createSignal, type Component } from "solid-js"; -import styles from "./ResetPasswordDialogue.module.scss"; -import UKButton from "@tcsw/uikit-solid/src/components/button/UKButton.jsx"; +import { type Component, createSignal } from "solid-js"; import trpc from "../../../../../../lib/trpc"; -import UKButtonGroup from "@tcsw/uikit-solid/src/components/buttonGroup/UKButtonGroup.tsx"; -import CHECK_ICON from "@material-symbols/svg-700/outlined/check.svg"; +import styles from "./ResetPasswordDialogue.module.scss"; -const ResetPasswordDialogue: Component<{ closeDialogue: () => void }> = ( - props, -) => { +const ResetPasswordDialogue: Component<{ closeDialogue: () => void }> = (props) => { const [passwordOne, setPasswordOne] = createSignal(""); const [passwordTwo, setPasswordTwo] = createSignal(""); @@ -58,9 +56,7 @@ const ResetPasswordDialogue: Component<{ closeDialogue: () => void }> = ( props.closeDialogue(); }} - disabled={ - !(passwordOne() === passwordTwo() && passwordOne().length > 3) - } + disabled={!(passwordOne() === passwordTwo() && passwordOne().length > 3)} > Confirm diff --git a/applications/uk.tcsw.settings/web/pages/authentication/components/MethodTwoFactor/MethodTwoFactor.tsx b/applications/uk.tcsw.settings/web/pages/authentication/components/MethodTwoFactor/MethodTwoFactor.tsx index 02c5a3c..0f42856 100644 --- a/applications/uk.tcsw.settings/web/pages/authentication/components/MethodTwoFactor/MethodTwoFactor.tsx +++ b/applications/uk.tcsw.settings/web/pages/authentication/components/MethodTwoFactor/MethodTwoFactor.tsx @@ -1,57 +1,62 @@ +import CHECK_ICON from "@material-symbols/svg-700/outlined/check.svg"; +import SHIELD_LOCK_ICON from "@material-symbols/svg-700/outlined/shield_lock.svg"; import UKButton from "@tcsw/uikit-solid/src/components/button/UKButton.jsx"; +import UKDialog from "@tcsw/uikit-solid/src/components/dialog/UKDialog.jsx"; +import UKIcon from "@tcsw/uikit-solid/src/components/icon/UKIcon.jsx"; import UKStackItem from "@tcsw/uikit-solid/src/components/stack/UKStackItem.jsx"; -import { type Component, createResource, Suspense } from "solid-js"; +import UKText from "@tcsw/uikit-solid/src/components/text/UKText.jsx"; +import { type Component, createResource, createSignal, Suspense } from "solid-js"; import trpc from "../../../../lib/trpc"; +import TwoFactorCreateCodeDialog from "./components/TwoFactorCreateCodeDialog/TwoFactorCreateCodeDialog"; import styles from "./MethodTwoFactor.module.scss"; -import UKText from "@tcsw/uikit-solid/src/components/text/UKText.jsx"; -import UKIcon from "@tcsw/uikit-solid/src/components/icon/UKIcon.jsx"; -import SHIELD_LOCK_ICON from "@material-symbols/svg-700/outlined/shield_lock.svg" -import CHECK_ICON from "@material-symbols/svg-700/outlined/check.svg" const MethodTwoFactor: Component = () => { const [hasTwoFactor, { refetch: refetchHasTwoFactor }] = createResource(() => trpc.authentication.hasTwoFactor.query(), ); + const [showDialog, setShowDialog] = createSignal<"createCode" | "confirmCode" | null>(null); return ( - {CHECK_ICON} - } - expandedComponent={ - -
- - Use an OTP passcode to verify it's really you trying to login.{" "} - {!hasTwoFactor() - ? "\nOnce enabled, you must provide the otp code generated by a supported authenticator app to login / perform certain actions. \n(If you lose access to the authenticator app, you must contact an administrator to regain access to your account.)" - : ""} - - { - refetchHasTwoFactor(); - return 0; - }} - > - {hasTwoFactor() ? "Reset" : "Setup"} OTP two factor - -
-
- } - /> + <> + {CHECK_ICON}} + expandedComponent={ + +
+ + Use an OTP passcode to verify it's really you trying to login.{" "} + {!hasTwoFactor() + ? "\nOnce enabled, you must provide the otp code generated by a supported authenticator app to login / perform certain actions. \n(If you lose access to the authenticator app, you must contact an administrator to regain access to your account.)" + : ""} + + { + setShowDialog("createCode"); + return 0; + }} + > + {hasTwoFactor() ? "Reset" : "Setup"} OTP two factor + +
+
+ } + /> + setShowDialog(null)} show={() => showDialog() === "createCode"}> + + + ); }; diff --git a/applications/uk.tcsw.settings/web/pages/authentication/components/MethodTwoFactor/components/TwoFactorCreateCodeDialog/TwoFactorCreateCodeDialog.tsx b/applications/uk.tcsw.settings/web/pages/authentication/components/MethodTwoFactor/components/TwoFactorCreateCodeDialog/TwoFactorCreateCodeDialog.tsx new file mode 100644 index 0000000..f148fef --- /dev/null +++ b/applications/uk.tcsw.settings/web/pages/authentication/components/MethodTwoFactor/components/TwoFactorCreateCodeDialog/TwoFactorCreateCodeDialog.tsx @@ -0,0 +1,7 @@ +import type { Component } from "solid-js"; + +const TwoFactorCreateCodeDialog: Component = () => { + return
Setup Two-Factor Authentication
; +}; + +export default TwoFactorCreateCodeDialog; diff --git a/applications/uk.tcsw.settings/web/pages/customization/wallpaper/Index.tsx b/applications/uk.tcsw.settings/web/pages/customization/wallpaper/Index.tsx index 141cefd..e774e04 100644 --- a/applications/uk.tcsw.settings/web/pages/customization/wallpaper/Index.tsx +++ b/applications/uk.tcsw.settings/web/pages/customization/wallpaper/Index.tsx @@ -1,4 +1,8 @@ +import CHECK_ICON from "@material-symbols/svg-700/outlined/check.svg"; import CHEVRON_LEFT_ICON from "@material-symbols/svg-700/outlined/chevron_left.svg"; +import DELETE_ICON from "@material-symbols/svg-700/outlined/delete.svg"; +import FOLDER_ICON from "@material-symbols/svg-700/outlined/folder.svg"; +import UPLOAD_ICON from "@material-symbols/svg-700/outlined/upload.svg"; import { createFileUploader } from "@solid-primitives/upload"; import { useNavigate } from "@solidjs/router"; import UKButton from "@tcsw/uikit-solid/src/components/button/UKButton.tsx"; @@ -120,7 +124,7 @@ const WallpaperPage: Component = () => {
{ setWallpaperFit("fill"); }} @@ -129,7 +133,7 @@ const WallpaperPage: Component = () => { Fill { setWallpaperFit("cover"); }} @@ -138,7 +142,7 @@ const WallpaperPage: Component = () => { Cover { setWallpaperFit("contain"); }} @@ -156,7 +160,7 @@ const WallpaperPage: Component = () => { { setWallpaperAlignVertical("top"); }} @@ -166,7 +170,7 @@ const WallpaperPage: Component = () => { { setWallpaperAlignVertical("middle"); }} @@ -176,7 +180,7 @@ const WallpaperPage: Component = () => { { setWallpaperAlignVertical("bottom"); }} @@ -188,7 +192,7 @@ const WallpaperPage: Component = () => { { setWallpaperAlignHorizontal("left"); }} @@ -198,7 +202,7 @@ const WallpaperPage: Component = () => { { setWallpaperAlignHorizontal("center"); }} @@ -208,7 +212,7 @@ const WallpaperPage: Component = () => { { setWallpaperAlignHorizontal("right"); }} @@ -225,7 +229,7 @@ const WallpaperPage: Component = () => {
{ selectWallpaperUpload(async (files) => { for (const file of files) { @@ -247,7 +251,7 @@ const WallpaperPage: Component = () => { { return 0; }} @@ -286,7 +290,7 @@ const WallpaperPage: Component = () => { { await trpc.customization.wallpaper.delete.mutate({ diff --git a/applications/uk.tcsw.store/web/lib/trpc.ts b/applications/uk.tcsw.store/web/lib/trpc.ts index 80dddf6..4277630 100644 --- a/applications/uk.tcsw.store/web/lib/trpc.ts +++ b/applications/uk.tcsw.store/web/lib/trpc.ts @@ -2,14 +2,14 @@ import { createTRPCClient, httpBatchLink } from "@trpc/client"; import type { TRPCRouter } from "../../backend/index"; const trpc = createTRPCClient({ - links: [ - httpBatchLink({ - url: "https://localhost/api/app/uk.tcsw.store", - fetch(input, init) { - return fetch(input, { credentials: "include", ...init }); - }, - }), - ], + links: [ + httpBatchLink({ + url: `${window.location.origin}/api/app/uk.tcsw.store`, + fetch(input, init) { + return fetch(input, { credentials: "include", ...init }); + }, + }), + ], }); export default trpc; diff --git a/instance/src/web/src/lib/backend.ts b/instance/src/web/src/lib/backend.ts index d292246..1af8ad4 100644 --- a/instance/src/web/src/lib/backend.ts +++ b/instance/src/web/src/lib/backend.ts @@ -3,5 +3,5 @@ export default function backend(path: string): string { return `https://localhost${path}`; } - return `https://${window.location.hostname}${path}`; + return `${window.location.origin}${path}`; } diff --git a/instance/src/web/src/pages/userSelect/signup/Signup.tsx b/instance/src/web/src/pages/userSelect/signup/Signup.tsx index ae8436b..70a03e6 100644 --- a/instance/src/web/src/pages/userSelect/signup/Signup.tsx +++ b/instance/src/web/src/pages/userSelect/signup/Signup.tsx @@ -1,327 +1,299 @@ -import { type Component, createResource, createSignal, Match, Switch } from "solid-js"; -import UKCard from "@tcsw/uikit-solid/src/components/card/UKCard.tsx"; +import { useNavigate } from "@solidjs/router"; +import UKAvatar from "@tcsw/uikit-solid/src/components/avatar/UKAvatar.tsx"; import UKButton from "@tcsw/uikit-solid/src/components/button/UKButton.tsx"; -import UKDivider from "@tcsw/uikit-solid/src/components/divider/UKDivider.tsx"; +import UKCard from "@tcsw/uikit-solid/src/components/card/UKCard.tsx"; import { DividerDirection } from "@tcsw/uikit-solid/src/components/divider/lib/direction.ts"; +import UKDivider from "@tcsw/uikit-solid/src/components/divider/UKDivider.tsx"; +import UKIndeterminateSpinner from "@tcsw/uikit-solid/src/components/indeterminateSpinner/UKIndeterminateSpinner.tsx"; +import UKSearchableDropdownMenu from "@tcsw/uikit-solid/src/components/searchableDropdownMenu/UKSearchableDropdownMenu.tsx"; import UKText from "@tcsw/uikit-solid/src/components/text/UKText.tsx"; import UKTextField from "@tcsw/uikit-solid/src/components/textField/UKTextField.tsx"; -import { useNavigate } from "@solidjs/router"; -import styles from "./Signup.module.scss"; import clsx from "clsx"; -import UKAvatar from "@tcsw/uikit-solid/src/components/avatar/UKAvatar.tsx"; -import UKSearchableDropdownMenu from "@tcsw/uikit-solid/src/components/searchableDropdownMenu/UKSearchableDropdownMenu.tsx"; -import UKIndeterminateSpinner from "@tcsw/uikit-solid/src/components/indeterminateSpinner/UKIndeterminateSpinner.tsx"; +import { type Component, createResource, createSignal, Match, Switch } from "solid-js"; import trpc from "../../../lib/trpc"; -import Username from "./stages/Username/Username"; +import styles from "./Signup.module.scss"; import Email from "./stages/Email/Email"; -import VerifyEmail from "./stages/VerifyEmail/VerifyEmail"; import TermsOfUse from "./stages/TermsOfUse/TermsOfUse"; import TwoFactorAuthentication from "./stages/TwoFactorAuthentication/TwoFactorAuthentication"; +import Username from "./stages/Username/Username"; +import VerifyEmail from "./stages/VerifyEmail/VerifyEmail"; export enum UserSelectStage { - Username, // set username - Email, // set email - VerifyEmail, // verify they own the email - Password, // set password - Profile, // set profile information - TermsOfUse, // accept the terms of use for this instance - TwoFactorAuthentication, // attempt to setup 2FA - GuidePrompt, // prompt the user for if they want to see the introductory guide - Guide, // guide the new user through the basics + Username, // set username + Email, // set email + VerifyEmail, // verify they own the email + Password, // set password + Profile, // set profile information + TermsOfUse, // accept the terms of use for this instance + TwoFactorAuthentication, // attempt to setup 2FA + GuidePrompt, // prompt the user for if they want to see the introductory guide + Guide, // guide the new user through the basics } const UserSelectPage: Component = () => { - const navigate = useNavigate(); - const [stage, setStage] = createSignal(UserSelectStage.Username); + const navigate = useNavigate(); + const [stage, setStage] = createSignal(UserSelectStage.Username); - const [username, setUsername] = createSignal(""); - const [password, setPassword] = createSignal(""); - const [confirmedPassword, setConfirmedPassword] = createSignal(""); - const [emailAddress, setEmailAddress] = createSignal<`${string}@${string}.${string}` | "">(""); - const [emailCode, setEmailCode] = createSignal(""); - const [displayName, setDisplayName] = createSignal(""); - const [gender, setGender] = createSignal<"female" | "male" | "other">("other"); - const [bio, setBio] = createSignal(""); + const [username, setUsername] = createSignal(""); + const [password, setPassword] = createSignal(""); + const [confirmedPassword, setConfirmedPassword] = createSignal(""); + const [emailAddress, setEmailAddress] = createSignal<`${string}@${string}.${string}` | "">(""); + const [emailCode, setEmailCode] = createSignal(""); + const [displayName, setDisplayName] = createSignal(""); + const [gender, setGender] = createSignal<"female" | "male" | "other">("other"); + const [bio, setBio] = createSignal(""); - const [requirements] = createResource(() => trpc.authorization.signupRequirements.query()); + const [requirements] = createResource(() => trpc.authorization.signupRequirements.query()); - const [isUsernameValid, setIsUsernameValid] = createSignal(false); - const [twoFactorTestCode, setTwoFactorTestCode] = createSignal(""); - const [isEmailCodeValid, setIsEmailCodeValid] = createSignal(false); + const [isUsernameValid, setIsUsernameValid] = createSignal(false); + const [twoFactorTestCode, setTwoFactorTestCode] = createSignal(""); + const [isEmailCodeValid, setIsEmailCodeValid] = createSignal(false); - return ( - }> - - }> + + + + + + + + + + + + + Set Password + + + - - - - - - - - - - - Set Password - - - - -
- { - if (requirements()?.email) { - setStage(UserSelectStage.VerifyEmail); - } else { - setStage(UserSelectStage.Username); - } - }} - color={"tonal"} - > - Back - - + { + if (requirements()?.email) { + setStage(UserSelectStage.VerifyEmail); + } else { + setStage(UserSelectStage.Username); } - onClick={() => { - setStage(UserSelectStage.Profile); - }} - color={"filled"} - > - Continue - -
-
-
- - - - Setup Profile - - - - - {displayName() || username()} - - + { + setStage(UserSelectStage.Profile); + }} + color={"filled"} > - {`@${username()}`} - - +
+ + + + + + Setup Profile + + + + + {displayName() || username()} + + + {`@${username()}`} + + + {gender() === "female" ? "she/her" : gender() === "male" ? "he/him" : "they/them"} + + + setGender(val.toLowerCase())} + items={[ + { + id: "female", + type: "button", + label: "Female", + }, + { + id: "male", + type: "button", + label: "Male", + }, + { + id: "other", + type: "button", + label: "Other", + }, + ]} + /> + +
+ { + setStage(UserSelectStage.TwoFactorAuthentication); + }} + color={"tonal"} > - {gender() === "female" - ? "she/her" - : gender() === "male" - ? "he/him" - : "they/them"} - - - setGender(val.toLowerCase())} - items={[ - { - id: "female", - type: "button", - label: "Female", - }, - { - id: "male", - type: "button", - label: "Male", - }, - { - id: "other", - type: "button", - label: "Other", - }, - ]} - /> - -
- { - setStage(UserSelectStage.TwoFactorAuthentication); - }} - color={"tonal"} - > - Back - - { - if (displayName() === "") { - setDisplayName(username()); - } + Back + + { + if (displayName() === "") { + setDisplayName(username()); + } - setStage(UserSelectStage.TermsOfUse); - }} - color={"filled"} - > - Continue - -
- - - - { - // create the user - let resp = await trpc.authorization.signup.mutate({ - username: username(), - bio: bio(), - displayName: displayName(), - emailAddress: emailAddress(), - emailCode: emailCode(), - gender: gender(), - password: password(), - }); + setStage(UserSelectStage.TermsOfUse); + }} + color={"filled"} + > + Continue +
+
+
+
+ + { + // create the user + const resp = await trpc.authorization.signup.mutate({ + username: username(), + bio: bio(), + displayName: displayName(), + emailAddress: emailAddress(), + emailCode: emailCode(), + gender: gender(), + password: password(), + }); - if (resp.type === "success") { - return () => { - setStage(UserSelectStage.TwoFactorAuthentication); - } - } else { - // TODO: add an error toast here instead of a console message (When implemented in UIKit of course) - console.error(resp); - alert("A critical error occurred!"); - } - }} - /> - - - - - - - - Guide - - - - {"Would you like to have a guide of Workspaces?"} - - -
- navigate("/app")} color={"tonal"}> - Skip guide - - setStage(UserSelectStage.Guide)} - color={"filled"} - > - Continue - -
-
-
- - - - {"Unimplemented"} - - - - {"The guide is not yet implemented"} - - -
- navigate("/app")} color={"filled"}> - Skip guide and continue - -
-
-
- - ); + if (resp.type === "success") { + return () => { + setStage(UserSelectStage.TwoFactorAuthentication); + }; + } else { + // TODO: add an error toast here instead of a console message (When implemented in UIKit of course) + console.error(resp); + alert("A critical error occurred!"); + } + }} + /> + + + + + + + + Guide + + + + {"Would you like to have a guide of Workspaces?"} + + +
+ navigate("/app")} color={"tonal"}> + Skip guide + + setStage(UserSelectStage.Guide)} color={"filled"}> + Continue + +
+
+
+ + + + {"Unimplemented"} + + + + {"The guide is not yet implemented"} + + +
+ navigate("/app")} color={"filled"}> + Skip guide and continue + +
+
+
+ + ); }; export default UserSelectPage; diff --git a/instance/src/web/src/pages/userSelect/signup/stages/Email/Email.tsx b/instance/src/web/src/pages/userSelect/signup/stages/Email/Email.tsx index bfe6d02..f0f00ea 100644 --- a/instance/src/web/src/pages/userSelect/signup/stages/Email/Email.tsx +++ b/instance/src/web/src/pages/userSelect/signup/stages/Email/Email.tsx @@ -1,61 +1,63 @@ -import type { Accessor, Component } from "solid-js"; -import modalStyles from "../../Signup.module.scss"; -import { UserSelectStage } from "../../Signup"; -import UKText from "@tcsw/uikit-solid/src/components/text/UKText.jsx"; +import UKButton from "@tcsw/uikit-solid/src/components/button/UKButton.jsx"; import UKCard from "@tcsw/uikit-solid/src/components/card/UKCard.jsx"; -import UKTextField from "@tcsw/uikit-solid/src/components/textField/UKTextField.jsx"; import UKDivider from "@tcsw/uikit-solid/src/components/divider/UKDivider.jsx"; -import UKButton from "@tcsw/uikit-solid/src/components/button/UKButton.jsx"; -import trpc from "../../../../../lib/trpc"; +import UKText from "@tcsw/uikit-solid/src/components/text/UKText.jsx"; +import UKTextField from "@tcsw/uikit-solid/src/components/textField/UKTextField.jsx"; +import type { Accessor, Component } from "solid-js"; import z from "zod"; +import trpc from "../../../../../lib/trpc"; +import { UserSelectStage } from "../../Signup"; +import modalStyles from "../../Signup.module.scss"; const Email: Component<{ - setStage(stage: UserSelectStage): void; - emailAddress: Accessor; - setEmailAddress(emailAddress: string): void; - setEmailCode(emailCode: string): void; + setStage(stage: UserSelectStage): void; + emailAddress: Accessor; + setEmailAddress(emailAddress: string): void; + setEmailCode(emailCode: string): void; }> = (props) => { - return ( - <> - - - Set Email - - - -
- { - props.setStage(UserSelectStage.Username); - }} - color={"tonal"} - > - Back - - { - await trpc.authorization.checkEmailAddressOwnership.mutate({ - emailAddress: props.emailAddress(), - }); + return ( + <> + + + Set Email + + + +
+ { + props.setStage(UserSelectStage.Username); + }} + color={"tonal"} + > + Back + + { + await trpc.authorization.checkEmailAddressOwnership.mutate({ + emailAddress: props.emailAddress(), + }); - props.setStage(UserSelectStage.VerifyEmail); - }} - color={"filled"} - > - Continue - -
-
- - ); + props.setStage(UserSelectStage.VerifyEmail); + }} + color={"filled"} + > + Continue +
+
+
+ + ); }; export default Email; diff --git a/instance/src/web/src/pages/userSelect/signup/stages/TermsOfUse/TermsOfUse.tsx b/instance/src/web/src/pages/userSelect/signup/stages/TermsOfUse/TermsOfUse.tsx index 612601a..826bb4b 100644 --- a/instance/src/web/src/pages/userSelect/signup/stages/TermsOfUse/TermsOfUse.tsx +++ b/instance/src/web/src/pages/userSelect/signup/stages/TermsOfUse/TermsOfUse.tsx @@ -1,48 +1,48 @@ +import { useNavigate } from "@solidjs/router"; import UKButton from "@tcsw/uikit-solid/src/components/button/UKButton.jsx"; import UKCard from "@tcsw/uikit-solid/src/components/card/UKCard.jsx"; import UKDivider from "@tcsw/uikit-solid/src/components/divider/UKDivider.jsx"; import UKText from "@tcsw/uikit-solid/src/components/text/UKText.jsx"; import clsx from "clsx"; -import { createResource, type Component } from "solid-js"; +import { type Component, createResource } from "solid-js"; +import trpc from "../../../../../lib/trpc"; +import type { UserSelectStage } from "../../Signup"; import modalStyles from "../../Signup.module.scss"; import styles from "./TermsOfUse.module.scss"; -import { useNavigate } from "@solidjs/router"; -import { UserSelectStage } from "../../Signup"; -import trpc from "../../../../../lib/trpc"; const TermsOfUse: Component<{ - setStage(stage: UserSelectStage): void; - signup(): Promise void)>; + setStage(stage: UserSelectStage): void; + signup(): Promise void)>; }> = (props) => { - const navigate = useNavigate(); + const navigate = useNavigate(); - const [termsOfUse] = createResource(() => trpc.termsOfUse.query()); + const [termsOfUse] = createResource(() => trpc.termsOfUse.query()); - return ( - <> - - - Terms Of Use - - - - {termsOfUse()} - - - - You must agree to the terms above to continue - -
- navigate("/")} color={"tonal"}> - Deny - - - Agree and Continue - -
-
- - ); + return ( + <> + + + Terms Of Use + + + + {termsOfUse()} + + + + You must agree to the terms above to continue + +
+ navigate("/")} color={"tonal"}> + Deny + + + Agree and Continue + +
+
+ + ); }; export default TermsOfUse; diff --git a/instance/src/web/src/pages/userSelect/signup/stages/TwoFactorAuthentication/TwoFactorAuthentication.tsx b/instance/src/web/src/pages/userSelect/signup/stages/TwoFactorAuthentication/TwoFactorAuthentication.tsx index ab843de..cfad604 100644 --- a/instance/src/web/src/pages/userSelect/signup/stages/TwoFactorAuthentication/TwoFactorAuthentication.tsx +++ b/instance/src/web/src/pages/userSelect/signup/stages/TwoFactorAuthentication/TwoFactorAuthentication.tsx @@ -3,116 +3,116 @@ import UKCard from "@tcsw/uikit-solid/src/components/card/UKCard.jsx"; import UKDivider from "@tcsw/uikit-solid/src/components/divider/UKDivider.jsx"; import UKText from "@tcsw/uikit-solid/src/components/text/UKText.jsx"; import UKTextField from "@tcsw/uikit-solid/src/components/textField/UKTextField.jsx"; +import clsx from "clsx"; +import QRCode from "qrcode"; import { - createEffect, - createResource, - type Accessor, - type Component, - createSignal, - type Resource, + type Accessor, + type Component, + createEffect, + createResource, + createSignal, + type Resource, } from "solid-js"; +import trpc from "../../../../../lib/trpc"; import { UserSelectStage } from "../../Signup"; -import clsx from "clsx"; import modalStyles from "../../Signup.module.scss"; import styles from "./TwoFactorAuthentication.module.scss"; -import QRCode from "qrcode"; -import trpc from "../../../../../lib/trpc"; const TwoFactorAuthentication: Component<{ - twoFactorTestCode: Accessor; - setTwoFactorTestCode(testCode: string): void; - setStage(stage: UserSelectStage): void; - requirements: Resource<{ twoFactorAuthentication?: boolean }>; + twoFactorTestCode: Accessor; + setTwoFactorTestCode(testCode: string): void; + setStage(stage: UserSelectStage): void; + requirements: Resource<{ twoFactorAuthentication?: boolean }>; }> = (props) => { - const [isTwoFactorCodeValid, setIsTwoFactorCodeValid] = createSignal(false); - const [twoFactorSecret] = createResource(() => trpc.authorization.enableTwoFactor.mutate()); - let canvasElement!: HTMLCanvasElement; + const [isTwoFactorCodeValid, setIsTwoFactorCodeValid] = createSignal(false); + const [twoFactorSecret] = createResource(() => trpc.authorization.enableTwoFactor.mutate()); + let canvasElement!: HTMLCanvasElement; - createEffect(() => { - let twoFactorSecretValue = twoFactorSecret(); + createEffect(() => { + const twoFactorSecretValue = twoFactorSecret(); - if (!twoFactorSecretValue) return; + if (!twoFactorSecretValue) return; - QRCode.toCanvas( - canvasElement, - twoFactorSecretValue?.twoFactorSecretURI || "https://http.cat/404", - function (error) { - if (error) console.error(error); - }, - ); - }); + QRCode.toCanvas( + canvasElement, + twoFactorSecretValue?.twoFactorSecretURI || "https://http.cat/404", + (error) => { + if (error) console.error(error); + }, + ); + }); - return ( - <> - {isTwoFactorCodeValid() ? ( - - - Two Factor Setup Complete! - - - - You have successfully setup two-factor authentication on your account! - - -
- { - props.setStage(UserSelectStage.GuidePrompt); - }} - color={"filled"} - > - Continue - -
-
- ) : ( - - - Setup Two Factor Authentication - - -
- - - {`secret: ${twoFactorSecret()?.twoFactorSecret || "..."}`} - -
- { - props.setTwoFactorTestCode(value); + return ( + <> + {isTwoFactorCodeValid() ? ( + + + Two Factor Setup Complete! + + + + You have successfully setup two-factor authentication on your account! + + +
+ { + props.setStage(UserSelectStage.GuidePrompt); + }} + color={"filled"} + > + Continue + +
+
+ ) : ( + + + Setup Two Factor Authentication + + +
+ + + {`secret: ${twoFactorSecret()?.twoFactorSecret || "..."}`} + +
+ { + props.setTwoFactorTestCode(value); - if (value.length === 6) { - setIsTwoFactorCodeValid( - await trpc.authorization.confirmTwoFactor.mutate({ - twoFactorCode: value, - }), - ); - } - }} - supportingText={"*required"} - maximumCharacterCount={6} - /> - {!props.requirements()?.twoFactorAuthentication && ( - <> - - { - props.setStage(UserSelectStage.GuidePrompt); - }} - color={"standard"} - > - Skip Two Factor Setup - - - )} -
- )} - - ); + if (value.length === 6) { + setIsTwoFactorCodeValid( + await trpc.authorization.confirmTwoFactor.mutate({ + twoFactorCode: value, + }), + ); + } + }} + supportingText={"*required"} + maximumCharacterCount={6} + /> + {!props.requirements()?.twoFactorAuthentication && ( + <> + + { + props.setStage(UserSelectStage.GuidePrompt); + }} + color={"standard"} + > + Skip Two Factor Setup + + + )} +
+ )} + + ); }; export default TwoFactorAuthentication; diff --git a/instance/src/web/src/pages/userSelect/signup/stages/Username/Username.tsx b/instance/src/web/src/pages/userSelect/signup/stages/Username/Username.tsx index fd7fa03..a0b66c3 100644 --- a/instance/src/web/src/pages/userSelect/signup/stages/Username/Username.tsx +++ b/instance/src/web/src/pages/userSelect/signup/stages/Username/Username.tsx @@ -1,3 +1,5 @@ +import PERSON_ICON from "@material-symbols/svg-700/outlined/person.svg"; +import { useNavigate } from "@solidjs/router"; import UKButton from "@tcsw/uikit-solid/src/components/button/UKButton.jsx"; import UKCard from "@tcsw/uikit-solid/src/components/card/UKCard.jsx"; import UKDivider from "@tcsw/uikit-solid/src/components/divider/UKDivider.jsx"; @@ -5,77 +7,76 @@ import UKText from "@tcsw/uikit-solid/src/components/text/UKText.jsx"; import UKTextField from "@tcsw/uikit-solid/src/components/textField/UKTextField.jsx"; import clsx from "clsx"; import type { Accessor, Component, Resource } from "solid-js"; -import styles from "./Username.module.scss"; +import trpc from "../../../../../lib/trpc"; import { UserSelectStage } from "../../Signup"; -import { useNavigate } from "@solidjs/router"; import modalStyles from "../../Signup.module.scss"; -import trpc from "../../../../../lib/trpc"; +import styles from "./Username.module.scss"; const Username: Component<{ - setStage(stage: UserSelectStage): void; - username: Accessor; - setUsername(username: string): void; - requirements: Resource<{ - email: boolean; - }>; - isUsernameValid: Accessor; - setIsUsernameValid(isValid: boolean): void; + setStage(stage: UserSelectStage): void; + username: Accessor; + setUsername(username: string): void; + requirements: Resource<{ + email: boolean; + }>; + isUsernameValid: Accessor; + setIsUsernameValid(isValid: boolean): void; }> = (props) => { - const navigate = useNavigate(); + const navigate = useNavigate(); - return ( - <> - - - Signup - - - { - props.setUsername(val); + return ( + <> + + + Signup + + + { + props.setUsername(val); - if (await trpc.authorization.isUsernameValid.query(val)) { - props.setIsUsernameValid(true); - } else { - props.setIsUsernameValid(false); - } - }} - onSubmit={() => { - if (props.username() !== "") props.setStage(UserSelectStage.Email); - }} - /> -
- { - if (props.requirements()?.email) { - props.setStage(UserSelectStage.Email); - } else { - props.setStage(UserSelectStage.Password); - } - }} - color={"filled"} - > - Continue - -
- -
- - Already have an account? - - navigate("/")} color={"tonal"}> - Login - -
-
- - ); + if (await trpc.authorization.isUsernameValid.query(val)) { + props.setIsUsernameValid(true); + } else { + props.setIsUsernameValid(false); + } + }} + onSubmit={() => { + if (props.username() !== "") props.setStage(UserSelectStage.Email); + }} + /> +
+ { + if (props.requirements()?.email) { + props.setStage(UserSelectStage.Email); + } else { + props.setStage(UserSelectStage.Password); + } + }} + color={"filled"} + > + Continue + +
+ +
+ + Already have an account? + + navigate("/")} color={"tonal"}> + Login + +
+
+ + ); }; export default Username; diff --git a/instance/src/web/src/pages/userSelect/signup/stages/VerifyEmail/VerifyEmail.tsx b/instance/src/web/src/pages/userSelect/signup/stages/VerifyEmail/VerifyEmail.tsx index 219606e..adfb5f3 100644 --- a/instance/src/web/src/pages/userSelect/signup/stages/VerifyEmail/VerifyEmail.tsx +++ b/instance/src/web/src/pages/userSelect/signup/stages/VerifyEmail/VerifyEmail.tsx @@ -1,71 +1,71 @@ import UKButton from "@tcsw/uikit-solid/src/components/button/UKButton.jsx"; import UKCard from "@tcsw/uikit-solid/src/components/card/UKCard.jsx"; -import { createSignal, type Accessor, type Component } from "solid-js"; -import { UserSelectStage } from "../../Signup"; -import UKTextField from "@tcsw/uikit-solid/src/components/textField/UKTextField.jsx"; import UKDivider from "@tcsw/uikit-solid/src/components/divider/UKDivider.jsx"; import UKText from "@tcsw/uikit-solid/src/components/text/UKText.jsx"; -import styles from "./VerifyEmail.module.scss"; -import modalStyles from "../../Signup.module.scss"; +import UKTextField from "@tcsw/uikit-solid/src/components/textField/UKTextField.jsx"; +import { type Accessor, type Component, createSignal } from "solid-js"; import trpc from "../../../../../lib/trpc"; +import { UserSelectStage } from "../../Signup"; +import modalStyles from "../../Signup.module.scss"; +import styles from "./VerifyEmail.module.scss"; const VerifyEmail: Component<{ - emailAddress: Accessor; - emailCode: Accessor; - setEmailCode(emailCode: string): void; - setStage(stage: UserSelectStage): void; - isEmailCodeValid: Accessor; - setIsEmailCodeValid(isValid: boolean): void; + emailAddress: Accessor; + emailCode: Accessor; + setEmailCode(emailCode: string): void; + setStage(stage: UserSelectStage): void; + isEmailCodeValid: Accessor; + setIsEmailCodeValid(isValid: boolean): void; }> = (props) => { - return ( - <> - - - Verify Email - - - - Please enter the code which was sent to the email you provided to continue. - - { - props.setEmailCode(value); + return ( + <> + + + Verify Email + + + + Please enter the code which was sent to the email you provided to continue. + + { + props.setEmailCode(value); - props.setIsEmailCodeValid( - await trpc.authorization.validateEmailCode.query({ - emailAddress: props.emailAddress(), - emailCode: props.emailCode(), - }), - ); - }} - maximumCharacterCount={8} - supportingText={"*required"} - /> -
- { - props.setStage(UserSelectStage.Email); - }} - color={"tonal"} - > - Back - - { - props.setStage(UserSelectStage.Password); - }} - color={"filled"} - > - Continue - -
-
- - ); + props.setIsEmailCodeValid( + await trpc.authorization.validateEmailCode.query({ + emailAddress: props.emailAddress(), + emailCode: props.emailCode(), + }), + ); + }} + maximumCharacterCount={8} + supportingText={"*required"} + /> +
+ { + props.setStage(UserSelectStage.Email); + }} + color={"tonal"} + > + Back + + { + props.setStage(UserSelectStage.Password); + }} + color={"filled"} + > + Continue + +
+
+ + ); }; export default VerifyEmail; diff --git a/instance/src/web/vite.config.ts b/instance/src/web/vite.config.ts index bb967c6..67ec3a6 100644 --- a/instance/src/web/vite.config.ts +++ b/instance/src/web/vite.config.ts @@ -15,6 +15,7 @@ export default defineConfig({ ], server: { host: true, + allowedHosts: [process.env.ALLOW_HOST || "localhost", "localhost"], }, resolve: { alias: {