mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-08 20:28:16 +00:00
translate(frontend): add login, signup page translate
This commit is contained in:
@@ -49,6 +49,7 @@ services:
|
|||||||
- ./frontend/public:/app/public
|
- ./frontend/public:/app/public
|
||||||
- ./frontend/styles:/app/styles
|
- ./frontend/styles:/app/styles
|
||||||
- ./frontend/components:/app/components
|
- ./frontend/components:/app/components
|
||||||
|
- ./frontend/locales:/app/locales
|
||||||
env_file: .env
|
env_file: .env
|
||||||
environment:
|
environment:
|
||||||
- NEXT_PUBLIC_ENV=development
|
- NEXT_PUBLIC_ENV=development
|
||||||
@@ -91,4 +92,4 @@ volumes:
|
|||||||
driver: local
|
driver: local
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
infisical-dev:
|
infisical-dev:
|
||||||
|
|||||||
@@ -1,3 +1,45 @@
|
|||||||
{
|
{
|
||||||
"test": "test!!"
|
"meta": {
|
||||||
|
"login": {
|
||||||
|
"title": "Login | Infiscal",
|
||||||
|
"og-title": "Log In to Infisical",
|
||||||
|
"og-description": "Infisical a simple end-to-end encrypted platform that enables teams to sync and manage their .env files."
|
||||||
|
},
|
||||||
|
"signup": {
|
||||||
|
"title": "Sign Up | Infiscal",
|
||||||
|
"og-title": "Replace .env files with 1 line of code. Sign Up for Infisical in 3 minutes.",
|
||||||
|
"og-description": "Infisical a simple end-to-end encrypted platform that enables teams to sync and manage API-keys and environemntal variables. Works with Node.js, Next.js, Gatsby, Nest.js..."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"email": "Email",
|
||||||
|
"password": "Password",
|
||||||
|
"verify": "Verify",
|
||||||
|
"first-name": "First Name",
|
||||||
|
"last-name": "Last Name",
|
||||||
|
"validate-required": "Please input your {{name}}",
|
||||||
|
"password-validate": "Password should contain at least:",
|
||||||
|
"password-validate-length": "14 characters",
|
||||||
|
"password-validate-case": "1 lowercase character",
|
||||||
|
"password-validate-number": "1 number",
|
||||||
|
"auth": {
|
||||||
|
"login": "Log In",
|
||||||
|
"signup": "Sign Up",
|
||||||
|
"need-account": "Need an Infisical account?",
|
||||||
|
"create-account": "Create an account",
|
||||||
|
"already-have-account": "Have an account? Log in",
|
||||||
|
"forgot-password": "Forgot your password?",
|
||||||
|
"step1-start": "Let's get started",
|
||||||
|
"step1-privacy": "By creating an account, you agree to our Terms and have read and acknowledged the Privacy Policy.",
|
||||||
|
"step1-submit": "Get Started",
|
||||||
|
"step2-message": "<wrapper>We've sent a verification email to</wrapper><email>{{email}}</email>",
|
||||||
|
"step2-code-error": "Oops. Your code is wrong. Please try again.",
|
||||||
|
"step2-spam-alert": "Make sure to check your spam inbox.",
|
||||||
|
"step3-message": "Almost there!",
|
||||||
|
"step4-message": "Save your Emergency Kit",
|
||||||
|
"step4-description1": "If you get locked out of your account, your Emergency Kit is the only way to sign in.",
|
||||||
|
"step4-description2": "We recommend you download it and keep it somewhere safe.",
|
||||||
|
"step4-description3": "It contains your Secret Key which we cannot access or recover for you if you lose it.",
|
||||||
|
"step4-download": "Download PDF"
|
||||||
|
},
|
||||||
|
"maintenance-alert": "We are experiencing minor technical difficulties. We are working on solving it right now. Please come back in a few minutes."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1 @@
|
|||||||
{
|
{}
|
||||||
"test": "테스트! !!!!!!!!"
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -33,6 +33,7 @@
|
|||||||
"jsrp": "^0.2.4",
|
"jsrp": "^0.2.4",
|
||||||
"markdown-it": "^13.0.1",
|
"markdown-it": "^13.0.1",
|
||||||
"next": "^12.2.5",
|
"next": "^12.2.5",
|
||||||
|
"next-translate": "^1.6.0",
|
||||||
"posthog-js": "^1.34.0",
|
"posthog-js": "^1.34.0",
|
||||||
"query-string": "^7.1.1",
|
"query-string": "^7.1.1",
|
||||||
"react": "^17.0.2",
|
"react": "^17.0.2",
|
||||||
|
|||||||
+11
-12
@@ -55,13 +55,13 @@ export default function Login() {
|
|||||||
return (
|
return (
|
||||||
<div className="bg-bunker-800 h-screen flex flex-col justify-start px-6">
|
<div className="bg-bunker-800 h-screen flex flex-col justify-start px-6">
|
||||||
<Head>
|
<Head>
|
||||||
<title>Login</title>
|
<title>{t("meta.login.title")}</title>
|
||||||
<link rel="icon" href="/infisical.ico" />
|
<link rel="icon" href="/infisical.ico" />
|
||||||
<meta property="og:image" content="/images/message.png" />
|
<meta property="og:image" content="/images/message.png" />
|
||||||
<meta property="og:title" content="Log In to Infisical" />
|
<meta property="og:title" content={t("meta.login.og-title")} />
|
||||||
<meta
|
<meta
|
||||||
name="og:description"
|
name="og:description"
|
||||||
content="Infisical a simple end-to-end encrypted platform that enables teams to sync and manage their .env files."
|
content={t("meta.login.og-description")}
|
||||||
/>
|
/>
|
||||||
</Head>
|
</Head>
|
||||||
<Link href="/">
|
<Link href="/">
|
||||||
@@ -76,25 +76,25 @@ export default function Login() {
|
|||||||
</Link>
|
</Link>
|
||||||
<div className="bg-bunker w-full max-w-md mx-auto h-7/12 py-4 pt-8 px-6 rounded-xl drop-shadow-xl">
|
<div className="bg-bunker w-full max-w-md mx-auto h-7/12 py-4 pt-8 px-6 rounded-xl drop-shadow-xl">
|
||||||
<p className="text-4xl flex justify-center font-semibold text-transparent bg-clip-text bg-gradient-to-br from-sky-400 to-primary">
|
<p className="text-4xl flex justify-center font-semibold text-transparent bg-clip-text bg-gradient-to-br from-sky-400 to-primary">
|
||||||
Log In {t("test")}
|
{t("auth.login")}
|
||||||
</p>
|
</p>
|
||||||
<div className="flex flex-row items-center justify-center">
|
<div className="flex flex-row items-center justify-center">
|
||||||
<p className="text-md flex justify-center mt-2 text-gray-400">
|
<p className="text-md flex justify-center mt-2 text-gray-400">
|
||||||
Need an Infisical account?
|
{t("auth.need-account")}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-col items-center justify-center w-full md:pb-4 max-h-24 max-w-md mx-auto">
|
<div className="flex flex-col items-center justify-center w-full md:pb-4 max-h-24 max-w-md mx-auto">
|
||||||
<Link href="/signup">
|
<Link href="/signup">
|
||||||
<button className="w-full pb-3 hover:opacity-90 duration-200">
|
<button className="w-full pb-3 hover:opacity-90 duration-200">
|
||||||
<u className="font-normal text-md text-sky-500">
|
<u className="font-normal text-md text-sky-500">
|
||||||
Create an account
|
{t("auth.create-account")}
|
||||||
</u>
|
</u>
|
||||||
</button>
|
</button>
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center justify-center w-full md:p-2 rounded-lg mt-4 md:mt-0 max-h-24 md:max-h-28">
|
<div className="flex items-center justify-center w-full md:p-2 rounded-lg mt-4 md:mt-0 max-h-24 md:max-h-28">
|
||||||
<InputField
|
<InputField
|
||||||
label="Email"
|
label={t("email")}
|
||||||
onChangeHandler={setEmail}
|
onChangeHandler={setEmail}
|
||||||
type="email"
|
type="email"
|
||||||
value={email}
|
value={email}
|
||||||
@@ -104,7 +104,7 @@ export default function Login() {
|
|||||||
</div>
|
</div>
|
||||||
<div className="flex items-center justify-center w-full md:p-2 rounded-lg md:mt-2 mt-6 max-h-24 md:max-h-28">
|
<div className="flex items-center justify-center w-full md:p-2 rounded-lg md:mt-2 mt-6 max-h-24 md:max-h-28">
|
||||||
<InputField
|
<InputField
|
||||||
label="Password"
|
label={t("password")}
|
||||||
onChangeHandler={setPassword}
|
onChangeHandler={setPassword}
|
||||||
type="password"
|
type="password"
|
||||||
value={password}
|
value={password}
|
||||||
@@ -118,7 +118,7 @@ export default function Login() {
|
|||||||
<div className="flex flex-col items-center justify-center w-full md:p-2 max-h-20 max-w-md mt-4 mx-auto text-sm">
|
<div className="flex flex-col items-center justify-center w-full md:p-2 max-h-20 max-w-md mt-4 mx-auto text-sm">
|
||||||
<div className="text-l mt-6 m-8 px-8 py-3 text-lg">
|
<div className="text-l mt-6 m-8 px-8 py-3 text-lg">
|
||||||
<Button
|
<Button
|
||||||
text="Log In"
|
text={t("login")}
|
||||||
onButtonPressed={loginCheck}
|
onButtonPressed={loginCheck}
|
||||||
loading={isLoading}
|
loading={isLoading}
|
||||||
size="lg"
|
size="lg"
|
||||||
@@ -135,9 +135,8 @@ export default function Login() {
|
|||||||
icon={faWarning}
|
icon={faWarning}
|
||||||
className="ml-2 mr-6 text-6xl"
|
className="ml-2 mr-6 text-6xl"
|
||||||
/>
|
/>
|
||||||
We are experiencing minor technical difficulties. We are
|
|
||||||
working on solving it right now. Please come back in a few
|
{t("maintenance-alert")}
|
||||||
minutes.
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+179
-78
@@ -19,6 +19,8 @@ import attemptLogin from "../components/utilities/attemptLogin";
|
|||||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||||
import { faCheck, faX, faWarning } from "@fortawesome/free-solid-svg-icons";
|
import { faCheck, faX, faWarning } from "@fortawesome/free-solid-svg-icons";
|
||||||
import issueBackupKey from "../components/utilities/issueBackupKey";
|
import issueBackupKey from "../components/utilities/issueBackupKey";
|
||||||
|
import useTranslation from "next-translate/useTranslation";
|
||||||
|
import Trans from "next-translate/Trans";
|
||||||
|
|
||||||
const ReactCodeInput = dynamic(import("react-code-input"));
|
const ReactCodeInput = dynamic(import("react-code-input"));
|
||||||
const nacl = require("tweetnacl");
|
const nacl = require("tweetnacl");
|
||||||
@@ -73,7 +75,8 @@ export default function SignUp() {
|
|||||||
const [passwordErrorNumber, setPasswordErrorNumber] = useState(false);
|
const [passwordErrorNumber, setPasswordErrorNumber] = useState(false);
|
||||||
const [passwordErrorUpperCase, setPasswordErrorUpperCase] = useState(false);
|
const [passwordErrorUpperCase, setPasswordErrorUpperCase] = useState(false);
|
||||||
const [passwordErrorLowerCase, setPasswordErrorLowerCase] = useState(false);
|
const [passwordErrorLowerCase, setPasswordErrorLowerCase] = useState(false);
|
||||||
const [passwordErrorSpecialChar, setPasswordErrorSpecialChar] = useState(false);
|
const [passwordErrorSpecialChar, setPasswordErrorSpecialChar] =
|
||||||
|
useState(false);
|
||||||
const [emailError, setEmailError] = useState(false);
|
const [emailError, setEmailError] = useState(false);
|
||||||
const [emailErrorMessage, setEmailErrorMessage] = useState("");
|
const [emailErrorMessage, setEmailErrorMessage] = useState("");
|
||||||
const [step, setStep] = useState(1);
|
const [step, setStep] = useState(1);
|
||||||
@@ -84,6 +87,8 @@ export default function SignUp() {
|
|||||||
const [verificationToken, setVerificationToken] = useState();
|
const [verificationToken, setVerificationToken] = useState();
|
||||||
const [backupKeyIssued, setBackupKeyIssued] = useState(false);
|
const [backupKeyIssued, setBackupKeyIssued] = useState(false);
|
||||||
|
|
||||||
|
const { t } = useTranslation("common");
|
||||||
|
|
||||||
useEffect(async () => {
|
useEffect(async () => {
|
||||||
let userWorkspace;
|
let userWorkspace;
|
||||||
try {
|
try {
|
||||||
@@ -108,7 +113,7 @@ export default function SignUp() {
|
|||||||
// Checking if the code matches the email.
|
// Checking if the code matches the email.
|
||||||
const response = await checkEmailVerificationCode(email, code);
|
const response = await checkEmailVerificationCode(email, code);
|
||||||
if (response.status == "200" || code == "111222") {
|
if (response.status == "200" || code == "111222") {
|
||||||
setVerificationToken((await response.json()).token)
|
setVerificationToken((await response.json()).token);
|
||||||
setStep(3);
|
setStep(3);
|
||||||
} else {
|
} else {
|
||||||
setCodeError(true);
|
setCodeError(true);
|
||||||
@@ -180,7 +185,14 @@ export default function SignUp() {
|
|||||||
|
|
||||||
const { ciphertext, iv, tag } = Aes256Gcm.encrypt(
|
const { ciphertext, iv, tag } = Aes256Gcm.encrypt(
|
||||||
PRIVATE_KEY,
|
PRIVATE_KEY,
|
||||||
password.slice(0, 32).padStart(32 + (password.slice(0, 32).length - new Blob([password]).size), "0")
|
password
|
||||||
|
.slice(0, 32)
|
||||||
|
.padStart(
|
||||||
|
32 +
|
||||||
|
(password.slice(0, 32).length -
|
||||||
|
new Blob([password]).size),
|
||||||
|
"0"
|
||||||
|
)
|
||||||
);
|
);
|
||||||
localStorage.setItem("PRIVATE_KEY", PRIVATE_KEY);
|
localStorage.setItem("PRIVATE_KEY", PRIVATE_KEY);
|
||||||
|
|
||||||
@@ -191,19 +203,21 @@ export default function SignUp() {
|
|||||||
},
|
},
|
||||||
async () => {
|
async () => {
|
||||||
client.createVerifier(async (err, result) => {
|
client.createVerifier(async (err, result) => {
|
||||||
const response = await completeAccountInformationSignup({
|
const response = await completeAccountInformationSignup(
|
||||||
email,
|
{
|
||||||
firstName,
|
email,
|
||||||
lastName,
|
firstName,
|
||||||
organizationName: firstName + "'s organization",
|
lastName,
|
||||||
publicKey: PUBLIC_KEY,
|
organizationName: firstName + "'s organization",
|
||||||
ciphertext,
|
publicKey: PUBLIC_KEY,
|
||||||
iv,
|
ciphertext,
|
||||||
tag,
|
iv,
|
||||||
salt: result.salt,
|
tag,
|
||||||
verifier: result.verifier,
|
salt: result.salt,
|
||||||
token: verificationToken
|
verifier: result.verifier,
|
||||||
});
|
token: verificationToken,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
// if everything works, go the main dashboard page.
|
// if everything works, go the main dashboard page.
|
||||||
if (!errorCheck && response.status == "200") {
|
if (!errorCheck && response.status == "200") {
|
||||||
@@ -243,20 +257,20 @@ export default function SignUp() {
|
|||||||
const step1 = (
|
const step1 = (
|
||||||
<div className="bg-bunker w-full max-w-md mx-auto h-7/12 py-8 md:px-6 mx-1 mb-48 md:mb-16 rounded-xl drop-shadow-xl">
|
<div className="bg-bunker w-full max-w-md mx-auto h-7/12 py-8 md:px-6 mx-1 mb-48 md:mb-16 rounded-xl drop-shadow-xl">
|
||||||
<p className="text-4xl font-semibold flex justify-center text-transparent bg-clip-text bg-gradient-to-br from-sky-400 to-primary">
|
<p className="text-4xl font-semibold flex justify-center text-transparent bg-clip-text bg-gradient-to-br from-sky-400 to-primary">
|
||||||
Let's get started
|
{t("auth.step1-start")}
|
||||||
</p>
|
</p>
|
||||||
<div className="flex flex-col items-center justify-center w-full md:pb-2 max-h-24 max-w-md mx-auto pt-2">
|
<div className="flex flex-col items-center justify-center w-full md:pb-2 max-h-24 max-w-md mx-auto pt-2">
|
||||||
<Link href="/login">
|
<Link href="/login">
|
||||||
<button className="w-max pb-3 hover:opacity-90 duration-200">
|
<button className="w-max pb-3 hover:opacity-90 duration-200">
|
||||||
<u className="font-normal text-md text-sky-500">
|
<u className="font-normal text-md text-sky-500">
|
||||||
Have an account? Log in
|
{t("auth.already-have-account")}
|
||||||
</u>
|
</u>
|
||||||
</button>
|
</button>
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center justify-center w-5/6 md:w-full m-auto md:p-2 rounded-lg max-h-24 mt-4">
|
<div className="flex items-center justify-center w-5/6 md:w-full m-auto md:p-2 rounded-lg max-h-24 mt-4">
|
||||||
<InputField
|
<InputField
|
||||||
label="Email"
|
label={t("email")}
|
||||||
onChangeHandler={setEmail}
|
onChangeHandler={setEmail}
|
||||||
type="email"
|
type="email"
|
||||||
value={email}
|
value={email}
|
||||||
@@ -276,7 +290,11 @@ export default function SignUp() {
|
|||||||
and acknowledged the Privacy Policy.
|
and acknowledged the Privacy Policy.
|
||||||
</p>
|
</p>
|
||||||
<div className="text-l mt-6 m-2 md:m-8 px-8 py-1 text-lg">
|
<div className="text-l mt-6 m-2 md:m-8 px-8 py-1 text-lg">
|
||||||
<Button text="Get Started" onButtonPressed={emailCheck} size="lg"/>
|
<Button
|
||||||
|
text={t("auth.step1-submit")}
|
||||||
|
onButtonPressed={emailCheck}
|
||||||
|
size="lg"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -285,12 +303,19 @@ export default function SignUp() {
|
|||||||
// Step 2 of the signup process (enter the email verification code)
|
// Step 2 of the signup process (enter the email verification code)
|
||||||
const step2 = (
|
const step2 = (
|
||||||
<div className="bg-bunker w-max mx-auto h-7/12 pt-10 pb-4 px-8 rounded-xl drop-shadow-xl mb-64 md:mb-16">
|
<div className="bg-bunker w-max mx-auto h-7/12 pt-10 pb-4 px-8 rounded-xl drop-shadow-xl mb-64 md:mb-16">
|
||||||
<p className="text-l flex justify-center text-gray-400">
|
<Trans
|
||||||
We've sent a verification email to{" "}
|
i18nKey="common:auth.step2-message"
|
||||||
</p>
|
components={{
|
||||||
<p className="text-l flex justify-center font-semibold my-2 text-gray-400">
|
wrapper: (
|
||||||
{email}{" "}
|
<p className="text-l flex justify-center text-gray-400" />
|
||||||
</p>
|
),
|
||||||
|
email: (
|
||||||
|
<p className="text-l flex justify-center font-semibold my-2 text-gray-400" />
|
||||||
|
),
|
||||||
|
}}
|
||||||
|
values={{ email }}
|
||||||
|
/>
|
||||||
|
|
||||||
<div className="hidden md:block">
|
<div className="hidden md:block">
|
||||||
<ReactCodeInput
|
<ReactCodeInput
|
||||||
type="text"
|
type="text"
|
||||||
@@ -309,11 +334,13 @@ export default function SignUp() {
|
|||||||
className="mt-2 mb-6"
|
className="mt-2 mb-6"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{codeError && (
|
{codeError && <Error text={t("auth.step2-code-error")} />}
|
||||||
<Error text="Oops. Your code is wrong. Please try again." />
|
|
||||||
)}
|
|
||||||
<div className="flex max-w-min flex-col items-center justify-center md:p-2 max-h-24 max-w-md mx-auto text-lg px-4 mt-4 mb-2">
|
<div className="flex max-w-min flex-col items-center justify-center md:p-2 max-h-24 max-w-md mx-auto text-lg px-4 mt-4 mb-2">
|
||||||
<Button text="Verify" onButtonPressed={incrementStep} size="lg"/>
|
<Button
|
||||||
|
text={t("verify")}
|
||||||
|
onButtonPressed={incrementStep}
|
||||||
|
size="lg"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-col items-center justify-center w-full max-h-24 max-w-md mx-auto pt-2">
|
<div className="flex flex-col items-center justify-center w-full max-h-24 max-w-md mx-auto pt-2">
|
||||||
{/* <Link href="/login">
|
{/* <Link href="/login">
|
||||||
@@ -324,7 +351,7 @@ export default function SignUp() {
|
|||||||
</button>
|
</button>
|
||||||
</Link> */}
|
</Link> */}
|
||||||
<p className="text-sm text-gray-500 pb-2">
|
<p className="text-sm text-gray-500 pb-2">
|
||||||
Make sure to check your spam inbox.
|
{t("auth.step2-spam-alert")}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -334,33 +361,37 @@ export default function SignUp() {
|
|||||||
const step3 = (
|
const step3 = (
|
||||||
<div className="bg-bunker w-max mx-auto h-7/12 py-10 px-8 rounded-xl drop-shadow-xl mb-36 md:mb-16">
|
<div className="bg-bunker w-max mx-auto h-7/12 py-10 px-8 rounded-xl drop-shadow-xl mb-36 md:mb-16">
|
||||||
<p className="text-4xl font-bold flex justify-center mb-6 text-gray-400 mx-8 md:mx-16 text-transparent bg-clip-text bg-gradient-to-br from-sky-400 to-primary">
|
<p className="text-4xl font-bold flex justify-center mb-6 text-gray-400 mx-8 md:mx-16 text-transparent bg-clip-text bg-gradient-to-br from-sky-400 to-primary">
|
||||||
Almost there!
|
{t("auth.step3-message")}
|
||||||
</p>
|
</p>
|
||||||
<div className="relative z-0 flex items-center justify-end w-full md:p-2 rounded-lg max-h-24">
|
<div className="relative z-0 flex items-center justify-end w-full md:p-2 rounded-lg max-h-24">
|
||||||
<InputField
|
<InputField
|
||||||
label="First Name"
|
label={t("first-name")}
|
||||||
onChangeHandler={setFirstName}
|
onChangeHandler={setFirstName}
|
||||||
type="name"
|
type="name"
|
||||||
value={firstName}
|
value={firstName}
|
||||||
isRequired
|
isRequired
|
||||||
errorText="Please input your first name."
|
errorText={t("validate-required", {
|
||||||
|
name: t("first-name"),
|
||||||
|
})}
|
||||||
error={firstNameError}
|
error={firstNameError}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="mt-2 flex items-center justify-center w-full md:p-2 rounded-lg max-h-24">
|
<div className="mt-2 flex items-center justify-center w-full md:p-2 rounded-lg max-h-24">
|
||||||
<InputField
|
<InputField
|
||||||
label="Last Name"
|
label={t("last-name")}
|
||||||
onChangeHandler={setLastName}
|
onChangeHandler={setLastName}
|
||||||
type="name"
|
type="name"
|
||||||
value={lastName}
|
value={lastName}
|
||||||
isRequired
|
isRequired
|
||||||
errorText="Please input your last name."
|
errorText={t("validate-required", {
|
||||||
|
name: t("last-name"),
|
||||||
|
})}
|
||||||
error={lastNameError}
|
error={lastNameError}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="mt-2 flex flex-col items-center justify-center w-full md:p-2 rounded-lg max-h-60">
|
<div className="mt-2 flex flex-col items-center justify-center w-full md:p-2 rounded-lg max-h-60">
|
||||||
<InputField
|
<InputField
|
||||||
label="Password"
|
label={t("password")}
|
||||||
onChangeHandler={(password) => {
|
onChangeHandler={(password) => {
|
||||||
setPassword(password);
|
setPassword(password);
|
||||||
passwordCheck(
|
passwordCheck(
|
||||||
@@ -374,61 +405,128 @@ export default function SignUp() {
|
|||||||
type="password"
|
type="password"
|
||||||
value={password}
|
value={password}
|
||||||
isRequired
|
isRequired
|
||||||
error={passwordErrorLength && passwordErrorNumber && passwordErrorLowerCase}
|
error={
|
||||||
|
passwordErrorLength &&
|
||||||
|
passwordErrorNumber &&
|
||||||
|
passwordErrorLowerCase
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
{(passwordErrorLength || passwordErrorLowerCase || passwordErrorNumber) ? <div className="w-full mt-4 bg-white/5 px-2 flex flex-col items-start py-2 rounded-md">
|
{passwordErrorLength ||
|
||||||
<div className={`text-gray-400 text-sm mb-1`}>Password should contain at least:</div>
|
passwordErrorLowerCase ||
|
||||||
<div className="flex flex-row justify-start items-center ml-1">
|
passwordErrorNumber ? (
|
||||||
{passwordErrorLength
|
<div className="w-full mt-4 bg-white/5 px-2 flex flex-col items-start py-2 rounded-md">
|
||||||
? <FontAwesomeIcon icon={faX} className="text-md text-red mr-2.5"/>
|
<div className={`text-gray-400 text-sm mb-1`}>
|
||||||
: <FontAwesomeIcon icon={faCheck} className="text-md text-primary mr-2"/>}
|
{t("password-validate")}
|
||||||
<div className={`${passwordErrorLength ? "text-gray-400" : "text-gray-600"} text-sm`}>14 characters</div>
|
</div>
|
||||||
|
<div className="flex flex-row justify-start items-center ml-1">
|
||||||
|
{passwordErrorLength ? (
|
||||||
|
<FontAwesomeIcon
|
||||||
|
icon={faX}
|
||||||
|
className="text-md text-red mr-2.5"
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<FontAwesomeIcon
|
||||||
|
icon={faCheck}
|
||||||
|
className="text-md text-primary mr-2"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
<div
|
||||||
|
className={`${
|
||||||
|
passwordErrorLength
|
||||||
|
? "text-gray-400"
|
||||||
|
: "text-gray-600"
|
||||||
|
} text-sm`}
|
||||||
|
>
|
||||||
|
{t("password-validate-length")}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="flex flex-row justify-start items-center ml-1">
|
||||||
|
{passwordErrorLowerCase ? (
|
||||||
|
<FontAwesomeIcon
|
||||||
|
icon={faX}
|
||||||
|
className="text-md text-red mr-2.5"
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<FontAwesomeIcon
|
||||||
|
icon={faCheck}
|
||||||
|
className="text-md text-primary mr-2"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
<div
|
||||||
|
className={`${
|
||||||
|
passwordErrorLowerCase
|
||||||
|
? "text-gray-400"
|
||||||
|
: "text-gray-600"
|
||||||
|
} text-sm`}
|
||||||
|
>
|
||||||
|
{t("password-validate-case")}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="flex flex-row justify-start items-center ml-1">
|
||||||
|
{passwordErrorNumber ? (
|
||||||
|
<FontAwesomeIcon
|
||||||
|
icon={faX}
|
||||||
|
className="text-md text-red mr-2.5"
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<FontAwesomeIcon
|
||||||
|
icon={faCheck}
|
||||||
|
className="text-md text-primary mr-2"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
<div
|
||||||
|
className={`${
|
||||||
|
passwordErrorNumber
|
||||||
|
? "text-gray-400"
|
||||||
|
: "text-gray-600"
|
||||||
|
} text-sm`}
|
||||||
|
>
|
||||||
|
{t("password-validate-number")}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-row justify-start items-center ml-1">
|
) : (
|
||||||
{passwordErrorLowerCase
|
<div className="py-2"></div>
|
||||||
? <FontAwesomeIcon icon={faX} className="text-md text-red mr-2.5"/>
|
)}
|
||||||
: <FontAwesomeIcon icon={faCheck} className="text-md text-primary mr-2"/>}
|
|
||||||
<div className={`${passwordErrorLowerCase ? "text-gray-400" : "text-gray-600"} text-sm`}>1 lowercase character</div>
|
|
||||||
</div>
|
|
||||||
<div className="flex flex-row justify-start items-center ml-1">
|
|
||||||
{passwordErrorNumber
|
|
||||||
? <FontAwesomeIcon icon={faX} className="text-md text-red mr-2.5"/>
|
|
||||||
: <FontAwesomeIcon icon={faCheck} className="text-md text-primary mr-2"/>}
|
|
||||||
<div className={`${passwordErrorNumber ? "text-gray-400" : "text-gray-600"} text-sm`}>1 number</div>
|
|
||||||
</div>
|
|
||||||
</div> : <div className="py-2"></div>}
|
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-col items-center justify-center md:p-2 max-h-48 max-w-max mx-auto text-lg px-2 py-3">
|
<div className="flex flex-col items-center justify-center md:p-2 max-h-48 max-w-max mx-auto text-lg px-2 py-3">
|
||||||
<Button text="Sign Up" loading={isLoading} onButtonPressed={signupErrorCheck} size="lg" />
|
<Button
|
||||||
|
text={t("auth.signup")}
|
||||||
|
loading={isLoading}
|
||||||
|
onButtonPressed={signupErrorCheck}
|
||||||
|
size="lg"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
// Step 4 of the sign up process (download the emergency kit pdf)
|
// Step 4 of the sign up process (download the emergency kit pdf)
|
||||||
const step4 = (
|
const step4 = (
|
||||||
<div className="bg-bunker flex flex-col items-center w-full max-w-xs md:max-w-lg mx-auto h-7/12 py-8 px-4 md:px-6 mx-1 mb-36 md:mb-16 rounded-xl drop-shadow-xl">
|
<div className="bg-bunker flex flex-col items-center w-full max-w-xs md:max-w-lg mx-auto h-7/12 py-8 px-4 md:px-6 mx-1 mb-36 md:mb-16 rounded-xl drop-shadow-xl">
|
||||||
<p className="text-4xl text-center font-semibold flex justify-center text-transparent bg-clip-text bg-gradient-to-br from-sky-400 to-primary">
|
<p className="text-4xl text-center font-semibold flex justify-center text-transparent bg-clip-text bg-gradient-to-br from-sky-400 to-primary">
|
||||||
Save your Emergency Kit
|
{t("auth.step4-message")}
|
||||||
</p>
|
</p>
|
||||||
<div className="flex flex-col items-center justify-center w-full mt-4 md:mt-8 max-w-md text-gray-400 text-md rounded-md px-2">
|
<div className="flex flex-col items-center justify-center w-full mt-4 md:mt-8 max-w-md text-gray-400 text-md rounded-md px-2">
|
||||||
<div>If you get locked out of your account, your Emergency Kit is the only way to sign in.</div>
|
<div>{t("auth.step4-description1")}</div>
|
||||||
<div className="mt-3">We recommend you download it and keep it somewhere safe.</div>
|
<div className="mt-3">{t("auth.step4-description2")}</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="w-full p-2 flex flex-row items-center bg-white/10 text-gray-400 rounded-md max-w-xs md:max-w-md mx-auto mt-4">
|
<div className="w-full p-2 flex flex-row items-center bg-white/10 text-gray-400 rounded-md max-w-xs md:max-w-md mx-auto mt-4">
|
||||||
<FontAwesomeIcon icon={faWarning} className="ml-2 mr-4 text-4xl"/>
|
<FontAwesomeIcon
|
||||||
It contains your Secret Key which we cannot access or recover for you if you lose it.
|
icon={faWarning}
|
||||||
|
className="ml-2 mr-4 text-4xl"
|
||||||
|
/>
|
||||||
|
{t("auth.step4-description3")}
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-row items-center justify-center w-3/4 md:w-full md:p-2 max-h-28 max-w-max mx-auto mt-6 py-1 md:mt-4 text-lg text-center md:text-left">
|
<div className="flex flex-row items-center justify-center w-3/4 md:w-full md:p-2 max-h-28 max-w-max mx-auto mt-6 py-1 md:mt-4 text-lg text-center md:text-left">
|
||||||
<Button
|
<Button
|
||||||
text="Download PDF"
|
text={t("auth.step4-download")}
|
||||||
onButtonPressed={async () => {
|
onButtonPressed={async () => {
|
||||||
await issueBackupKey({
|
await issueBackupKey({
|
||||||
email,
|
email,
|
||||||
password,
|
password,
|
||||||
personalName: (firstName + " " + lastName),
|
personalName: firstName + " " + lastName,
|
||||||
setBackupKeyError,
|
setBackupKeyError,
|
||||||
setBackupKeyIssued
|
setBackupKeyIssued,
|
||||||
});
|
});
|
||||||
router.push("/dashboard/");
|
router.push("/dashboard/");
|
||||||
}}
|
}}
|
||||||
@@ -453,16 +551,13 @@ export default function SignUp() {
|
|||||||
return (
|
return (
|
||||||
<div className="bg-bunker-800 h-screen flex flex-col items-center justify-center">
|
<div className="bg-bunker-800 h-screen flex flex-col items-center justify-center">
|
||||||
<Head>
|
<Head>
|
||||||
<title>Infiscal | Sign Up</title>
|
<title>{t("meta.signup.title")}</title>
|
||||||
<link rel="icon" href="/infisical.ico" />
|
<link rel="icon" href="/infisical.ico" />
|
||||||
<meta property="og:image" content="/images/message.png" />
|
<meta property="og:image" content="/images/message.png" />
|
||||||
<meta
|
<meta property="og:title" content={t("meta.signup.og-title")} />
|
||||||
property="og:title"
|
|
||||||
content="Replace .env files with 1 line of code. Sign Up for Infisical in 3 minutes."
|
|
||||||
/>
|
|
||||||
<meta
|
<meta
|
||||||
name="og:description"
|
name="og:description"
|
||||||
content="Infisical a simple end-to-end encrypted platform that enables teams to sync and manage API-keys and environemntal variables. Works with Node.js, Next.js, Gatsby, Nest.js..."
|
content={t("meta.signup.og-description")}
|
||||||
/>
|
/>
|
||||||
</Head>
|
</Head>
|
||||||
<div className="flex flex-col justify-center items-center">
|
<div className="flex flex-col justify-center items-center">
|
||||||
@@ -476,7 +571,13 @@ export default function SignUp() {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</Link>
|
</Link>
|
||||||
{step == 1 ? step1 : step == 2 ? step2 : step == 3 ? step3 : step4}
|
{step == 1
|
||||||
|
? step1
|
||||||
|
: step == 2
|
||||||
|
? step2
|
||||||
|
: step == 3
|
||||||
|
? step3
|
||||||
|
: step4}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1791,6 +1791,11 @@ nanoid@^3.3.4:
|
|||||||
resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz"
|
resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz"
|
||||||
integrity sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==
|
integrity sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==
|
||||||
|
|
||||||
|
next-translate@^1.6.0:
|
||||||
|
version "1.6.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/next-translate/-/next-translate-1.6.0.tgz#28329d9970030c573c529a1a6d5c6b4e75146164"
|
||||||
|
integrity sha512-rmRBYOwPHvokN+5uH3O/SZqfRUVORLkgt/097mSaq3+CWcEtXEjkVrfBZpYwZ8W3og4QVd+uphYX//qegnIbRg==
|
||||||
|
|
||||||
next@^12.2.5:
|
next@^12.2.5:
|
||||||
version "12.3.1"
|
version "12.3.1"
|
||||||
resolved "https://registry.npmjs.org/next/-/next-12.3.1.tgz"
|
resolved "https://registry.npmjs.org/next/-/next-12.3.1.tgz"
|
||||||
|
|||||||
Reference in New Issue
Block a user