mirror of
https://github.com/Infisical/infisical.git
synced 2025-03-22 21:37:16 +00:00
Compare commits
20 Commits
Author | SHA1 | Date | |
---|---|---|---|
dcbf8525bd | |||
79ddada537 | |||
44da5da300 | |||
9e28ba9b84 | |||
454d1d304a | |||
8f8c501a64 | |||
665c6b1a6d | |||
a4285df0ff | |||
f642a46924 | |||
f020b553b3 | |||
28335ceabd | |||
ee0a95c1db | |||
78d4fb2300 | |||
bec139315f | |||
142ed1541c | |||
417eddaeff | |||
6405e9f43f | |||
13e7883373 | |||
d25f4ccc89 | |||
71a7497ea7 |
README.md
backend/src/controllers
cli/packages
docs/cli
frontend
components
basic
dashboard
integrations
navigation
pages
dashboard.js
dashboard
heroku.jshome
index.jsintegrations
login.tsxnetlify.jspassword-reset.tsxsettings
signup.tsxsignupinvite.jsusers
vercel.jsverify-email.tsx@ -321,4 +321,4 @@ Infisical officially launched as v.1.0 on November 21st, 2022. However, a lot of
|
||||
<!-- prettier-ignore-start -->
|
||||
<!-- markdownlint-disable -->
|
||||
|
||||
<a href="https://github.com/dangtony98"><img src="https://avatars.githubusercontent.com/u/25857006?v=4" width="50" height="50" alt=""/></a> <a href="https://github.com/mv-turtle"><img src="https://avatars.githubusercontent.com/u/78047717?s=96&v=4" width="50" height="50" alt=""/></a> <a href="https://github.com/maidul98"><img src="https://avatars.githubusercontent.com/u/9300960?v=4" width="50" height="50" alt=""/></a> <a href="https://github.com/gangjun06"><img src="https://avatars.githubusercontent.com/u/50910815?v=4" width="50" height="50" alt=""/></a> <a href="https://github.com/reginaldbondoc"><img src="https://avatars.githubusercontent.com/u/7693108?v=4" width="50" height="50" alt=""/></a> <a href="https://github.com/SH5H"><img src="https://avatars.githubusercontent.com/u/25437192?v=4" width="50" height="50" alt=""/></a> <a href="https://github.com/gmgale"><img src="https://avatars.githubusercontent.com/u/62303146?v=4" width="50" height="50" alt=""/></a> <a href="https://github.com/asharonbaltazar"><img src="https://avatars.githubusercontent.com/u/58940073?v=4" width="50" height="50" alt=""/></a> <a href="https://github.com/edgarrmondragon"><img src="https://avatars.githubusercontent.com/u/16805946?v=4" width="50" height="50" alt=""/></a> <a href="https://github.com/arjunyel"><img src="https://avatars.githubusercontent.com/u/11153289?v=4" width="50" height="50" alt=""/></a> <a href="https://github.com/LemmyMwaura"><img src="https://avatars.githubusercontent.com/u/20738858?v=4" width="50" height="50" alt=""/></a> <a href="https://github.com/Zamion101"><img src="https://avatars.githubusercontent.com/u/8071263?v=4" width="50" height="50" alt=""/></a> <a href="https://github.com/naorpeled"><img src="https://avatars.githubusercontent.com/u/6171622?v=4" width="50" height="50" alt=""/></a> <a href="https://github.com/jonerrr"><img src="https://avatars.githubusercontent.com/u/73760377?v=4" width="50" height="50" alt=""/></a> <a href="https://github.com/adrianmarinwork"><img src="https://avatars.githubusercontent.com/u/118568289?v=4" width="50" height="50" alt=""/></a> <a href="https://github.com/arthurzenika"><img src="https://avatars.githubusercontent.com/u/445200?v=4" width="50" height="50" alt=""/></a> <a href="https://github.com/hanywang2"><img src="https://avatars.githubusercontent.com/u/44352119?v=4" width="50" height="50" alt=""/></a> <a href="https://github.com/tobias-mintlify"><img src="https://avatars.githubusercontent.com/u/110702161?v=4" width="50" height="50" alt=""/></a> <a href="https://github.com/wjhurley"><img src="https://avatars.githubusercontent.com/u/15939055?v=4" width="50" height="50" alt=""/></a> <a href="https://github.com/0xflotus"><img src="https://avatars.githubusercontent.com/u/26602940?v=4" width="50" height="50" alt=""/></a> <a href="https://github.com/wanjohiryan"><img src="https://avatars.githubusercontent.com/u/71614375?v=4" width="50" height="50" alt=""/></a>
|
||||
<a href="https://github.com/dangtony98"><img src="https://avatars.githubusercontent.com/u/25857006?v=4" width="50" height="50" alt=""/></a> <a href="https://github.com/mv-turtle"><img src="https://avatars.githubusercontent.com/u/78047717?s=96&v=4" width="50" height="50" alt=""/></a> <a href="https://github.com/maidul98"><img src="https://avatars.githubusercontent.com/u/9300960?v=4" width="50" height="50" alt=""/></a> <a href="https://github.com/gangjun06"><img src="https://avatars.githubusercontent.com/u/50910815?v=4" width="50" height="50" alt=""/></a> <a href="https://github.com/reginaldbondoc"><img src="https://avatars.githubusercontent.com/u/7693108?v=4" width="50" height="50" alt=""/></a> <a href="https://github.com/SH5H"><img src="https://avatars.githubusercontent.com/u/25437192?v=4" width="50" height="50" alt=""/></a> <a href="https://github.com/gmgale"><img src="https://avatars.githubusercontent.com/u/62303146?v=4" width="50" height="50" alt=""/></a> <a href="https://github.com/asharonbaltazar"><img src="https://avatars.githubusercontent.com/u/58940073?v=4" width="50" height="50" alt=""/></a> <a href="https://github.com/edgarrmondragon"><img src="https://avatars.githubusercontent.com/u/16805946?v=4" width="50" height="50" alt=""/></a> <a href="https://github.com/arjunyel"><img src="https://avatars.githubusercontent.com/u/11153289?v=4" width="50" height="50" alt=""/></a> <a href="https://github.com/LemmyMwaura"><img src="https://avatars.githubusercontent.com/u/20738858?v=4" width="50" height="50" alt=""/></a> <a href="https://github.com/Zamion101"><img src="https://avatars.githubusercontent.com/u/8071263?v=4" width="50" height="50" alt=""/></a> <a href="https://github.com/akhilmhdh"><img src="https://avatars.githubusercontent.com/u/31166322?v=4" width="50" height="50" alt=""/></a> <a href="https://github.com/naorpeled"><img src="https://avatars.githubusercontent.com/u/6171622?v=4" width="50" height="50" alt=""/></a> <a href="https://github.com/jonerrr"><img src="https://avatars.githubusercontent.com/u/73760377?v=4" width="50" height="50" alt=""/></a> <a href="https://github.com/adrianmarinwork"><img src="https://avatars.githubusercontent.com/u/118568289?v=4" width="50" height="50" alt=""/></a> <a href="https://github.com/arthurzenika"><img src="https://avatars.githubusercontent.com/u/445200?v=4" width="50" height="50" alt=""/></a> <a href="https://github.com/hanywang2"><img src="https://avatars.githubusercontent.com/u/44352119?v=4" width="50" height="50" alt=""/></a> <a href="https://github.com/tobias-mintlify"><img src="https://avatars.githubusercontent.com/u/110702161?v=4" width="50" height="50" alt=""/></a> <a href="https://github.com/wjhurley"><img src="https://avatars.githubusercontent.com/u/15939055?v=4" width="50" height="50" alt=""/></a> <a href="https://github.com/0xflotus"><img src="https://avatars.githubusercontent.com/u/26602940?v=4" width="50" height="50" alt=""/></a> <a href="https://github.com/wanjohiryan"><img src="https://avatars.githubusercontent.com/u/71614375?v=4" width="50" height="50" alt=""/></a>
|
||||
|
@ -10,6 +10,7 @@ import {
|
||||
} from '../helpers/signup';
|
||||
import { issueTokens, createToken } from '../helpers/auth';
|
||||
import { INVITED, ACCEPTED } from '../variables';
|
||||
import axios from 'axios';
|
||||
|
||||
/**
|
||||
* Signup step 1: Initialize account for user under email [email] and send a verification code
|
||||
@ -179,6 +180,21 @@ export const completeAccountSignup = async (req: Request, res: Response) => {
|
||||
|
||||
token = tokens.token;
|
||||
refreshToken = tokens.refreshToken;
|
||||
|
||||
// sending a welcome email to new users
|
||||
if (process.env.LOOPS_API_KEY) {
|
||||
await axios.post("https://app.loops.so/api/v1/events/send", {
|
||||
"email": email,
|
||||
"eventName": "Sign Up",
|
||||
"firstName": firstName,
|
||||
"lastName": lastName
|
||||
}, {
|
||||
headers: {
|
||||
"Accept": "application/json",
|
||||
"Authorization": "Bearer " + process.env.LOOPS_API_KEY
|
||||
},
|
||||
});
|
||||
}
|
||||
} catch (err) {
|
||||
Sentry.setUser(null);
|
||||
Sentry.captureException(err);
|
||||
|
@ -91,7 +91,9 @@ var loginCmd = &cobra.Command{
|
||||
|
||||
err = util.StoreUserCredsInKeyRing(userCredentialsToBeStored)
|
||||
if err != nil {
|
||||
log.Errorln("Unable to store your credentials in system key ring. Run with flag -d to see full logs")
|
||||
currentVault, _ := util.GetCurrentVaultBackend()
|
||||
log.Errorf("Unable to store your credentials in system vault [%s]. Rerun with flag -d to see full logs", currentVault)
|
||||
log.Errorln("To trouble shoot further, read https://infisical.com/docs/cli/faq")
|
||||
log.Debugln(err)
|
||||
return
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ var rootCmd = &cobra.Command{
|
||||
Short: "Infisical CLI is used to inject environment variables into any process",
|
||||
Long: `Infisical is a simple, end-to-end encrypted service that enables teams to sync and manage their environment variables across their development life cycle.`,
|
||||
CompletionOptions: cobra.CompletionOptions{DisableDefaultCmd: true},
|
||||
Version: "0.1.13",
|
||||
Version: "0.1.15",
|
||||
}
|
||||
|
||||
// Execute adds all child commands to the root command and sets flags appropriately.
|
||||
|
@ -60,6 +60,13 @@ var runCmd = &cobra.Command{
|
||||
return
|
||||
}
|
||||
|
||||
secretOverriding, err := cmd.Flags().GetBool("secret-overriding")
|
||||
if err != nil {
|
||||
log.Errorln("Unable to parse the secret-overriding flag")
|
||||
log.Debugln(err)
|
||||
return
|
||||
}
|
||||
|
||||
shouldExpandSecrets, err := cmd.Flags().GetBool("expand")
|
||||
if err != nil {
|
||||
log.Errorln("Unable to parse the substitute flag")
|
||||
@ -84,6 +91,10 @@ var runCmd = &cobra.Command{
|
||||
secrets = util.SubstituteSecrets(secrets)
|
||||
}
|
||||
|
||||
if secretOverriding {
|
||||
secrets = util.OverrideWithPersonalSecrets(secrets)
|
||||
}
|
||||
|
||||
if cmd.Flags().Changed("command") {
|
||||
command := cmd.Flag("command").Value.String()
|
||||
err = executeMultipleCommandWithEnvs(command, secrets)
|
||||
@ -108,6 +119,7 @@ func init() {
|
||||
runCmd.Flags().StringP("env", "e", "dev", "Set the environment (dev, prod, etc.) from which your secrets should be pulled from")
|
||||
runCmd.Flags().String("projectId", "", "The project ID from which your secrets should be pulled from")
|
||||
runCmd.Flags().Bool("expand", true, "Parse shell parameter expansions in your secrets")
|
||||
runCmd.Flags().Bool("secret-overriding", true, "Prioritizes personal secrets with the same name over shared secrets")
|
||||
runCmd.Flags().StringP("command", "c", "", "chained commands to execute (e.g. \"npm install && npm run dev; echo ...\")")
|
||||
}
|
||||
|
||||
|
@ -42,7 +42,7 @@ var vaultSetCmd = &cobra.Command{
|
||||
|
||||
err = util.WriteConfigFile(&configFile)
|
||||
if err != nil {
|
||||
log.Errorf("Unable to set vault to [%s] because an error occurred when saving the config file [err=%s]")
|
||||
log.Errorf("Unable to set vault to [%s] because an error occurred when saving the config file [err=%s]", wantedVaultTypeName, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -17,6 +17,7 @@ type ConfigFile struct {
|
||||
type SingleEnvironmentVariable struct {
|
||||
Key string `json:"key"`
|
||||
Value string `json:"value"`
|
||||
Type string `json:"type"`
|
||||
}
|
||||
|
||||
type WorkspaceConfigFile struct {
|
||||
|
@ -19,6 +19,7 @@ func GetHomeDir() (string, error) {
|
||||
return directory, err
|
||||
}
|
||||
|
||||
// write file to given path. If path does not exist throw error
|
||||
func WriteToFile(fileName string, dataToWrite []byte, filePerm os.FileMode) error {
|
||||
err := os.WriteFile(fileName, dataToWrite, filePerm)
|
||||
if err != nil {
|
||||
|
@ -187,7 +187,7 @@ func GetConfigFile() (models.ConfigFile, error) {
|
||||
|
||||
// Write a ConfigFile to disk. Raise error if unable to save the model to ask
|
||||
func WriteConfigFile(configFile *models.ConfigFile) error {
|
||||
fullConfigFilePath, _, err := GetFullConfigFilePath()
|
||||
fullConfigFilePath, fullConfigFileDirPath, err := GetFullConfigFilePath()
|
||||
if err != nil {
|
||||
return fmt.Errorf("writeConfigFile: unable to write config file because an error occurred when getting config file path [err=%s]", err)
|
||||
}
|
||||
@ -197,8 +197,20 @@ func WriteConfigFile(configFile *models.ConfigFile) error {
|
||||
return fmt.Errorf("writeConfigFile: unable to write config file because an error occurred when marshalling the config file [err=%s]", err)
|
||||
}
|
||||
|
||||
// check if config folder exists and if not create it
|
||||
if _, err := os.Stat(fullConfigFileDirPath); errors.Is(err, os.ErrNotExist) {
|
||||
err := os.Mkdir(fullConfigFileDirPath, os.ModePerm)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Create file in directory
|
||||
err = WriteToFile(fullConfigFilePath, configFileMarshalled, os.ModePerm)
|
||||
err = os.WriteFile(fullConfigFilePath, configFileMarshalled, os.ModePerm)
|
||||
if err != nil {
|
||||
return fmt.Errorf("writeConfigFile: Unable to write to file [err=%s]", err)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("writeConfigFile: unable to write config file because an error occurred when write the config to file [err=%s]", err)
|
||||
|
||||
|
@ -14,6 +14,9 @@ import (
|
||||
"golang.org/x/crypto/nacl/box"
|
||||
)
|
||||
|
||||
const PERSONAL_SECRET_TYPE_NAME = "personal"
|
||||
const SHARED_SECRET_TYPE_NAME = "shared"
|
||||
|
||||
func getSecretsByWorkspaceIdAndEnvName(httpClient resty.Client, envName string, workspace models.WorkspaceConfigFile, userCreds models.UserCredentials) (listOfSecrets []models.SingleEnvironmentVariable, err error) {
|
||||
var pullSecretsRequestResponse models.PullSecretsResponse
|
||||
response, err := httpClient.
|
||||
@ -78,6 +81,7 @@ func getSecretsByWorkspaceIdAndEnvName(httpClient resty.Client, envName string,
|
||||
env := models.SingleEnvironmentVariable{
|
||||
Key: string(plainTextKey),
|
||||
Value: string(plainTextValue),
|
||||
Type: string(secret.Type),
|
||||
}
|
||||
|
||||
listOfEnv = append(listOfEnv, env)
|
||||
@ -187,6 +191,7 @@ func GetSecretsFromAPIUsingInfisicalToken(infisicalToken string, envName string,
|
||||
env := models.SingleEnvironmentVariable{
|
||||
Key: string(plainTextKey),
|
||||
Value: string(plainTextValue),
|
||||
Type: string(secret.Type),
|
||||
}
|
||||
|
||||
listOfEnv = append(listOfEnv, env)
|
||||
@ -335,9 +340,48 @@ func SubstituteSecrets(secrets []models.SingleEnvironmentVariable) []models.Sing
|
||||
expandedSecrets = append(expandedSecrets, models.SingleEnvironmentVariable{
|
||||
Key: secret.Key,
|
||||
Value: expandedVariable,
|
||||
Type: secret.Type,
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
return expandedSecrets
|
||||
}
|
||||
|
||||
// if two secrets with the same name are found, the one that has type `personal` will be in the returned list
|
||||
func OverrideWithPersonalSecrets(secrets []models.SingleEnvironmentVariable) []models.SingleEnvironmentVariable {
|
||||
personalSecret := make(map[string]models.SingleEnvironmentVariable)
|
||||
sharedSecret := make(map[string]models.SingleEnvironmentVariable)
|
||||
secretsToReturn := []models.SingleEnvironmentVariable{}
|
||||
|
||||
for _, secret := range secrets {
|
||||
if secret.Type == PERSONAL_SECRET_TYPE_NAME {
|
||||
personalSecret[secret.Key] = models.SingleEnvironmentVariable{
|
||||
Key: secret.Key,
|
||||
Value: secret.Value,
|
||||
Type: secret.Type,
|
||||
}
|
||||
}
|
||||
|
||||
if secret.Type == SHARED_SECRET_TYPE_NAME {
|
||||
sharedSecret[secret.Key] = models.SingleEnvironmentVariable{
|
||||
Key: secret.Key,
|
||||
Value: secret.Value,
|
||||
Type: secret.Type,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for _, secret := range secrets {
|
||||
personalValue, personalExists := personalSecret[secret.Key]
|
||||
sharedValue, sharedExists := sharedSecret[secret.Key]
|
||||
|
||||
if personalExists && sharedExists || personalExists && !sharedExists {
|
||||
secretsToReturn = append(secretsToReturn, personalValue)
|
||||
} else {
|
||||
secretsToReturn = append(secretsToReturn, sharedValue)
|
||||
}
|
||||
}
|
||||
|
||||
return secretsToReturn
|
||||
}
|
||||
|
@ -34,3 +34,4 @@ Inject environment variables from the platform into an application process.
|
||||
| `--projectId` | Used to link a local project to the platform (required only if injecting via the service token method) | None |
|
||||
| `--expand` | Parse shell parameter expansions in your secrets (e.g., `${DOMAIN}`) | `true` |
|
||||
| `--command` | Pass secrets into chained commands (e.g., `"first-command && second-command; more-commands..."`) | None |
|
||||
| `--secret-overriding`| Prioritizes personal secrets with the same name over shared secrets | `true` |
|
||||
|
@ -38,13 +38,7 @@ infisical init
|
||||
infisical run -- [your application start command]
|
||||
```
|
||||
|
||||
Options you can specify:
|
||||
|
||||
| Option | Description | Default value |
|
||||
| ------------- | ----------------------------------------------------------------------------------------------------------- | ------------- |
|
||||
| `--env` | Used to set the environment that secrets are pulled from. Accepted values: `dev`, `staging`, `test`, `prod` | `dev` |
|
||||
| `--projectId` | Used to link a local project to the platform (required only if injecting via the service token method) | `None` |
|
||||
| `--expand` | Parse shell parameter expansions in your secrets (e.g., `${DOMAIN}`) | `true` |
|
||||
View all available options for `run` command [here](./commands/run)
|
||||
|
||||
## Examples:
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useState } from 'react';
|
||||
import { memo,useState } from 'react';
|
||||
import { faCircle, faEye, faEyeSlash } from '@fortawesome/free-solid-svg-icons';
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||
|
||||
@ -96,6 +96,7 @@ const InputField = (
|
||||
/>
|
||||
{props.label?.includes('Password') && (
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => {
|
||||
setPasswordVisible(!passwordVisible);
|
||||
}}
|
||||
@ -139,4 +140,4 @@ const InputField = (
|
||||
}
|
||||
};
|
||||
|
||||
export default React.memo(InputField);
|
||||
export default memo(InputField);
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React from "react";
|
||||
import React, { ButtonHTMLAttributes } from "react";
|
||||
import Image from "next/image";
|
||||
import { IconProp } from "@fortawesome/fontawesome-svg-core";
|
||||
import {
|
||||
@ -18,6 +18,7 @@ type ButtonProps = {
|
||||
active?: boolean;
|
||||
iconDisabled?: string;
|
||||
textDisabled?: string;
|
||||
type?: ButtonHTMLAttributes<any>['type'];
|
||||
};
|
||||
|
||||
/**
|
||||
@ -91,6 +92,7 @@ export default function Button(props: ButtonProps): JSX.Element {
|
||||
const button = (
|
||||
<button
|
||||
disabled={!activityStatus}
|
||||
type={props.type}
|
||||
onClick={props.onButtonPressed}
|
||||
className={styleButton}
|
||||
>
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useRouter } from 'next/router';
|
||||
import { faX } from '@fortawesome/free-solid-svg-icons';
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useEffect, useMemo, useState } from 'react';
|
||||
import { useEffect, useMemo, useState } from 'react';
|
||||
import { useRouter } from 'next/router';
|
||||
import { faX } from '@fortawesome/free-solid-svg-icons';
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { SyntheticEvent, useRef } from 'react';
|
||||
import { memo, SyntheticEvent, useRef } from 'react';
|
||||
import { faCircle } from '@fortawesome/free-solid-svg-icons';
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||
|
||||
@ -153,4 +153,4 @@ const DashboardInputField = ({
|
||||
return <>Something Wrong</>;
|
||||
};
|
||||
|
||||
export default React.memo(DashboardInputField);
|
||||
export default memo(DashboardInputField);
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useRouter } from "next/router";
|
||||
import {
|
||||
faArrowRight,
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* eslint-disable react-hooks/exhaustive-deps */
|
||||
/* eslint-disable react/jsx-key */
|
||||
import React, { Fragment, useEffect, useState } from 'react';
|
||||
import { Fragment, useEffect, useState } from 'react';
|
||||
import Image from 'next/image';
|
||||
import { useRouter } from 'next/router';
|
||||
import { faGithub, faSlack } from '@fortawesome/free-brands-svg-icons';
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useRouter } from "next/router";
|
||||
import {
|
||||
faAngleRight,
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useEffect } from "react";
|
||||
import { useEffect } from "react";
|
||||
import Head from "next/head";
|
||||
import { useRouter } from "next/router";
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { Fragment, useCallback, useEffect, useState } from 'react';
|
||||
import { Fragment, useCallback, useEffect, useState } from 'react';
|
||||
import Head from 'next/head';
|
||||
import Image from 'next/image';
|
||||
import { useRouter } from 'next/router';
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useEffect } from "react";
|
||||
import { useEffect } from "react";
|
||||
import Head from "next/head";
|
||||
import { useRouter } from "next/router";
|
||||
const queryString = require("query-string");
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { useEffect, useState } from 'react';
|
||||
import Link from 'next/link';
|
||||
import { useRouter } from 'next/router';
|
||||
import { IconProp } from '@fortawesome/fontawesome-svg-core';
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useEffect } from "react";
|
||||
import { useEffect } from "react";
|
||||
import { useRouter } from "next/router";
|
||||
|
||||
export default function Home() {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { useEffect, useState } from "react";
|
||||
import Head from "next/head";
|
||||
import Image from "next/image";
|
||||
import { useRouter } from "next/router";
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { useEffect, useState } from 'react';
|
||||
import Head from 'next/head';
|
||||
import Image from 'next/image';
|
||||
import Link from 'next/link';
|
||||
@ -38,6 +38,10 @@ export default function Login() {
|
||||
* This function check if the user entered the correct credentials and should be allowed to log in.
|
||||
*/
|
||||
const loginCheck = async () => {
|
||||
if (!email || !password) {
|
||||
return;
|
||||
}
|
||||
|
||||
setIsLoading(true);
|
||||
await attemptLogin(
|
||||
email,
|
||||
@ -45,7 +49,7 @@ export default function Login() {
|
||||
setErrorLogin,
|
||||
router,
|
||||
false,
|
||||
true
|
||||
true,
|
||||
).then(() => {
|
||||
setTimeout(function () {
|
||||
setIsLoading(false);
|
||||
@ -75,68 +79,73 @@ export default function Login() {
|
||||
/>
|
||||
</div>
|
||||
</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">
|
||||
<p className="text-3xl w-max mx-auto flex justify-center font-semibold text-bunker-100 mb-6">
|
||||
Log in to your account
|
||||
</p>
|
||||
<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
|
||||
label="Email"
|
||||
onChangeHandler={setEmail}
|
||||
type="email"
|
||||
value={email}
|
||||
placeholder=""
|
||||
isRequired
|
||||
autoComplete="username"
|
||||
/>
|
||||
</div>
|
||||
<div className="relative 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
|
||||
label="Password"
|
||||
onChangeHandler={setPassword}
|
||||
type="password"
|
||||
value={password}
|
||||
placeholder=""
|
||||
isRequired
|
||||
autoComplete="current-password"
|
||||
id="current-password"
|
||||
/>
|
||||
<div className="absolute top-2 right-3 text-primary-700 hover:text-primary duration-200 cursor-pointer text-sm">
|
||||
<Link href="/verify-email">Forgot password?</Link>
|
||||
</div>
|
||||
</div>
|
||||
{errorLogin && <Error text="Your email and/or password are wrong." />}
|
||||
<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">
|
||||
<Button
|
||||
text="Log In"
|
||||
onButtonPressed={loginCheck}
|
||||
loading={isLoading}
|
||||
size="lg"
|
||||
<form
|
||||
onChange={() => setErrorLogin(false)} onSubmit={(e) => e.preventDefault()}
|
||||
>
|
||||
<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-3xl w-max mx-auto flex justify-center font-semibold text-bunker-100 mb-6">
|
||||
Log in to your account
|
||||
</p>
|
||||
<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
|
||||
label="Email"
|
||||
onChangeHandler={setEmail}
|
||||
type="email"
|
||||
value={email}
|
||||
placeholder=""
|
||||
isRequired
|
||||
autoComplete="username"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
{/* <div className="flex items-center justify-center w-full md:p-2 rounded-lg max-h-24 md:max-h-28">
|
||||
<div className="relative 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
|
||||
label="Password"
|
||||
onChangeHandler={setPassword}
|
||||
type="password"
|
||||
value={password}
|
||||
placeholder=""
|
||||
isRequired
|
||||
autoComplete="current-password"
|
||||
id="current-password"
|
||||
/>
|
||||
<div className="absolute top-2 right-3 text-primary-700 hover:text-primary duration-200 cursor-pointer text-sm">
|
||||
<Link href="/verify-email">Forgot password?</Link>
|
||||
</div>
|
||||
</div>
|
||||
{!isLoading && errorLogin && <Error text="Your email and/or password are wrong." />}
|
||||
<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">
|
||||
<Button
|
||||
type="submit"
|
||||
text="Log In"
|
||||
onButtonPressed={loginCheck}
|
||||
loading={isLoading}
|
||||
size="lg"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
{/* <div className="flex items-center justify-center w-full md:p-2 rounded-lg max-h-24 md:max-h-28">
|
||||
<p className="text-gray-400">I may have <Link href="/login"><u className="text-sky-500 cursor-pointer">forgotten my password.</u></Link></p>
|
||||
</div> */}
|
||||
</div>
|
||||
{false && (
|
||||
<div className="w-full p-2 flex flex-row items-center bg-white/10 text-gray-300 rounded-md max-w-md mx-auto mt-4">
|
||||
<FontAwesomeIcon icon={faWarning} 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 minutes.
|
||||
</div>
|
||||
)}
|
||||
<div className="flex flex-row items-center justify-center md:pb-4 mt-4">
|
||||
<p className="text-sm flex justify-center text-gray-400 w-max">
|
||||
Need an Infisical account?
|
||||
</p>
|
||||
<Link href="/signup">
|
||||
<button className="text-primary-700 hover:text-primary duration-200 font-normal text-sm underline-offset-4 ml-1.5">
|
||||
Sign up here.
|
||||
</button>
|
||||
</Link>
|
||||
</div>
|
||||
{false && (
|
||||
<div className="w-full p-2 flex flex-row items-center bg-white/10 text-gray-300 rounded-md max-w-md mx-auto mt-4">
|
||||
<FontAwesomeIcon icon={faWarning} 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 minutes.
|
||||
</div>
|
||||
)}
|
||||
<div className="flex flex-row items-center justify-center md:pb-4 mt-4">
|
||||
<p className="text-sm flex justify-center text-gray-400 w-max">
|
||||
Need an Infisical account?
|
||||
</p>
|
||||
<Link href="/signup">
|
||||
<button className="text-primary-700 hover:text-primary duration-200 font-normal text-sm underline-offset-4 ml-1.5">
|
||||
Sign up here.
|
||||
</button>
|
||||
</Link>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useEffect } from "react";
|
||||
import { useEffect } from "react";
|
||||
import Head from "next/head";
|
||||
import { useRouter } from "next/router";
|
||||
const queryString = require("query-string");
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useState } from 'react';
|
||||
import { useState } from 'react';
|
||||
import Image from 'next/image';
|
||||
import { useRouter } from 'next/router';
|
||||
import { faCheck, faX } from '@fortawesome/free-solid-svg-icons';
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { useEffect, useState } from "react";
|
||||
import Head from "next/head";
|
||||
|
||||
import Plan from "~/components/billing/Plan";
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { useEffect, useState } from 'react';
|
||||
import Head from 'next/head';
|
||||
import { useRouter } from 'next/router';
|
||||
import {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { useEffect, useState } from "react";
|
||||
import Head from "next/head";
|
||||
import { faCheck, faX } from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useEffect, useRef, useState } from "react";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import Head from "next/head";
|
||||
import { useRouter } from "next/router";
|
||||
import { faCheck, faPlus } from "@fortawesome/free-solid-svg-icons";
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { useEffect, useState } from 'react';
|
||||
import ReactCodeInput from 'react-code-input';
|
||||
import Head from 'next/head';
|
||||
import Image from 'next/image';
|
||||
@ -260,46 +260,49 @@ export default function SignUp() {
|
||||
|
||||
// Step 1 of the sign up process (enter the email or choose google authentication)
|
||||
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">
|
||||
<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
|
||||
</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>
|
||||
<div className="bg-bunker w-full max-w-md mx-auto h-7/12 py-8 md:px-6 mx-1 rounded-xl drop-shadow-xl">
|
||||
<p className="text-4xl font-semibold flex justify-center text-primary">
|
||||
{'Let\''}s get started
|
||||
</p>
|
||||
<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
|
||||
label="Email"
|
||||
onChangeHandler={setEmail}
|
||||
type="email"
|
||||
value={email}
|
||||
placeholder=""
|
||||
isRequired
|
||||
error={emailError}
|
||||
errorText={emailErrorMessage}
|
||||
autoComplete="username"
|
||||
/>
|
||||
</div>
|
||||
{/* <div className='flex flex-row justify-left mt-4 max-w-md mx-auto'>
|
||||
<Checkbox className="mr-4"/>
|
||||
<p className='text-sm'>I do not want to receive emails about Infisical and its products.</p>
|
||||
</div> */}
|
||||
<div className="flex flex-col items-center justify-center w-5/6 md:w-full md:p-2 max-h-28 max-w-xs md:max-w-md mx-auto mt-4 md:mt-4 text-sm text-center md:text-left">
|
||||
<p className="text-gray-400 mt-2 md:mx-0.5">
|
||||
By creating an account, you agree to our Terms and have read and
|
||||
acknowledged the Privacy Policy.
|
||||
</p>
|
||||
<div className="text-l mt-6 m-2 md:m-8 px-8 py-1 text-lg">
|
||||
<Button text="Get Started" type="submit" onButtonPressed={emailCheck} size="lg" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-col items-center justify-center w-full md:pb-2 max-w-md mx-auto pt-2 mb-48 md:mb-16 mt-2">
|
||||
<Link href="/login">
|
||||
<button className="w-max pb-3 hover:opacity-90 duration-200">
|
||||
<u className="font-normal text-md text-sky-500">
|
||||
<button type="button" className="w-max pb-3 hover:opacity-90 duration-200">
|
||||
<u className="font-normal text-sm text-primary-500">
|
||||
Have an account? Log in
|
||||
</u>
|
||||
</button>
|
||||
</Link>
|
||||
</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">
|
||||
<InputField
|
||||
label="Email"
|
||||
onChangeHandler={setEmail}
|
||||
type="email"
|
||||
value={email}
|
||||
placeholder=""
|
||||
isRequired
|
||||
error={emailError}
|
||||
errorText={emailErrorMessage}
|
||||
autoComplete="username"
|
||||
/>
|
||||
</div>
|
||||
{/* <div className='flex flex-row justify-left mt-4 max-w-md mx-auto'>
|
||||
<Checkbox className="mr-4"/>
|
||||
<p className='text-sm'>I do not want to receive emails about Infisical and its products.</p>
|
||||
</div> */}
|
||||
<div className="flex flex-col items-center justify-center w-5/6 md:w-full md:p-2 max-h-28 max-w-xs md:max-w-md mx-auto mt-4 md:mt-4 text-sm text-center md:text-left">
|
||||
<p className="text-gray-400 mt-2 md:mx-0.5">
|
||||
By creating an account, you agree to our Terms and have read and
|
||||
acknowledged the Privacy Policy.
|
||||
</p>
|
||||
<div className="text-l mt-6 m-2 md:m-8 px-8 py-1 text-lg">
|
||||
<Button loading={isLoading} text="Get Started" onButtonPressed={emailCheck} size="lg" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
);
|
||||
|
||||
// Step 2 of the signup process (enter the email verification code)
|
||||
@ -340,11 +343,11 @@ export default function SignUp() {
|
||||
<Button text="Verify" onButtonPressed={incrementStep} size="lg" />
|
||||
</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-row items-baseline gap-1">
|
||||
<div className="flex flex-row items-baseline gap-1 text-sm">
|
||||
<span className="text-gray-400">
|
||||
Not seeing an email?
|
||||
</span>
|
||||
<u className={`font-normal text-sm ${isResendingVerificationEmail ? 'text-gray-400' : 'text-sky-500 hover:opacity-90 duration-200'}`}>
|
||||
<u className={`font-normal ${isResendingVerificationEmail ? 'text-gray-400' : 'text-primary-500 hover:opacity-90 duration-200'}`}>
|
||||
<button disabled={isLoading} onClick={resendVerificationEmail}>
|
||||
{isResendingVerificationEmail ? 'Resending...' : 'Resend'}
|
||||
</button>
|
||||
@ -512,7 +515,7 @@ export default function SignUp() {
|
||||
It contains your Secret Key which we cannot access or recover for you if
|
||||
you lose it.
|
||||
</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-col items-center justify-center md:px-4 md:py-5 mt-2 px-2 py-3 max-h-24 max-w-max mx-auto text-lg">
|
||||
<Button
|
||||
text="Download PDF"
|
||||
onButtonPressed={async () => {
|
||||
@ -521,11 +524,9 @@ export default function SignUp() {
|
||||
password,
|
||||
personalName: firstName + ' ' + lastName,
|
||||
setBackupKeyError,
|
||||
setBackupKeyIssued,
|
||||
setBackupKeyIssued
|
||||
});
|
||||
const userWorkspaces = await getWorkspaces();
|
||||
const userWorkspace = userWorkspaces[0]._id;
|
||||
router.push('/home/' + userWorkspace);
|
||||
router.push('/dashboard/');
|
||||
}}
|
||||
size="lg"
|
||||
/>
|
||||
@ -571,7 +572,9 @@ export default function SignUp() {
|
||||
/>
|
||||
</div>
|
||||
</Link>
|
||||
{step == 1 ? step1 : step == 2 ? step2 : step == 3 ? step3 : step4}
|
||||
<form onSubmit={(e) => e.preventDefault()}>
|
||||
{step == 1 ? step1 : step == 2 ? step2 : step == 3 ? step3 : step4}
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useState } from 'react';
|
||||
import { useState } from 'react';
|
||||
import Head from 'next/head';
|
||||
import Image from 'next/image';
|
||||
import Link from 'next/link';
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { useEffect, useState } from 'react';
|
||||
import Head from 'next/head';
|
||||
import Image from 'next/image';
|
||||
import { useRouter } from 'next/router';
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useEffect } from "react";
|
||||
import { useEffect } from "react";
|
||||
import Head from "next/head";
|
||||
import { useRouter } from "next/router";
|
||||
const queryString = require("query-string");
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useState } from 'react';
|
||||
import { useState } from 'react';
|
||||
import Head from 'next/head';
|
||||
import Image from 'next/image';
|
||||
import Link from 'next/link';
|
||||
|
Reference in New Issue
Block a user