mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-08 09:27:50 +00:00
Merge remote-tracking branch 'origin' into secret-versioning
This commit is contained in:
@@ -13,7 +13,7 @@ permissions:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
goreleaser:
|
goreleaser:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-20.04
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
@@ -24,6 +24,15 @@ jobs:
|
|||||||
go-version: '>=1.19.3'
|
go-version: '>=1.19.3'
|
||||||
cache: true
|
cache: true
|
||||||
cache-dependency-path: cli/go.sum
|
cache-dependency-path: cli/go.sum
|
||||||
|
- name: libssl1.1 => libssl1.0-dev for OSXCross
|
||||||
|
run: |
|
||||||
|
echo 'deb http://security.ubuntu.com/ubuntu bionic-security main' | sudo tee -a /etc/apt/sources.list
|
||||||
|
sudo apt update && apt-cache policy libssl1.0-dev
|
||||||
|
sudo apt-get install libssl1.0-dev
|
||||||
|
- name: OSXCross for CGO Support
|
||||||
|
run: |
|
||||||
|
mkdir ../../osxcross
|
||||||
|
git clone https://github.com/plentico/osxcross-target.git ../../osxcross/target
|
||||||
- uses: goreleaser/goreleaser-action@v2
|
- uses: goreleaser/goreleaser-action@v2
|
||||||
with:
|
with:
|
||||||
distribution: goreleaser
|
distribution: goreleaser
|
||||||
|
|||||||
+15
-6
@@ -7,12 +7,23 @@
|
|||||||
# # you may remove this if you don't need go generate
|
# # you may remove this if you don't need go generate
|
||||||
# - cd cli && go generate ./...
|
# - cd cli && go generate ./...
|
||||||
builds:
|
builds:
|
||||||
- env:
|
- id: darwin-build
|
||||||
- CGO_ENABLED=0
|
|
||||||
binary: infisical
|
binary: infisical
|
||||||
id: infisical
|
env:
|
||||||
|
- CGO_ENABLED=1
|
||||||
|
- CC=/home/runner/work/osxcross/target/bin/o64-clang
|
||||||
|
- CXX=/home/runner/work/osxcross/target/bin/o64-clang++
|
||||||
goos:
|
goos:
|
||||||
- darwin
|
- darwin
|
||||||
|
ignore:
|
||||||
|
- goos: darwin
|
||||||
|
goarch: "386"
|
||||||
|
dir: ./cli
|
||||||
|
- id: all-other-builds
|
||||||
|
env:
|
||||||
|
- CGO_ENABLED=0
|
||||||
|
binary: infisical
|
||||||
|
goos:
|
||||||
- freebsd
|
- freebsd
|
||||||
- linux
|
- linux
|
||||||
- netbsd
|
- netbsd
|
||||||
@@ -27,8 +38,6 @@ builds:
|
|||||||
- 6
|
- 6
|
||||||
- 7
|
- 7
|
||||||
ignore:
|
ignore:
|
||||||
- goos: darwin
|
|
||||||
goarch: "386"
|
|
||||||
- goos: windows
|
- goos: windows
|
||||||
goarch: "386"
|
goarch: "386"
|
||||||
- goos: freebsd
|
- goos: freebsd
|
||||||
@@ -71,7 +80,7 @@ nfpms:
|
|||||||
- id: infisical
|
- id: infisical
|
||||||
package_name: infisical
|
package_name: infisical
|
||||||
builds:
|
builds:
|
||||||
- infisical
|
- all-other-builds
|
||||||
vendor: Infisical, Inc
|
vendor: Infisical, Inc
|
||||||
homepage: https://infisical.com/
|
homepage: https://infisical.com/
|
||||||
maintainer: Infisical, Inc
|
maintainer: Infisical, Inc
|
||||||
|
|||||||
@@ -91,7 +91,9 @@ var loginCmd = &cobra.Command{
|
|||||||
|
|
||||||
err = util.StoreUserCredsInKeyRing(userCredentialsToBeStored)
|
err = util.StoreUserCredsInKeyRing(userCredentialsToBeStored)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorln("Unable to store your credentials in system key ring")
|
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)
|
log.Debugln(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ var rootCmd = &cobra.Command{
|
|||||||
Short: "Infisical CLI is used to inject environment variables into any process",
|
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.`,
|
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},
|
CompletionOptions: cobra.CompletionOptions{DisableDefaultCmd: true},
|
||||||
Version: "0.1.12",
|
Version: "0.1.14",
|
||||||
}
|
}
|
||||||
|
|
||||||
// Execute adds all child commands to the root command and sets flags appropriately.
|
// Execute adds all child commands to the root command and sets flags appropriately.
|
||||||
@@ -31,8 +31,6 @@ func init() {
|
|||||||
rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
|
rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
|
||||||
rootCmd.PersistentFlags().BoolVarP(&debugLogging, "debug", "d", false, "Enable verbose logging")
|
rootCmd.PersistentFlags().BoolVarP(&debugLogging, "debug", "d", false, "Enable verbose logging")
|
||||||
rootCmd.PersistentFlags().StringVar(&util.INFISICAL_URL, "domain", "https://app.infisical.com/api", "Point the CLI to your own backend")
|
rootCmd.PersistentFlags().StringVar(&util.INFISICAL_URL, "domain", "https://app.infisical.com/api", "Point the CLI to your own backend")
|
||||||
|
// rootCmd.PersistentPreRun = func(cmd *cobra.Command, args []string) {
|
||||||
rootCmd.PersistentPreRun = func(cmd *cobra.Command, args []string) {
|
// }
|
||||||
util.InitKeyRingInstance()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ var vaultSetCmd = &cobra.Command{
|
|||||||
|
|
||||||
err = util.WriteConfigFile(&configFile)
|
err = util.WriteConfigFile(&configFile)
|
||||||
if err != nil {
|
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
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ func GetHomeDir() (string, error) {
|
|||||||
return directory, err
|
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 {
|
func WriteToFile(fileName string, dataToWrite []byte, filePerm os.FileMode) error {
|
||||||
err := os.WriteFile(fileName, dataToWrite, filePerm)
|
err := os.WriteFile(fileName, dataToWrite, filePerm)
|
||||||
if err != nil {
|
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
|
// Write a ConfigFile to disk. Raise error if unable to save the model to ask
|
||||||
func WriteConfigFile(configFile *models.ConfigFile) error {
|
func WriteConfigFile(configFile *models.ConfigFile) error {
|
||||||
fullConfigFilePath, _, err := GetFullConfigFilePath()
|
fullConfigFilePath, fullConfigFileDirPath, err := GetFullConfigFilePath()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("writeConfigFile: unable to write config file because an error occurred when getting config file path [err=%s]", err)
|
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)
|
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
|
// 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 {
|
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)
|
return fmt.Errorf("writeConfigFile: unable to write config file because an error occurred when write the config to file [err=%s]", err)
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,13 @@ func StoreUserCredsInKeyRing(userCred *models.UserCredentials) error {
|
|||||||
return fmt.Errorf("StoreUserCredsInKeyRing: something went wrong when marshalling user creds [err=%s]", err)
|
return fmt.Errorf("StoreUserCredsInKeyRing: something went wrong when marshalling user creds [err=%s]", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = keyringInstance.Set(keyring.Item{
|
// Get keyring
|
||||||
|
configuredKeyring, err := GetKeyRing()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("StoreUserCredsInKeyRing: unable to get keyring instance with [err=%s]", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = configuredKeyring.Set(keyring.Item{
|
||||||
Key: userCred.Email,
|
Key: userCred.Email,
|
||||||
Data: []byte(string(userCredMarshalled)),
|
Data: []byte(string(userCredMarshalled)),
|
||||||
})
|
})
|
||||||
@@ -32,20 +38,26 @@ func StoreUserCredsInKeyRing(userCred *models.UserCredentials) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func GetUserCredsFromKeyRing(userEmail string) (credentials models.UserCredentials, err error) {
|
func GetUserCredsFromKeyRing(userEmail string) (credentials models.UserCredentials, err error) {
|
||||||
credentialsValue, err := keyringInstance.Get(userEmail)
|
// Get keyring
|
||||||
|
configuredKeyring, err := GetKeyRing()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return models.UserCredentials{}, fmt.Errorf("Unable to get key from Keyring. could not find login credentials in your Keyring. This is common if you have switched vault backend recently. If so, please login in again and retry:", err)
|
return models.UserCredentials{}, fmt.Errorf("GetUserCredsFromKeyRing: unable to get keyring instance with [err=%s]", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
credentialsValue, err := configuredKeyring.Get(userEmail)
|
||||||
|
if err != nil {
|
||||||
|
return models.UserCredentials{}, fmt.Errorf("GetUserCredsFromKeyRing: unable to get key from Keyring. could not find login credentials in your Keyring. This is common if you have switched vault backend recently. If so, please login in again and retry [err=%s]", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var userCredentials models.UserCredentials
|
var userCredentials models.UserCredentials
|
||||||
|
|
||||||
err = json.Unmarshal([]byte(credentialsValue.Data), &userCredentials)
|
err = json.Unmarshal([]byte(credentialsValue.Data), &userCredentials)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return models.UserCredentials{}, fmt.Errorf("Something went wrong when unmarshalling user creds:", err)
|
return models.UserCredentials{}, fmt.Errorf("getUserCredsFromKeyRing: Something went wrong when unmarshalling user creds [err=%s]", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return models.UserCredentials{}, fmt.Errorf("Unable to store user credentials", err)
|
return models.UserCredentials{}, fmt.Errorf("GetUserCredsFromKeyRing: Unable to store user credentials [err=%s]", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return userCredentials, err
|
return userCredentials, err
|
||||||
@@ -82,7 +94,7 @@ func IsUserLoggedIn() (hasUserLoggedIn bool, theUsersEmail string, err error) {
|
|||||||
|
|
||||||
if response.StatusCode() > 299 {
|
if response.StatusCode() > 299 {
|
||||||
log.Infoln("Login expired, please login again.")
|
log.Infoln("Login expired, please login again.")
|
||||||
return false, "", fmt.Errorf("Login expired, please login again.")
|
return false, "", fmt.Errorf("GetUserCredsFromKeyRing: Login expired, please login again.")
|
||||||
}
|
}
|
||||||
|
|
||||||
return true, configFile.LoggedInUserEmail, nil
|
return true, configFile.LoggedInUserEmail, nil
|
||||||
|
|||||||
@@ -5,14 +5,9 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/99designs/keyring"
|
"github.com/99designs/keyring"
|
||||||
log "github.com/sirupsen/logrus"
|
|
||||||
"golang.org/x/term"
|
"golang.org/x/term"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Keyring instance
|
|
||||||
var keyringInstance keyring.Keyring
|
|
||||||
var keyringInstanceConfig keyring.Config
|
|
||||||
|
|
||||||
func GetCurrentVaultBackend() (keyring.BackendType, error) {
|
func GetCurrentVaultBackend() (keyring.BackendType, error) {
|
||||||
configFile, err := GetConfigFile()
|
configFile, err := GetConfigFile()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -20,21 +15,19 @@ func GetCurrentVaultBackend() (keyring.BackendType, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if configFile.VaultBackendType == "" {
|
if configFile.VaultBackendType == "" {
|
||||||
if keyring.AvailableBackends()[0] == keyring.FileBackend {
|
|
||||||
}
|
|
||||||
return keyring.AvailableBackends()[0], nil
|
return keyring.AvailableBackends()[0], nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return configFile.VaultBackendType, nil
|
return configFile.VaultBackendType, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func InitKeyRingInstance() {
|
func GetKeyRing() (keyring.Keyring, error) {
|
||||||
currentVaultBackend, err := GetCurrentVaultBackend()
|
currentVaultBackend, err := GetCurrentVaultBackend()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Infof("InitKeyRingInstance: unable to get the current vault backend, [err=%s]", err)
|
return nil, fmt.Errorf("GetKeyRing: unable to get the current vault backend, [err=%s]", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
keyringInstanceConfig = keyring.Config{
|
keyringInstanceConfig := keyring.Config{
|
||||||
FilePasswordFunc: fileKeyringPassphrasePrompt,
|
FilePasswordFunc: fileKeyringPassphrasePrompt,
|
||||||
ServiceName: SERVICE_NAME,
|
ServiceName: SERVICE_NAME,
|
||||||
LibSecretCollectionName: SERVICE_NAME,
|
LibSecretCollectionName: SERVICE_NAME,
|
||||||
@@ -51,10 +44,12 @@ func InitKeyRingInstance() {
|
|||||||
keyringInstanceConfig.AllowedBackends = []keyring.BackendType{keyring.BackendType(currentVaultBackend)}
|
keyringInstanceConfig.AllowedBackends = []keyring.BackendType{keyring.BackendType(currentVaultBackend)}
|
||||||
}
|
}
|
||||||
|
|
||||||
keyringInstance, err = keyring.Open(keyringInstanceConfig)
|
keyringInstance, err := keyring.Open(keyringInstanceConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("InitKeyRingInstance: Unable to create instance of Keyring because of [err=%s]", err)
|
return nil, fmt.Errorf("GetKeyRing: Unable to create instance of Keyring because of [err=%s]", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return keyringInstance, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func fileKeyringPassphrasePrompt(prompt string) (string, error) {
|
func fileKeyringPassphrasePrompt(prompt string) (string, error) {
|
||||||
|
|||||||
@@ -30,12 +30,10 @@ title: "infisical vault"
|
|||||||
|
|
||||||
## Description
|
## Description
|
||||||
|
|
||||||
To ensure secure storage of your login credentials when using the CLI, Infisical saves them to a password manager if one is detected.
|
To ensure secure storage of your login credentials when using the CLI, Infisical stores login credentials securely in a system vault or encrypted text file with a passphrase known only by the user.
|
||||||
If a password manager is not available, your credentials are stored in an encrypted text file.
|
|
||||||
|
|
||||||
|
<Accordion title="Supported vaults">
|
||||||
<Accordion title="Supported password managers" defaultOpen="true">
|
By default, the most appropriate vault is chosen to store your login credentials.
|
||||||
By default, the most appropriate password manager is chosen to store your login credentials.
|
|
||||||
For example, if you are on macOS, KeyChain will be automatically selected.
|
For example, if you are on macOS, KeyChain will be automatically selected.
|
||||||
|
|
||||||
- [macOS Keychain](https://support.apple.com/en-au/guide/keychain-access/welcome/mac)
|
- [macOS Keychain](https://support.apple.com/en-au/guide/keychain-access/welcome/mac)
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
---
|
||||||
|
title: "FAQ"
|
||||||
|
---
|
||||||
|
|
||||||
|
Frequently asked questions about the CLI can be found on this page.
|
||||||
|
If you can't find the answer you're looking for, please create an issue on our GitHub repository or join our Slack channel for additional support.
|
||||||
|
|
||||||
|
<Accordion title="I'm getting a Keyring related error message when trying to login" defaultOpen="true">
|
||||||
|
By default, the CLI will choose the most suitable store available on your system.
|
||||||
|
If you experience issues with the default store, you can switch to a different one.
|
||||||
|
If none of the available stores work for you, you can try using the `file` store type by running `infisical vault set file`, which should work in most cases.
|
||||||
|
If you are still experiencing trouble, please seek support.
|
||||||
|
|
||||||
|
[Learn more about vault command](./commands/vault)
|
||||||
|
</Accordion>
|
||||||
+2
-1
@@ -97,7 +97,8 @@
|
|||||||
"cli/commands/export",
|
"cli/commands/export",
|
||||||
"cli/commands/vault"
|
"cli/commands/vault"
|
||||||
]
|
]
|
||||||
}
|
},
|
||||||
|
"cli/faq"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -96,6 +96,7 @@ const InputField = (
|
|||||||
/>
|
/>
|
||||||
{props.label?.includes('Password') && (
|
{props.label?.includes('Password') && (
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setPasswordVisible(!passwordVisible);
|
setPasswordVisible(!passwordVisible);
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import React from "react";
|
import React, { ButtonHTMLAttributes } from "react";
|
||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
import { IconProp } from "@fortawesome/fontawesome-svg-core";
|
import { IconProp } from "@fortawesome/fontawesome-svg-core";
|
||||||
import {
|
import {
|
||||||
@@ -18,6 +18,7 @@ type ButtonProps = {
|
|||||||
active?: boolean;
|
active?: boolean;
|
||||||
iconDisabled?: string;
|
iconDisabled?: string;
|
||||||
textDisabled?: string;
|
textDisabled?: string;
|
||||||
|
type?: ButtonHTMLAttributes<any>['type'];
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -91,6 +92,7 @@ export default function Button(props: ButtonProps): JSX.Element {
|
|||||||
const button = (
|
const button = (
|
||||||
<button
|
<button
|
||||||
disabled={!activityStatus}
|
disabled={!activityStatus}
|
||||||
|
type={props.type}
|
||||||
onClick={props.onButtonPressed}
|
onClick={props.onButtonPressed}
|
||||||
className={styleButton}
|
className={styleButton}
|
||||||
>
|
>
|
||||||
|
|||||||
+67
-58
@@ -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.
|
* This function check if the user entered the correct credentials and should be allowed to log in.
|
||||||
*/
|
*/
|
||||||
const loginCheck = async () => {
|
const loginCheck = async () => {
|
||||||
|
if (!email || !password) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
await attemptLogin(
|
await attemptLogin(
|
||||||
email,
|
email,
|
||||||
@@ -45,7 +49,7 @@ export default function Login() {
|
|||||||
setErrorLogin,
|
setErrorLogin,
|
||||||
router,
|
router,
|
||||||
false,
|
false,
|
||||||
true
|
true,
|
||||||
).then(() => {
|
).then(() => {
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
@@ -75,68 +79,73 @@ export default function Login() {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</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">
|
<form
|
||||||
<p className="text-3xl w-max mx-auto flex justify-center font-semibold text-bunker-100 mb-6">
|
onChange={() => setErrorLogin(false)} onSubmit={(e) => e.preventDefault()}
|
||||||
Log in to your account
|
>
|
||||||
</p>
|
<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="flex items-center justify-center w-full md:p-2 rounded-lg mt-4 md:mt-0 max-h-24 md:max-h-28">
|
<p className="text-3xl w-max mx-auto flex justify-center font-semibold text-bunker-100 mb-6">
|
||||||
<InputField
|
Log in to your account
|
||||||
label="Email"
|
</p>
|
||||||
onChangeHandler={setEmail}
|
<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">
|
||||||
type="email"
|
<InputField
|
||||||
value={email}
|
label="Email"
|
||||||
placeholder=""
|
onChangeHandler={setEmail}
|
||||||
isRequired
|
type="email"
|
||||||
autoComplete="username"
|
value={email}
|
||||||
/>
|
placeholder=""
|
||||||
</div>
|
isRequired
|
||||||
<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">
|
autoComplete="username"
|
||||||
<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"
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</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">
|
||||||
{/* <div className="flex items-center justify-center w-full md:p-2 rounded-lg 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>
|
<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> */}
|
||||||
</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>
|
||||||
)}
|
{false && (
|
||||||
<div className="flex flex-row items-center justify-center md:pb-4 mt-4">
|
<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">
|
||||||
<p className="text-sm flex justify-center text-gray-400 w-max">
|
<FontAwesomeIcon icon={faWarning} className="ml-2 mr-6 text-6xl" />
|
||||||
Need an Infisical account?
|
We are experiencing minor technical difficulties. We are working on
|
||||||
</p>
|
solving it right now. Please come back in a few minutes.
|
||||||
<Link href="/signup">
|
</div>
|
||||||
<button className="text-primary-700 hover:text-primary duration-200 font-normal text-sm underline-offset-4 ml-1.5">
|
)}
|
||||||
Sign up here.
|
<div className="flex flex-row items-center justify-center md:pb-4 mt-4">
|
||||||
</button>
|
<p className="text-sm flex justify-center text-gray-400 w-max">
|
||||||
</Link>
|
Need an Infisical account?
|
||||||
</div>
|
</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>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
+17
-33
@@ -266,7 +266,7 @@ export default function SignUp() {
|
|||||||
</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 type="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
|
Have an account? Log in
|
||||||
</u>
|
</u>
|
||||||
@@ -286,7 +286,7 @@ export default function SignUp() {
|
|||||||
autoComplete="username"
|
autoComplete="username"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{/* <div className='flex flex-row justify-left mt-4 max-w-md mx-auto'>
|
{/* <div className='flex flex-row justify-left mt-4 max-w-md mx-auto'>
|
||||||
<Checkbox className="mr-4"/>
|
<Checkbox className="mr-4"/>
|
||||||
<p className='text-sm'>I do not want to receive emails about Infisical and its products.</p>
|
<p className='text-sm'>I do not want to receive emails about Infisical and its products.</p>
|
||||||
</div> */}
|
</div> */}
|
||||||
@@ -296,7 +296,7 @@ export default function SignUp() {
|
|||||||
acknowledged the Privacy Policy.
|
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 loading={isLoading} text="Get Started" onButtonPressed={emailCheck} size="lg" />
|
<Button text="Get Started" type="submit" onButtonPressed={emailCheck} size="lg" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -512,35 +512,17 @@ export default function SignUp() {
|
|||||||
It contains your Secret Key which we cannot access or recover for you if
|
It contains your Secret Key which we cannot access or recover for you if
|
||||||
you lose it.
|
you lose it.
|
||||||
</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
|
||||||
<Button
|
className="text-l mt-4 text-lg text-gray-400 hover:text-gray-300 duration-200 bg-white/5 px-8 hover:bg-white/10 py-3 rounded-md cursor-pointer"
|
||||||
text="Download PDF"
|
onClick={() => {
|
||||||
onButtonPressed={async () => {
|
if (localStorage.getItem("projectData.id")) {
|
||||||
await issueBackupKey({
|
router.push("/dashboard/" + localStorage.getItem("projectData.id"));
|
||||||
email,
|
} else {
|
||||||
password,
|
router.push("/noprojects")
|
||||||
personalName: firstName + ' ' + lastName,
|
}
|
||||||
setBackupKeyError,
|
}}
|
||||||
setBackupKeyIssued,
|
>
|
||||||
});
|
Later
|
||||||
const userWorkspaces = await getWorkspaces();
|
|
||||||
const userWorkspace = userWorkspaces[0]._id;
|
|
||||||
router.push('/home/' + userWorkspace);
|
|
||||||
}}
|
|
||||||
size="lg"
|
|
||||||
/>
|
|
||||||
{/* <div
|
|
||||||
className="text-l mt-4 text-lg text-gray-400 hover:text-gray-300 duration-200 bg-white/5 px-8 hover:bg-white/10 py-3 rounded-md cursor-pointer"
|
|
||||||
onClick={() => {
|
|
||||||
if (localStorage.getItem("projectData.id")) {
|
|
||||||
router.push("/dashboard/" + localStorage.getItem("projectData.id"));
|
|
||||||
} else {
|
|
||||||
router.push("/noprojects")
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Later
|
|
||||||
</div> */}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
@@ -571,7 +553,9 @@ export default function SignUp() {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</Link>
|
</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>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user