mirror of
https://github.com/sussy-code/smov.git
synced 2024-12-29 16:07:40 +01:00
make email an optional setting + add device name validation
This commit is contained in:
parent
83bc9637b0
commit
7841fadcb6
7 changed files with 40 additions and 9 deletions
|
@ -16,6 +16,7 @@
|
||||||
"title": "Login to your account",
|
"title": "Login to your account",
|
||||||
"description": "Please enter your passphrase to login to your account",
|
"description": "Please enter your passphrase to login to your account",
|
||||||
"validationError": "Invalid or incomplete passphrase",
|
"validationError": "Invalid or incomplete passphrase",
|
||||||
|
"deviceLengthError": "Please entire a device name",
|
||||||
"submit": "Login",
|
"submit": "Login",
|
||||||
"passphraseLabel": "12-Word passphrase",
|
"passphraseLabel": "12-Word passphrase",
|
||||||
"passphrasePlaceholder": "Passphrase"
|
"passphrasePlaceholder": "Passphrase"
|
||||||
|
|
|
@ -4,6 +4,7 @@ import { useHistory } from "react-router-dom";
|
||||||
import { Icon, Icons } from "@/components/Icon";
|
import { Icon, Icons } from "@/components/Icon";
|
||||||
import { BrandPill } from "@/components/layout/BrandPill";
|
import { BrandPill } from "@/components/layout/BrandPill";
|
||||||
import { WideContainer } from "@/components/layout/WideContainer";
|
import { WideContainer } from "@/components/layout/WideContainer";
|
||||||
|
import { shouldHaveDmcaPage } from "@/pages/Dmca";
|
||||||
import { conf } from "@/setup/config";
|
import { conf } from "@/setup/config";
|
||||||
|
|
||||||
function FooterLink(props: {
|
function FooterLink(props: {
|
||||||
|
@ -30,6 +31,8 @@ function Dmca() {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
|
|
||||||
|
if (!shouldHaveDmcaPage()) return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<FooterLink icon={Icons.DRAGON} onClick={() => history.push("/dmca")}>
|
<FooterLink icon={Icons.DRAGON} onClick={() => history.push("/dmca")}>
|
||||||
{t("footer.links.dmca")}
|
{t("footer.links.dmca")}
|
||||||
|
|
|
@ -4,10 +4,14 @@ import { Icon, Icons } from "@/components/Icon";
|
||||||
import { ThinContainer } from "@/components/layout/ThinContainer";
|
import { ThinContainer } from "@/components/layout/ThinContainer";
|
||||||
import { Heading1, Paragraph } from "@/components/utils/Text";
|
import { Heading1, Paragraph } from "@/components/utils/Text";
|
||||||
import { PageTitle } from "@/pages/parts/util/PageTitle";
|
import { PageTitle } from "@/pages/parts/util/PageTitle";
|
||||||
|
import { conf } from "@/setup/config";
|
||||||
|
|
||||||
import { SubPageLayout } from "./layouts/SubPageLayout";
|
import { SubPageLayout } from "./layouts/SubPageLayout";
|
||||||
|
|
||||||
// TODO make email a constant
|
export function shouldHaveDmcaPage() {
|
||||||
|
return !!conf().DMCA_EMAIL;
|
||||||
|
}
|
||||||
|
|
||||||
export function DmcaPage() {
|
export function DmcaPage() {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
@ -19,7 +23,7 @@ export function DmcaPage() {
|
||||||
<Paragraph>{t("screens.dmca.text")}</Paragraph>
|
<Paragraph>{t("screens.dmca.text")}</Paragraph>
|
||||||
<Paragraph className="flex space-x-3 items-center">
|
<Paragraph className="flex space-x-3 items-center">
|
||||||
<Icon icon={Icons.MAIL} />
|
<Icon icon={Icons.MAIL} />
|
||||||
<span>dmca@movie-web.app</span>
|
<span>{conf().DMCA_EMAIL ?? ""}</span>
|
||||||
</Paragraph>
|
</Paragraph>
|
||||||
</ThinContainer>
|
</ThinContainer>
|
||||||
</SubPageLayout>
|
</SubPageLayout>
|
||||||
|
|
|
@ -32,11 +32,18 @@ export function AccountCreatePart(props: AccountCreatePartProps) {
|
||||||
const [colorB, setColorB] = useState("#2E65CF");
|
const [colorB, setColorB] = useState("#2E65CF");
|
||||||
const [userIcon, setUserIcon] = useState<UserIcons>(UserIcons.USER);
|
const [userIcon, setUserIcon] = useState<UserIcons>(UserIcons.USER);
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
// TODO validate device and account before next step
|
const [hasDeviceError, setHasDeviceError] = useState(false);
|
||||||
|
|
||||||
const nextStep = useCallback(() => {
|
const nextStep = useCallback(() => {
|
||||||
|
setHasDeviceError(false);
|
||||||
|
const validatedDevice = device.trim();
|
||||||
|
if (validatedDevice.length === 0) {
|
||||||
|
setHasDeviceError(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
props.onNext?.({
|
props.onNext?.({
|
||||||
device,
|
device: validatedDevice,
|
||||||
profile: {
|
profile: {
|
||||||
colorA,
|
colorA,
|
||||||
colorB,
|
colorB,
|
||||||
|
@ -75,6 +82,11 @@ export function AccountCreatePart(props: AccountCreatePartProps) {
|
||||||
value={userIcon}
|
value={userIcon}
|
||||||
onInput={setUserIcon}
|
onInput={setUserIcon}
|
||||||
/>
|
/>
|
||||||
|
{hasDeviceError ? (
|
||||||
|
<p className="text-authentication-errorText">
|
||||||
|
{t("auth.login.deviceLengthError")}
|
||||||
|
</p>
|
||||||
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
<LargeCardButtons>
|
<LargeCardButtons>
|
||||||
<Button theme="purple" onClick={() => nextStep()}>
|
<Button theme="purple" onClick={() => nextStep()}>
|
||||||
|
|
|
@ -29,14 +29,17 @@ export function LoginFormPart(props: LoginFormPartProps) {
|
||||||
|
|
||||||
const [result, execute] = useAsyncFn(
|
const [result, execute] = useAsyncFn(
|
||||||
async (inputMnemonic: string, inputdevice: string) => {
|
async (inputMnemonic: string, inputdevice: string) => {
|
||||||
// TODO verify valid device input
|
|
||||||
if (!verifyValidMnemonic(inputMnemonic))
|
if (!verifyValidMnemonic(inputMnemonic))
|
||||||
throw new Error(t("auth.login.validationError") ?? undefined);
|
throw new Error(t("auth.login.validationError") ?? undefined);
|
||||||
|
|
||||||
|
const validatedDevice = inputdevice.trim();
|
||||||
|
if (validatedDevice.length === 0)
|
||||||
|
throw new Error(t("auth.login.deviceLengthError") ?? undefined);
|
||||||
|
|
||||||
const account = await login({
|
const account = await login({
|
||||||
mnemonic: inputMnemonic,
|
mnemonic: inputMnemonic,
|
||||||
userData: {
|
userData: {
|
||||||
device: inputdevice,
|
device: validatedDevice,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -46,7 +49,7 @@ export function LoginFormPart(props: LoginFormPartProps) {
|
||||||
|
|
||||||
props.onLogin?.();
|
props.onLogin?.();
|
||||||
},
|
},
|
||||||
[props, login, restore]
|
[props, login, restore, t]
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -14,7 +14,7 @@ import { useOnlineListener } from "@/hooks/usePing";
|
||||||
import { AboutPage } from "@/pages/About";
|
import { AboutPage } from "@/pages/About";
|
||||||
import { AdminPage } from "@/pages/admin/AdminPage";
|
import { AdminPage } from "@/pages/admin/AdminPage";
|
||||||
import VideoTesterView from "@/pages/developer/VideoTesterView";
|
import VideoTesterView from "@/pages/developer/VideoTesterView";
|
||||||
import { DmcaPage } from "@/pages/Dmca";
|
import { DmcaPage, shouldHaveDmcaPage } from "@/pages/Dmca";
|
||||||
import { NotFoundPage } from "@/pages/errors/NotFoundPage";
|
import { NotFoundPage } from "@/pages/errors/NotFoundPage";
|
||||||
import { HomePage } from "@/pages/HomePage";
|
import { HomePage } from "@/pages/HomePage";
|
||||||
import { LoginPage } from "@/pages/Login";
|
import { LoginPage } from "@/pages/Login";
|
||||||
|
@ -93,7 +93,10 @@ function App() {
|
||||||
<Route exact path="/register" component={RegisterPage} />
|
<Route exact path="/register" component={RegisterPage} />
|
||||||
<Route exact path="/login" component={LoginPage} />
|
<Route exact path="/login" component={LoginPage} />
|
||||||
<Route exact path="/faq" component={AboutPage} />
|
<Route exact path="/faq" component={AboutPage} />
|
||||||
|
|
||||||
|
{shouldHaveDmcaPage() ? (
|
||||||
<Route exact path="/dmca" component={DmcaPage} />
|
<Route exact path="/dmca" component={DmcaPage} />
|
||||||
|
) : null}
|
||||||
|
|
||||||
{/* Settings page */}
|
{/* Settings page */}
|
||||||
<Route exact path="/settings" component={SettingsPage} />
|
<Route exact path="/settings" component={SettingsPage} />
|
||||||
|
|
|
@ -10,6 +10,7 @@ interface Config {
|
||||||
GITHUB_LINK: string;
|
GITHUB_LINK: string;
|
||||||
DONATION_LINK: string;
|
DONATION_LINK: string;
|
||||||
DISCORD_LINK: string;
|
DISCORD_LINK: string;
|
||||||
|
DMCA_EMAIL: string;
|
||||||
TMDB_READ_API_KEY: string;
|
TMDB_READ_API_KEY: string;
|
||||||
CORS_PROXY_URL: string;
|
CORS_PROXY_URL: string;
|
||||||
NORMAL_ROUTER: boolean;
|
NORMAL_ROUTER: boolean;
|
||||||
|
@ -22,6 +23,7 @@ export interface RuntimeConfig {
|
||||||
GITHUB_LINK: string;
|
GITHUB_LINK: string;
|
||||||
DONATION_LINK: string;
|
DONATION_LINK: string;
|
||||||
DISCORD_LINK: string;
|
DISCORD_LINK: string;
|
||||||
|
DMCA_EMAIL: string | null;
|
||||||
TMDB_READ_API_KEY: string;
|
TMDB_READ_API_KEY: string;
|
||||||
NORMAL_ROUTER: boolean;
|
NORMAL_ROUTER: boolean;
|
||||||
PROXY_URLS: string[];
|
PROXY_URLS: string[];
|
||||||
|
@ -35,6 +37,7 @@ const env: Record<keyof Config, undefined | string> = {
|
||||||
GITHUB_LINK: undefined,
|
GITHUB_LINK: undefined,
|
||||||
DONATION_LINK: undefined,
|
DONATION_LINK: undefined,
|
||||||
DISCORD_LINK: undefined,
|
DISCORD_LINK: undefined,
|
||||||
|
DMCA_EMAIL: import.meta.env.VITE_DMCA_EMAIL,
|
||||||
CORS_PROXY_URL: import.meta.env.VITE_CORS_PROXY_URL,
|
CORS_PROXY_URL: import.meta.env.VITE_CORS_PROXY_URL,
|
||||||
NORMAL_ROUTER: import.meta.env.VITE_NORMAL_ROUTER,
|
NORMAL_ROUTER: import.meta.env.VITE_NORMAL_ROUTER,
|
||||||
BACKEND_URL: import.meta.env.VITE_BACKEND_URL,
|
BACKEND_URL: import.meta.env.VITE_BACKEND_URL,
|
||||||
|
@ -54,11 +57,13 @@ function getKey(key: keyof Config, defaultString?: string): string {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function conf(): RuntimeConfig {
|
export function conf(): RuntimeConfig {
|
||||||
|
const dmcaEmail = getKey("DMCA_EMAIL");
|
||||||
return {
|
return {
|
||||||
APP_VERSION,
|
APP_VERSION,
|
||||||
GITHUB_LINK,
|
GITHUB_LINK,
|
||||||
DONATION_LINK,
|
DONATION_LINK,
|
||||||
DISCORD_LINK,
|
DISCORD_LINK,
|
||||||
|
DMCA_EMAIL: dmcaEmail.length > 0 ? dmcaEmail : null,
|
||||||
BACKEND_URL: getKey("BACKEND_URL"),
|
BACKEND_URL: getKey("BACKEND_URL"),
|
||||||
TMDB_READ_API_KEY: getKey("TMDB_READ_API_KEY"),
|
TMDB_READ_API_KEY: getKey("TMDB_READ_API_KEY"),
|
||||||
PROXY_URLS: getKey("CORS_PROXY_URL")
|
PROXY_URLS: getKey("CORS_PROXY_URL")
|
||||||
|
|
Loading…
Reference in a new issue