Fix 405 error (#516)

Co-authored-by: Christopher Oliphant <christopheroliphant@christophersmbp.home>
This commit is contained in:
FromTheLOLAshesandChristopher Oliphant authored and GitHub committed 2024-06-23 15:20:06 -04:00
1 parent ff259446f6
commit fecb909570
5 files changed
+179 -19

No files matched your search

+51
View File
@@ -107,4 +107,55 @@ export class UsersApi extends ApiManager {
};
});
}
public async Signup({
username,
email,
password,
passwordConfirmation,
}: {
username: string;
email: string;
password: string;
passwordConfirmation: string;
}): Promise<ApiResponse<{ signedSession?: string }>> {
const endpoint = `${this.ApiTargets.BaseApi}/v1/create_account`;
const body = {
email_address: email,
password,
password_confirmation: passwordConfirmation,
username,
};
return await this.post<
{
username: string;
email_address: string;
password: string;
password_confirmation: string;
},
{
success: boolean;
signed_session?: string;
error_fields?: Record<string, string>;
error_message?: string;
error_type?: string;
}
>({
endpoint: endpoint,
body: body,
})
.then((response) => {
return {
success: response.success,
data: { signedSession: response.signed_session },
errorMessage: Object.values(response.error_fields ?? {}).join(","),
};
})
.catch((err) => {
return {
success: false,
error_message: err.message,
};
});
}
}
+1 -2
View File
@@ -1,6 +1,6 @@
import React, { useEffect } from "react";
import { useSignals } from "@preact/signals-react/runtime";
import { LoadingDots, Toaster, TopBar } from "~/components";
import { LoadingDots, TopBar } from "~/components";
import { SidePanel } from "~/pages/PageEnigma/comps/SidePanel";
import { Timeline } from "./comps/Timeline";
import { Controls3D } from "./comps/Controls3D";
@@ -108,7 +108,6 @@ export const PageEditor = () => {
}}
>
<div className="relative w-full overflow-hidden bg-transparent">
<Toaster />
<SceneContainer>
<EditorCanvas />
<PreviewFrameImage />
+2
View File
@@ -22,6 +22,7 @@ import { config } from "@fortawesome/fontawesome-svg-core";
import EnvironmentVariables from "~/Classes/EnvironmentVariables";
import { environmentVariables, pageHeight, pageWidth } from "~/signals";
import { Toaster } from "~/components";
config.autoAddCss = false; /* eslint-disable import/first */
@@ -95,6 +96,7 @@ export default function App() {
<body className="overflow-hidden bg-ui-background">
{data && <GlobalSettingsManager env={data.ENV} />}
<div className="topbar-spacer" />
<Toaster />
<Outlet />
<ScrollRestoration />
<Scripts />
+92 -17
View File
@@ -1,31 +1,103 @@
import { Form } from "@remix-run/react";
import { faEnvelope, faKey, faUser } from "@fortawesome/pro-solid-svg-icons";
import {
Button,
H1,
Input,
Link,
P,
} from '~/components';
import { Button, H1, Input, Link, P } from "~/components";
import { addToast, authentication, signUp } from "~/signals";
import { FormEvent, useRef, useState } from "react";
import { AUTH_STATUS, ToastTypes } from "~/enums";
import { useSignalEffect, useSignals } from "@preact/signals-react/runtime";
import { useNavigate, useSearchParams } from "@remix-run/react";
const regEx =
/^(([^<>()[\].,;:\s@"]+(.[^<>()[\].,;:\s@"]+)*)|(".+"))@(([^<>()[\].,;:\s@"]+\.)+[^<>()[\].,;:\s@"]{2,})$/i;
export default function SignUpScreen() {
useSignals();
const navigate = useNavigate();
const formRef = useRef<HTMLFormElement | null>(null);
const [usernameError, setUsernameError] = useState("");
const [emailError, setEmailError] = useState("");
const [passwordError, setPasswordError] = useState("");
const [passwordConfirmationError, setPasswordConfirmationError] =
useState("");
const [searchParams] = useSearchParams();
const { status: authStatus } = authentication;
const handleOnSubmit = (ev: FormEvent<HTMLFormElement>) => {
ev.preventDefault();
if (formRef.current) {
const form = new FormData(formRef.current);
const email = form.get("email")?.toString();
const password = form.get("password")?.toString();
const passwordConfirmation = form
.get("password-confirmation")
?.toString();
const username = form.get("username")?.toString();
setUsernameError("");
if (!username || username.length < 6) {
setUsernameError("Username must be at least 6 characters long");
}
setEmailError("");
if (!email || !email.match(regEx)) {
setEmailError("Email must be a valid email address");
}
setPasswordError("");
if (!password || password.length < 8) {
setPasswordError("Password must be at least 8 characters long");
}
setPasswordConfirmationError("");
if (!passwordError && passwordConfirmation !== password) {
setPasswordConfirmationError("Passwords do not match");
}
if (
!usernameError &&
!passwordError &&
!emailError &&
!passwordConfirmationError &&
signUp
) {
signUp({
username: username!,
email: email!,
password: password!,
passwordConfirmation: passwordConfirmation!,
}).then((error) => {
console.log("Error occured", error);
if (error) {
addToast(ToastTypes.ERROR, error);
}
});
}
}
}; // end handleOnSubmit
useSignalEffect(() => {
const redirectPath = searchParams.get("redirect");
if (authStatus.value === AUTH_STATUS.LOGGED_IN) {
navigate(redirectPath ? redirectPath : "/");
return;
}
if (authStatus.value === AUTH_STATUS.NO_ACCESS) {
window.open("https://storyteller.ai/", "_self");
return;
}
});
export default function LoginScreen() {
return (
<div
className="fixed w-full overflow-scroll"
style={{height: "calc(100% - 72px)"}}
style={{ height: "calc(100% - 72px)" }}
>
<div className="w-10/12 max-w-2xl mx-auto my-6">
<div className="mx-auto my-6 w-10/12 max-w-2xl">
<H1 className="text-center">Sign Up to Storyteller</H1>
</div>
<div
className='bg-ui-panel w-10/12 max-w-2xl mx-auto my-6 rounded-lg p-6 border border-ui-panel-border'
>
<Form method="post" >
<div className="mx-auto my-6 w-10/12 max-w-2xl rounded-lg border border-ui-panel-border bg-ui-panel p-6">
<form ref={formRef} onSubmit={handleOnSubmit}>
<Input
label="Username"
icon={faUser}
placeholder="Username"
name="username"
errorMessage={usernameError}
required
/>
<br />
@@ -35,6 +107,7 @@ export default function LoginScreen() {
icon={faEnvelope}
placeholder="Email"
name="email"
errorMessage={emailError}
required
/>
<br />
@@ -45,6 +118,7 @@ export default function LoginScreen() {
name="password"
placeholder="Password"
autoComplete="current-password"
errorMessage={passwordError}
required
/>
<br />
@@ -54,6 +128,7 @@ export default function LoginScreen() {
icon={faKey}
placeholder="Password COnfirmation"
name="password-confirmation"
errorMessage={passwordConfirmationError}
required
/>
<br />
@@ -62,9 +137,9 @@ export default function LoginScreen() {
<br />
<div className="flex gap-2">
<P>Already have an account?</P>
<Link to='/login'>Log in instead</Link>
<Link to="/login">Log in instead</Link>
</div>
</Form>
</form>
</div>
</div>
);
+33
View File
@@ -48,6 +48,39 @@ export const login = async ({
getUserInfoAndSubcriptions();
};
export const signUp = async ({
username,
email,
password,
passwordConfirmation,
}: {
username: string;
email: string;
password: string;
passwordConfirmation: string;
}) => {
updateAuthStatus(AUTH_STATUS.LOGGING);
const usersApi = new UsersApi();
const response = await usersApi.Signup({
email,
password,
passwordConfirmation,
username,
});
console.log(response);
if (!response.success || !response.data) {
setLogoutStates();
return response.errorMessage ?? "Unknown error";
}
// technically user is login with the system now, HOWEVER,
// in storyteller studio, only having a sesison is not enough,
// we need session info and active subscription info as well
getUserInfoAndSubcriptions();
return "";
};
export const persistLogin = async () => {
//Only run First Load, return if not
if (authentication.status.value !== AUTH_STATUS.INIT) {