mirror of
https://github.com/steveiliop56/tinyauth.git
synced 2025-10-28 12:45:47 +00:00
Compare commits
7 Commits
v2.0.0-alp
...
v2.0.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2385599c80 | ||
|
|
6f184856f1 | ||
|
|
e2e3b3bdc6 | ||
|
|
3efcb26db1 | ||
|
|
c54267f50d | ||
|
|
4de12ce5c1 | ||
|
|
0cf0aafc14 |
3
.gitignore
vendored
3
.gitignore
vendored
@@ -11,4 +11,5 @@ docker-compose.test.yml
|
||||
users.txt
|
||||
|
||||
# secret test file
|
||||
secret.txt
|
||||
secret.txt
|
||||
secret_oauth.txt
|
||||
35
cmd/root.go
35
cmd/root.go
@@ -1,9 +1,12 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
cmd "tinyauth/cmd/user"
|
||||
"tinyauth/internal/api"
|
||||
"tinyauth/internal/assets"
|
||||
"tinyauth/internal/auth"
|
||||
"tinyauth/internal/hooks"
|
||||
"tinyauth/internal/providers"
|
||||
@@ -22,21 +25,28 @@ var rootCmd = &cobra.Command{
|
||||
Short: "The simplest way to protect your apps with a login screen.",
|
||||
Long: `Tinyauth is a simple authentication middleware that adds simple username/password login or OAuth with Google, Github and any generic OAuth provider to all of your docker apps.`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
// Logger
|
||||
log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr, TimeFormat: time.RFC3339}).With().Timestamp().Logger().Level(zerolog.FatalLevel)
|
||||
|
||||
// Get config
|
||||
log.Info().Msg("Parsing config")
|
||||
var config types.Config
|
||||
parseErr := viper.Unmarshal(&config)
|
||||
HandleError(parseErr, "Failed to parse config")
|
||||
|
||||
// Secrets
|
||||
config.Secret = utils.GetSecret(config.Secret, config.SecretFile)
|
||||
config.GithubClientSecret = utils.GetSecret(config.GithubClientSecret, config.GithubClientSecretFile)
|
||||
config.GoogleClientSecret = utils.GetSecret(config.GoogleClientSecret, config.GoogleClientSecretFile)
|
||||
config.GenericClientSecret = utils.GetSecret(config.GenericClientSecret, config.GenericClientSecretFile)
|
||||
|
||||
// Validate config
|
||||
log.Info().Msg("Validating config")
|
||||
validator := validator.New()
|
||||
validateErr := validator.Struct(config)
|
||||
HandleError(validateErr, "Invalid config")
|
||||
HandleError(validateErr, "Failed to validate config")
|
||||
|
||||
// Set log level
|
||||
log.Info().Int8("log_level", config.LogLevel).Msg("Setting log level")
|
||||
log.Logger = log.Logger.Level(zerolog.Level(config.LogLevel))
|
||||
// Logger
|
||||
log.Logger = log.Level(zerolog.Level(config.LogLevel))
|
||||
log.Info().Str("version", assets.Version).Msg("Starting tinyauth")
|
||||
|
||||
// Users
|
||||
log.Info().Msg("Parsing users")
|
||||
@@ -46,17 +56,9 @@ var rootCmd = &cobra.Command{
|
||||
log.Fatal().Err(usersErr).Msg("Failed to parse users")
|
||||
}
|
||||
|
||||
// Secrets
|
||||
log.Info().Msg("Parsing secrets")
|
||||
|
||||
config.Secret = utils.GetSecret(config.Secret, config.SecretFile)
|
||||
config.GithubClientSecret = utils.GetSecret(config.GithubClientSecret, config.GithubClientSecretFile)
|
||||
config.GoogleClientSecret = utils.GetSecret(config.GoogleClientSecret, config.GoogleClientSecretFile)
|
||||
config.GenericClientSecret = utils.GetSecret(config.GenericClientSecret, config.GenericClientSecretFile)
|
||||
|
||||
// Create oauth whitelist
|
||||
oauthWhitelist := strings.Split(config.OAuthWhitelist, ",")
|
||||
log.Debug().Strs("oauth_whitelist", oauthWhitelist).Msg("Parsed OAuth whitelist")
|
||||
log.Debug().Msg("Parsed OAuth whitelist")
|
||||
|
||||
// Create OAuth config
|
||||
oauthConfig := types.OAuthConfig{
|
||||
@@ -72,7 +74,8 @@ var rootCmd = &cobra.Command{
|
||||
GenericUserURL: config.GenericUserURL,
|
||||
AppURL: config.AppURL,
|
||||
}
|
||||
log.Debug().Interface("oauth_config", oauthConfig).Msg("Parsed OAuth config")
|
||||
|
||||
log.Debug().Msg("Parsed OAuth config")
|
||||
|
||||
// Create auth service
|
||||
auth := auth.NewAuth(users, oauthWhitelist)
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/charmbracelet/huh"
|
||||
"github.com/rs/zerolog"
|
||||
"github.com/rs/zerolog/log"
|
||||
"github.com/spf13/cobra"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
@@ -21,6 +22,8 @@ var CreateCmd = &cobra.Command{
|
||||
Short: "Create a user",
|
||||
Long: `Create a user either interactively or by passing flags.`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
log.Logger = log.Level(zerolog.InfoLevel)
|
||||
|
||||
if interactive {
|
||||
form := huh.NewForm(
|
||||
huh.NewGroup(
|
||||
|
||||
@@ -8,12 +8,17 @@ import (
|
||||
)
|
||||
|
||||
func UserCmd() *cobra.Command {
|
||||
// Create the user command
|
||||
userCmd := &cobra.Command{
|
||||
Use: "user",
|
||||
Use: "user",
|
||||
Short: "User utilities",
|
||||
Long: `Utilities for creating and verifying tinyauth compatible users.`,
|
||||
Long: `Utilities for creating and verifying tinyauth compatible users.`,
|
||||
}
|
||||
|
||||
// Add subcommands
|
||||
userCmd.AddCommand(create.CreateCmd)
|
||||
userCmd.AddCommand(verify.VerifyCmd)
|
||||
|
||||
// Return the user command
|
||||
return userCmd
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/charmbracelet/huh"
|
||||
"github.com/rs/zerolog"
|
||||
"github.com/rs/zerolog/log"
|
||||
"github.com/spf13/cobra"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
@@ -21,6 +22,8 @@ var VerifyCmd = &cobra.Command{
|
||||
Short: "Verify a user is set up correctly",
|
||||
Long: `Verify a user is set up correctly meaning that it has a correct username and password.`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
log.Logger = log.Level(zerolog.InfoLevel)
|
||||
|
||||
if interactive {
|
||||
form := huh.NewForm(
|
||||
huh.NewGroup(
|
||||
|
||||
@@ -114,7 +114,7 @@ func (api *API) SetupRoutes() {
|
||||
RedirectURI: fmt.Sprintf("%s://%s%s", proto, host, uri),
|
||||
})
|
||||
|
||||
log.Debug().Interface("queries", queries).Msg("Redirecting to login")
|
||||
log.Debug().Interface("redirect_uri", fmt.Sprintf("%s://%s%s", proto, host, uri)).Msg("Redirecting to login")
|
||||
|
||||
if queryErr != nil {
|
||||
log.Error().Err(queryErr).Msg("Failed to build query")
|
||||
@@ -142,7 +142,7 @@ func (api *API) SetupRoutes() {
|
||||
return
|
||||
}
|
||||
|
||||
log.Debug().Interface("login", login).Msg("Got login request")
|
||||
log.Debug().Msg("Got login request")
|
||||
|
||||
user := api.Auth.GetUser(login.Username)
|
||||
|
||||
@@ -250,7 +250,7 @@ func (api *API) SetupRoutes() {
|
||||
return
|
||||
}
|
||||
|
||||
log.Debug().Interface("request", request).Msg("Got OAuth request")
|
||||
log.Debug().Msg("Got OAuth request")
|
||||
|
||||
provider := api.Providers.GetProvider(request.Provider)
|
||||
|
||||
@@ -266,7 +266,7 @@ func (api *API) SetupRoutes() {
|
||||
|
||||
authURL := provider.GetAuthURL()
|
||||
|
||||
log.Debug().Str("authURL", authURL).Msg("Got auth URL")
|
||||
log.Debug().Msg("Got auth URL")
|
||||
|
||||
redirectURI := c.Query("redirect_uri")
|
||||
|
||||
@@ -291,7 +291,7 @@ func (api *API) SetupRoutes() {
|
||||
return
|
||||
}
|
||||
|
||||
log.Debug().Interface("providerName", providerName).Msg("Got provider name")
|
||||
log.Debug().Interface("provider", providerName.Provider).Msg("Got provider name")
|
||||
|
||||
code := c.Query("code")
|
||||
|
||||
@@ -301,7 +301,7 @@ func (api *API) SetupRoutes() {
|
||||
return
|
||||
}
|
||||
|
||||
log.Debug().Str("code", code).Msg("Got code")
|
||||
log.Debug().Msg("Got code")
|
||||
|
||||
provider := api.Providers.GetProvider(providerName.Provider)
|
||||
|
||||
@@ -312,9 +312,9 @@ func (api *API) SetupRoutes() {
|
||||
return
|
||||
}
|
||||
|
||||
token, tokenErr := provider.ExchangeToken(code)
|
||||
_, tokenErr := provider.ExchangeToken(code)
|
||||
|
||||
log.Debug().Str("token", token).Msg("Got token")
|
||||
log.Debug().Msg("Got token")
|
||||
|
||||
if handleApiError(c, "Failed to exchange token", tokenErr) {
|
||||
return
|
||||
@@ -363,7 +363,7 @@ func (api *API) SetupRoutes() {
|
||||
RedirectURI: redirectURI,
|
||||
})
|
||||
|
||||
log.Debug().Interface("redirectQuery", redirectQuery).Msg("Got redirect query")
|
||||
log.Debug().Msg("Got redirect query")
|
||||
|
||||
if handleApiError(c, "Failed to build query", redirectQueryErr) {
|
||||
return
|
||||
|
||||
@@ -1 +1 @@
|
||||
v2.0.0
|
||||
v2.0.2
|
||||
@@ -50,7 +50,7 @@ func (auth *Auth) EmailWhitelisted(emailSrc string) bool {
|
||||
func (auth *Auth) CreateSessionCookie(c *gin.Context, data *types.SessionCookie) {
|
||||
log.Debug().Msg("Creating session cookie")
|
||||
sessions := sessions.Default(c)
|
||||
log.Debug().Interface("data", data).Msg("Setting session cookie")
|
||||
log.Debug().Msg("Setting session cookie")
|
||||
sessions.Set("username", data.Username)
|
||||
sessions.Set("provider", data.Provider)
|
||||
sessions.Save()
|
||||
@@ -70,13 +70,10 @@ func (auth *Auth) GetSessionCookie(c *gin.Context) (types.SessionCookie, error)
|
||||
cookieUsername := sessions.Get("username")
|
||||
cookieProvider := sessions.Get("provider")
|
||||
|
||||
log.Debug().Interface("cookieUsername", cookieUsername).Msg("Got username")
|
||||
log.Debug().Interface("cookieProvider", cookieProvider).Msg("Got provider")
|
||||
|
||||
username, usernameOk := cookieUsername.(string)
|
||||
provider, providerOk := cookieProvider.(string)
|
||||
|
||||
log.Debug().Str("username", username).Bool("usernameOk", usernameOk).Str("provider", provider).Bool("providerOk", providerOk).Msg("Parsed cookie")
|
||||
log.Debug().Str("username", username).Str("provider", provider).Msg("Parsed cookie")
|
||||
|
||||
if !usernameOk || !providerOk {
|
||||
log.Warn().Msg("Session cookie invalid")
|
||||
|
||||
@@ -34,8 +34,6 @@ func (hooks *Hooks) UseUserContext(c *gin.Context) types.UserContext {
|
||||
}
|
||||
}
|
||||
|
||||
log.Debug().Interface("cookie", cookie).Msg("Got session cookie")
|
||||
|
||||
if cookie.Provider == "username" {
|
||||
log.Debug().Msg("Provider is username")
|
||||
if hooks.Auth.GetUser(cookie.Username) != nil {
|
||||
@@ -55,7 +53,7 @@ func (hooks *Hooks) UseUserContext(c *gin.Context) types.UserContext {
|
||||
if provider != nil {
|
||||
log.Debug().Msg("Provider exists")
|
||||
if !hooks.Auth.EmailWhitelisted(cookie.Username) {
|
||||
log.Error().Msgf("Email %s not whitelisted", cookie.Username)
|
||||
log.Error().Str("email", cookie.Username).Msg("Email is not whitelisted")
|
||||
hooks.Auth.DeleteSessionCookie(c)
|
||||
return types.UserContext{
|
||||
Username: "",
|
||||
@@ -73,7 +71,6 @@ func (hooks *Hooks) UseUserContext(c *gin.Context) types.UserContext {
|
||||
}
|
||||
}
|
||||
|
||||
log.Error().Msg("Provider does not exist")
|
||||
return types.UserContext{
|
||||
Username: "",
|
||||
IsLoggedIn: false,
|
||||
|
||||
@@ -37,7 +37,7 @@ func GetGenericEmail(client *http.Client, url string) (string, error) {
|
||||
return "", jsonErr
|
||||
}
|
||||
|
||||
log.Debug().Interface("user", user).Msg("Parsed user from generic provider")
|
||||
log.Debug().Msg("Parsed user from generic provider")
|
||||
|
||||
return user.Email, nil
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ func GetGithubEmail(client *http.Client) (string, error) {
|
||||
return "", jsonErr
|
||||
}
|
||||
|
||||
log.Debug().Interface("emails", emails).Msg("Parsed emails from github")
|
||||
log.Debug().Msg("Parsed emails from github")
|
||||
|
||||
for _, email := range emails {
|
||||
if email.Primary {
|
||||
|
||||
@@ -41,7 +41,7 @@ func GetGoogleEmail(client *http.Client) (string, error) {
|
||||
return "", jsonErr
|
||||
}
|
||||
|
||||
log.Debug().Interface("user", user).Msg("Parsed user from google")
|
||||
log.Debug().Msg("Parsed user from google")
|
||||
|
||||
return user.Email, nil
|
||||
}
|
||||
|
||||
@@ -19,8 +19,8 @@ type User struct {
|
||||
type Users []User
|
||||
|
||||
type Config struct {
|
||||
Port int `validate:"number" mapstructure:"port"`
|
||||
Address string `mapstructure:"address, ip4_addr"`
|
||||
Port int `mapstructure:"port" validate:"required"`
|
||||
Address string `validate:"required,ip4_addr" mapstructure:"address"`
|
||||
Secret string `validate:"required,len=32" mapstructure:"secret"`
|
||||
SecretFile string `mapstructure:"secret-file"`
|
||||
AppURL string `validate:"required,url" mapstructure:"app-url"`
|
||||
@@ -43,7 +43,7 @@ type Config struct {
|
||||
DisableContinue bool `mapstructure:"disable-continue"`
|
||||
OAuthWhitelist string `mapstructure:"oauth-whitelist"`
|
||||
CookieExpiry int `mapstructure:"cookie-expiry"`
|
||||
LogLevel int8 `mapstructure:"log-level"`
|
||||
LogLevel int8 `mapstructure:"log-level" validate:"min=-1,max=5"`
|
||||
}
|
||||
|
||||
type UserContext struct {
|
||||
|
||||
@@ -15,15 +15,12 @@ func ParseUsers(users string) (types.Users, error) {
|
||||
var usersParsed types.Users
|
||||
userList := strings.Split(users, ",")
|
||||
|
||||
log.Debug().Strs("users", userList).Msg("Splitted users")
|
||||
|
||||
if len(userList) == 0 {
|
||||
return types.Users{}, errors.New("invalid user format")
|
||||
}
|
||||
|
||||
for _, user := range userList {
|
||||
userSplit := strings.Split(user, ":")
|
||||
log.Debug().Strs("user", userSplit).Msg("Splitting user")
|
||||
if len(userSplit) != 2 {
|
||||
return types.Users{}, errors.New("invalid user format")
|
||||
}
|
||||
@@ -33,7 +30,7 @@ func ParseUsers(users string) (types.Users, error) {
|
||||
})
|
||||
}
|
||||
|
||||
log.Debug().Interface("users", usersParsed).Msg("Parsed users")
|
||||
log.Debug().Msg("Parsed users")
|
||||
|
||||
return usersParsed, nil
|
||||
}
|
||||
@@ -45,7 +42,7 @@ func GetRootURL(urlSrc string) (string, error) {
|
||||
return "", parseErr
|
||||
}
|
||||
|
||||
urlSplitted := strings.Split(urlParsed.Host, ".")
|
||||
urlSplitted := strings.Split(urlParsed.Hostname(), ".")
|
||||
|
||||
urlFinal := strings.Join(urlSplitted[1:], ".")
|
||||
|
||||
@@ -77,21 +74,19 @@ func ParseFileToLine(content string) string {
|
||||
continue
|
||||
}
|
||||
|
||||
users = append(users, line)
|
||||
users = append(users, strings.TrimSpace(line))
|
||||
}
|
||||
|
||||
return strings.Join(users, ",")
|
||||
}
|
||||
|
||||
func GetSecret(env string, file string) string {
|
||||
if env == "" && file == "" {
|
||||
log.Debug().Msg("No secret provided")
|
||||
func GetSecret(conf string, file string) string {
|
||||
if conf == "" && file == "" {
|
||||
return ""
|
||||
}
|
||||
|
||||
if env != "" {
|
||||
log.Debug().Str("secret", env).Msg("Using secret from env")
|
||||
return env
|
||||
if conf != "" {
|
||||
return conf
|
||||
}
|
||||
|
||||
contents, err := ReadFile(file)
|
||||
@@ -100,29 +95,29 @@ func GetSecret(env string, file string) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
log.Debug().Str("secret", contents).Msg("Using secret from file")
|
||||
|
||||
return contents
|
||||
}
|
||||
|
||||
func GetUsers(env string, file string) (types.Users, error) {
|
||||
func GetUsers(conf string, file string) (types.Users, error) {
|
||||
var users string
|
||||
|
||||
if env == "" && file == "" {
|
||||
if conf == "" && file == "" {
|
||||
return types.Users{}, errors.New("no users provided")
|
||||
}
|
||||
|
||||
if env != "" {
|
||||
log.Debug().Str("users", env).Msg("Using users from env")
|
||||
users += env
|
||||
if conf != "" {
|
||||
log.Debug().Msg("Using users from config")
|
||||
users += conf
|
||||
}
|
||||
|
||||
if file != "" {
|
||||
fileContents, fileErr := ReadFile(file)
|
||||
|
||||
if fileErr == nil {
|
||||
log.Debug().Str("users", ParseFileToLine(fileContents)).Msg("Using users from file")
|
||||
users += ","
|
||||
log.Debug().Msg("Using users from file")
|
||||
if users != "" {
|
||||
users += ","
|
||||
}
|
||||
users += ParseFileToLine(fileContents)
|
||||
}
|
||||
}
|
||||
|
||||
4
main.go
4
main.go
@@ -4,7 +4,6 @@ import (
|
||||
"os"
|
||||
"time"
|
||||
"tinyauth/cmd"
|
||||
"tinyauth/internal/assets"
|
||||
|
||||
"github.com/rs/zerolog"
|
||||
"github.com/rs/zerolog/log"
|
||||
@@ -12,8 +11,7 @@ import (
|
||||
|
||||
func main() {
|
||||
// Logger
|
||||
log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr, TimeFormat: time.RFC3339}).With().Timestamp().Logger()
|
||||
log.Info().Str("version", assets.Version).Msg("Starting tinyauth")
|
||||
log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr, TimeFormat: time.RFC3339}).With().Timestamp().Logger().Level(zerolog.FatalLevel)
|
||||
|
||||
// Run cmd
|
||||
cmd.Execute()
|
||||
|
||||
BIN
site/bun.lockb
BIN
site/bun.lockb
Binary file not shown.
@@ -1,8 +1,9 @@
|
||||
import { Button, Paper, Text } from "@mantine/core";
|
||||
import { Button, Code, Paper, Text } from "@mantine/core";
|
||||
import { notifications } from "@mantine/notifications";
|
||||
import { Navigate } from "react-router";
|
||||
import { useUserContext } from "../context/user-context";
|
||||
import { Layout } from "../components/layouts/layout";
|
||||
import { ReactNode } from "react";
|
||||
|
||||
export const ContinuePage = () => {
|
||||
const queryString = window.location.search;
|
||||
@@ -12,11 +13,11 @@ export const ContinuePage = () => {
|
||||
const { isLoggedIn, disableContinue } = useUserContext();
|
||||
|
||||
if (!isLoggedIn) {
|
||||
return <Navigate to="/login" />;
|
||||
return <Navigate to={`/login?redirect_uri=${redirectUri}`} />;
|
||||
}
|
||||
|
||||
if (disableContinue && redirectUri !== "null") {
|
||||
window.location.replace(redirectUri!);
|
||||
if (redirectUri === "null") {
|
||||
return <Navigate to="/" />;
|
||||
}
|
||||
|
||||
const redirect = () => {
|
||||
@@ -26,31 +27,62 @@ export const ContinuePage = () => {
|
||||
color: "blue",
|
||||
});
|
||||
setTimeout(() => {
|
||||
window.location.replace(redirectUri!);
|
||||
window.location.href = redirectUri!;
|
||||
}, 500);
|
||||
};
|
||||
|
||||
const urlParsed = URL.parse(redirectUri!);
|
||||
|
||||
if (
|
||||
window.location.protocol === "https:" &&
|
||||
urlParsed!.protocol === "http:"
|
||||
) {
|
||||
return (
|
||||
<ContinuePageLayout>
|
||||
<Text size="xl" fw={700}>
|
||||
Insecure Redirect
|
||||
</Text>
|
||||
<Text>
|
||||
Your are logged in but trying to redirect from <Code>https</Code> to{" "}
|
||||
<Code>http</Code>, please click the button to redirect.
|
||||
</Text>
|
||||
<Button fullWidth mt="xl" onClick={redirect}>
|
||||
Continue
|
||||
</Button>
|
||||
</ContinuePageLayout>
|
||||
);
|
||||
}
|
||||
|
||||
if (disableContinue) {
|
||||
window.location.href = redirectUri!;
|
||||
return (
|
||||
<ContinuePageLayout>
|
||||
<Text size="xl" fw={700}>
|
||||
Redirecting
|
||||
</Text>
|
||||
<Text>You should be redirected to your app soon.</Text>
|
||||
</ContinuePageLayout>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<ContinuePageLayout>
|
||||
<Text size="xl" fw={700}>
|
||||
Continue
|
||||
</Text>
|
||||
<Text>Click the button to continue to your app.</Text>
|
||||
<Button fullWidth mt="xl" onClick={redirect}>
|
||||
Continue
|
||||
</Button>
|
||||
</ContinuePageLayout>
|
||||
);
|
||||
};
|
||||
|
||||
export const ContinuePageLayout = ({ children }: { children: ReactNode }) => {
|
||||
return (
|
||||
<Layout>
|
||||
<Paper shadow="md" p={30} mt={30} radius="md" withBorder>
|
||||
{redirectUri !== "null" ? (
|
||||
<>
|
||||
<Text size="xl" fw={700}>
|
||||
Continue
|
||||
</Text>
|
||||
<Text>Click the button to continue to your app.</Text>
|
||||
<Button fullWidth mt="xl" onClick={redirect}>
|
||||
Continue
|
||||
</Button>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<Text size="xl" fw={700}>
|
||||
Logged in
|
||||
</Text>
|
||||
<Text>You are now signed in and can use your apps.</Text>
|
||||
</>
|
||||
)}
|
||||
{children}
|
||||
</Paper>
|
||||
</Layout>
|
||||
);
|
||||
|
||||
@@ -65,8 +65,12 @@ export const LoginPage = () => {
|
||||
color: "green",
|
||||
});
|
||||
setTimeout(() => {
|
||||
window.location.replace(`/continue?redirect_uri=${redirectUri}`);
|
||||
});
|
||||
if (redirectUri === "null") {
|
||||
window.location.replace("/");
|
||||
} else {
|
||||
window.location.replace(`/continue?redirect_uri=${redirectUri}`);
|
||||
}
|
||||
}, 500);
|
||||
},
|
||||
});
|
||||
|
||||
@@ -84,7 +88,14 @@ export const LoginPage = () => {
|
||||
});
|
||||
},
|
||||
onSuccess: (data) => {
|
||||
window.location.replace(data.data.url);
|
||||
notifications.show({
|
||||
title: "Redirecting",
|
||||
message: "Redirecting to your OAuth provider",
|
||||
color: "blue",
|
||||
});
|
||||
setTimeout(() => {
|
||||
window.location.href = data.data.url;
|
||||
}, 500);
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ export const LogoutPage = () => {
|
||||
color: "green",
|
||||
});
|
||||
setTimeout(() => {
|
||||
window.location.reload();
|
||||
window.location.replace("/login");
|
||||
}, 500);
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user