mirror of
https://github.com/steveiliop56/tinyauth.git
synced 2025-10-28 12:45:47 +00:00
Compare commits
3 Commits
l10n_main
...
6647c6cd78
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6647c6cd78 | ||
|
|
7231efcbc3 | ||
|
|
5482430907 |
@@ -1,62 +1,62 @@
|
||||
{
|
||||
"loginTitle": "Tervetuloa takaisin, kirjaudu sisään käyttäen",
|
||||
"loginTitleSimple": "Tervetuloa takaisin, ole hyvä ja kirjaudu",
|
||||
"loginDivider": "Tai",
|
||||
"loginUsername": "Käyttäjätunnus",
|
||||
"loginPassword": "Salasana",
|
||||
"loginSubmit": "Kirjaudu",
|
||||
"loginFailTitle": "Kirjautuminen epäonnistui",
|
||||
"loginFailSubtitle": "Tarkista käyttäjätunnuksesi ja salasanasi",
|
||||
"loginFailRateLimit": "Kirjautuminen epäonnistui liian monta kertaa. Yritä myöhemmin uudelleen",
|
||||
"loginSuccessTitle": "Olet kirjautunut sisään",
|
||||
"loginSuccessSubtitle": "Tervetuloa takaisin!",
|
||||
"loginOauthFailTitle": "Tapahtui virhe",
|
||||
"loginOauthFailSubtitle": "OAuthin URL-osoitteen haku epäonnistui",
|
||||
"loginOauthSuccessTitle": "Uudelleenohjataan",
|
||||
"loginOauthSuccessSubtitle": "Uudelleenohjaus OAuth -palveluntarjoajallesi",
|
||||
"loginOauthAutoRedirectTitle": "Automaattinen OAuth -uudelleenohjaus",
|
||||
"loginOauthAutoRedirectSubtitle": "Sinut ohjataan automaattisesti OAuth -palveluntarjoajallesi todentamista varten.",
|
||||
"loginOauthAutoRedirectButton": "Siirry nyt",
|
||||
"continueTitle": "Jatka",
|
||||
"continueRedirectingTitle": "Uudelleenohjataan...",
|
||||
"continueRedirectingSubtitle": "Sinun pitäisi ohjautua sovellukseen pian",
|
||||
"continueRedirectManually": "Siirrä minut manuaalisesti",
|
||||
"continueInsecureRedirectTitle": "Turvaton uudelleenohjaus",
|
||||
"continueInsecureRedirectSubtitle": "Yrität siirtyä suojatusta <code>https</code> -sivusta suojaamattomalle <code>http</code> -sivulle. Oletko varma, että haluat jatkaa?",
|
||||
"continueUntrustedRedirectTitle": "Ei-luotettu uudelleenohjaus",
|
||||
"continueUntrustedRedirectSubtitle": "Yrität uudelleenohjata domainiin, joka ei vastaa määritettyä verkkotunnusta (<code>{{cookieDomain}}</code>). Oletko varma, että haluat jatkaa?",
|
||||
"logoutFailTitle": "Uloskirjautuminen epäonnistui",
|
||||
"logoutFailSubtitle": "Ole hyvä ja yritä uudelleen",
|
||||
"logoutSuccessTitle": "Kirjauduttu ulos",
|
||||
"logoutSuccessSubtitle": "Sinut on kirjattu ulos",
|
||||
"logoutTitle": "Kirjaudu ulos",
|
||||
"logoutUsernameSubtitle": "Olet kirjautuneena sisään tunnuksella <code>{{username}}</code>. Kirjaudu ulos alla olevasta painikkeesta.",
|
||||
"logoutOauthSubtitle": "Olet kirjautuneena sisään tunnuksella <code>{{username}}</code> OAuth palvelun {{provider}} kautta. Kirjaudu ulos alla olevasta painikkeesta.",
|
||||
"notFoundTitle": "Sivua ei löydy",
|
||||
"notFoundSubtitle": "Sivua, jota etsit ei ole olemassa.",
|
||||
"notFoundButton": "Palaa kotinäkymään",
|
||||
"totpFailTitle": "Koodin vahvistus epäonnistui",
|
||||
"totpFailSubtitle": "Tarkista koodisi ja yritä uudelleen",
|
||||
"totpSuccessTitle": "Vahvistettu",
|
||||
"totpSuccessSubtitle": "Uudelleenohjataan sovelluksellesi",
|
||||
"totpTitle": "Syötä TOTP -koodisi",
|
||||
"totpSubtitle": "Ole hyvä ja syötä koodi todennussovelluksestasi.",
|
||||
"unauthorizedTitle": "Ei sallittu",
|
||||
"unauthorizedResourceSubtitle": "Käyttäjällä <code>{{username}}</code> ei ole pääsyä kohteeseen <code>{{resource}}</code>.",
|
||||
"unauthorizedLoginSubtitle": "Käyttäjällä <code>{{username}}</code> ei ole lupaa kirjautua.",
|
||||
"unauthorizedGroupsSubtitle": "Käyttäjä <code>{{username}}</code> ei ole ryhmässä, joka vaaditaan pääsyyn kohteeseen <code>{{resource}}</code>.",
|
||||
"unauthorizedIpSubtitle": "IP osoitteestasi <code>{{ip}}</code> ei ole pääsyä kohteeseen <code>{{resource}}</code>.",
|
||||
"unauthorizedButton": "Yritä uudelleen",
|
||||
"cancelTitle": "Peruuta",
|
||||
"forgotPasswordTitle": "Unohditko salasanasi?",
|
||||
"failedToFetchProvidersTitle": "Todennuspalvelujen tarjoajien lataaminen epäonnistui. Tarkista määrityksesi.",
|
||||
"errorTitle": "Tapahtui virhe",
|
||||
"errorSubtitle": "Tapahtui virhe yritettäessä suorittaa tämä toiminto. Ole hyvä ja tarkista konsoli saadaksesi lisätietoja.",
|
||||
"forgotPasswordMessage": "Voit nollata salasanasi vaihtamalla ympäristömuuttujan `USERS`.",
|
||||
"fieldRequired": "Tämä kenttä on pakollinen",
|
||||
"invalidInput": "Virheellinen syöte",
|
||||
"domainWarningTitle": "Virheellinen verkkotunnus",
|
||||
"domainWarningSubtitle": "Tämä instanssi on määritelty käyttämään osoitetta <code>{{appUrl}}</code>, mutta nykyinen osoite on <code>{{currentUrl}}</code>. Jos jatkat, saatat törmätä ongelmiin autentikoinnissa.",
|
||||
"ignoreTitle": "Jätä huomiotta",
|
||||
"goToCorrectDomainTitle": "Siirry oikeaan verkkotunnukseen"
|
||||
"loginTitle": "Welcome back, login with",
|
||||
"loginTitleSimple": "Welcome back, please login",
|
||||
"loginDivider": "Or",
|
||||
"loginUsername": "Username",
|
||||
"loginPassword": "Password",
|
||||
"loginSubmit": "Login",
|
||||
"loginFailTitle": "Failed to log in",
|
||||
"loginFailSubtitle": "Please check your username and password",
|
||||
"loginFailRateLimit": "You failed to login too many times. Please try again later",
|
||||
"loginSuccessTitle": "Logged in",
|
||||
"loginSuccessSubtitle": "Welcome back!",
|
||||
"loginOauthFailTitle": "An error occurred",
|
||||
"loginOauthFailSubtitle": "Failed to get OAuth URL",
|
||||
"loginOauthSuccessTitle": "Redirecting",
|
||||
"loginOauthSuccessSubtitle": "Redirecting to your OAuth provider",
|
||||
"loginOauthAutoRedirectTitle": "OAuth Auto Redirect",
|
||||
"loginOauthAutoRedirectSubtitle": "You will be automatically redirected to your OAuth provider to authenticate.",
|
||||
"loginOauthAutoRedirectButton": "Redirect now",
|
||||
"continueTitle": "Continue",
|
||||
"continueRedirectingTitle": "Redirecting...",
|
||||
"continueRedirectingSubtitle": "You should be redirected to the app soon",
|
||||
"continueRedirectManually": "Redirect me manually",
|
||||
"continueInsecureRedirectTitle": "Insecure redirect",
|
||||
"continueInsecureRedirectSubtitle": "You are trying to redirect from <code>https</code> to <code>http</code> which is not secure. Are you sure you want to continue?",
|
||||
"continueUntrustedRedirectTitle": "Untrusted redirect",
|
||||
"continueUntrustedRedirectSubtitle": "You are trying to redirect to a domain that does not match your configured domain (<code>{{cookieDomain}}</code>). Are you sure you want to continue?",
|
||||
"logoutFailTitle": "Failed to log out",
|
||||
"logoutFailSubtitle": "Please try again",
|
||||
"logoutSuccessTitle": "Logged out",
|
||||
"logoutSuccessSubtitle": "You have been logged out",
|
||||
"logoutTitle": "Logout",
|
||||
"logoutUsernameSubtitle": "You are currently logged in as <code>{{username}}</code>. Click the button below to logout.",
|
||||
"logoutOauthSubtitle": "You are currently logged in as <code>{{username}}</code> using the {{provider}} OAuth provider. Click the button below to logout.",
|
||||
"notFoundTitle": "Page not found",
|
||||
"notFoundSubtitle": "The page you are looking for does not exist.",
|
||||
"notFoundButton": "Go home",
|
||||
"totpFailTitle": "Failed to verify code",
|
||||
"totpFailSubtitle": "Please check your code and try again",
|
||||
"totpSuccessTitle": "Verified",
|
||||
"totpSuccessSubtitle": "Redirecting to your app",
|
||||
"totpTitle": "Enter your TOTP code",
|
||||
"totpSubtitle": "Please enter the code from your authenticator app.",
|
||||
"unauthorizedTitle": "Unauthorized",
|
||||
"unauthorizedResourceSubtitle": "The user with username <code>{{username}}</code> is not authorized to access the resource <code>{{resource}}</code>.",
|
||||
"unauthorizedLoginSubtitle": "The user with username <code>{{username}}</code> is not authorized to login.",
|
||||
"unauthorizedGroupsSubtitle": "The user with username <code>{{username}}</code> is not in the groups required by the resource <code>{{resource}}</code>.",
|
||||
"unauthorizedIpSubtitle": "Your IP address <code>{{ip}}</code> is not authorized to access the resource <code>{{resource}}</code>.",
|
||||
"unauthorizedButton": "Try again",
|
||||
"cancelTitle": "Cancel",
|
||||
"forgotPasswordTitle": "Forgot your password?",
|
||||
"failedToFetchProvidersTitle": "Failed to load authentication providers. Please check your configuration.",
|
||||
"errorTitle": "An error occurred",
|
||||
"errorSubtitle": "An error occurred while trying to perform this action. Please check the console for more information.",
|
||||
"forgotPasswordMessage": "You can reset your password by changing the `USERS` environment variable.",
|
||||
"fieldRequired": "This field is required",
|
||||
"invalidInput": "Invalid input",
|
||||
"domainWarningTitle": "Invalid Domain",
|
||||
"domainWarningSubtitle": "This instance is configured to be accessed from <code>{{appUrl}}</code>, but <code>{{currentUrl}}</code> is being used. If you proceed, you may encounter issues with authentication.",
|
||||
"ignoreTitle": "Ignore",
|
||||
"goToCorrectDomainTitle": "Go to correct domain"
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package bootstrap
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
@@ -13,11 +14,13 @@ import (
|
||||
"tinyauth/internal/config"
|
||||
"tinyauth/internal/controller"
|
||||
"tinyauth/internal/middleware"
|
||||
"tinyauth/internal/model"
|
||||
"tinyauth/internal/service"
|
||||
"tinyauth/internal/utils"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/rs/zerolog/log"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type Controller interface {
|
||||
@@ -277,6 +280,10 @@ func (app *BootstrapApp) Setup() error {
|
||||
go app.heartbeat()
|
||||
}
|
||||
|
||||
// Start DB cleanup routine
|
||||
log.Debug().Msg("Starting database cleanup routine")
|
||||
go app.dbCleanup(database)
|
||||
|
||||
// Start server
|
||||
address := fmt.Sprintf("%s:%d", app.config.Address, app.config.Port)
|
||||
log.Info().Msgf("Starting server on %s", address)
|
||||
@@ -338,3 +345,17 @@ func (app *BootstrapApp) heartbeat() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (app *BootstrapApp) dbCleanup(db *gorm.DB) {
|
||||
ticker := time.NewTicker(time.Duration(30) * time.Minute)
|
||||
defer ticker.Stop()
|
||||
ctx := context.Background()
|
||||
|
||||
for ; true; <-ticker.C {
|
||||
log.Debug().Msg("Cleaning up old database sessions")
|
||||
_, err := gorm.G[model.Session](db).Where("expiry < ?", time.Now().UnixMilli()).Delete(ctx)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("Failed to cleanup old sessions")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,6 +72,7 @@ func (controller *OAuthController) oauthURLHandler(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
service.GenerateVerifier()
|
||||
state := service.GenerateState()
|
||||
authURL := service.GetAuthURL(state)
|
||||
c.SetCookie(controller.config.CSRFCookieName, state, int(time.Hour.Seconds()), "/", fmt.Sprintf(".%s", controller.config.CookieDomain), controller.config.SecureCookie, true)
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
@@ -41,6 +43,7 @@ type AuthService struct {
|
||||
loginMutex sync.RWMutex
|
||||
ldap *LdapService
|
||||
database *gorm.DB
|
||||
ctx context.Context
|
||||
}
|
||||
|
||||
func NewAuthService(config AuthServiceConfig, docker *DockerService, ldap *LdapService, database *gorm.DB) *AuthService {
|
||||
@@ -54,6 +57,7 @@ func NewAuthService(config AuthServiceConfig, docker *DockerService, ldap *LdapS
|
||||
}
|
||||
|
||||
func (auth *AuthService) Init() error {
|
||||
auth.ctx = context.Background()
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -213,7 +217,7 @@ func (auth *AuthService) CreateSessionCookie(c *gin.Context, data *config.Sessio
|
||||
OAuthName: data.OAuthName,
|
||||
}
|
||||
|
||||
err = auth.database.Create(&session).Error
|
||||
err = gorm.G[model.Session](auth.database).Create(auth.ctx, &session)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -231,10 +235,10 @@ func (auth *AuthService) DeleteSessionCookie(c *gin.Context) error {
|
||||
return err
|
||||
}
|
||||
|
||||
res := auth.database.Unscoped().Where("uuid = ?", cookie).Delete(&model.Session{})
|
||||
_, err = gorm.G[model.Session](auth.database).Where("uuid = ?", cookie).Delete(auth.ctx)
|
||||
|
||||
if res.Error != nil {
|
||||
return res.Error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c.SetCookie(auth.config.SessionCookieName, "", -1, "/", fmt.Sprintf(".%s", auth.config.CookieDomain), auth.config.SecureCookie, true)
|
||||
@@ -249,15 +253,13 @@ func (auth *AuthService) GetSessionCookie(c *gin.Context) (config.SessionCookie,
|
||||
return config.SessionCookie{}, err
|
||||
}
|
||||
|
||||
var session model.Session
|
||||
session, err := gorm.G[model.Session](auth.database).Where("uuid = ?", cookie).First(auth.ctx)
|
||||
|
||||
res := auth.database.Unscoped().Where("uuid = ?", cookie).First(&session)
|
||||
|
||||
if res.Error != nil {
|
||||
return config.SessionCookie{}, res.Error
|
||||
if err != nil {
|
||||
return config.SessionCookie{}, err
|
||||
}
|
||||
|
||||
if res.RowsAffected == 0 {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return config.SessionCookie{}, fmt.Errorf("session not found")
|
||||
}
|
||||
|
||||
|
||||
@@ -59,10 +59,8 @@ func (generic *GenericOAuthService) Init() error {
|
||||
ctx := context.Background()
|
||||
|
||||
ctx = context.WithValue(ctx, oauth2.HTTPClient, httpClient)
|
||||
verifier := oauth2.GenerateVerifier()
|
||||
|
||||
generic.context = ctx
|
||||
generic.verifier = verifier
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -76,6 +74,12 @@ func (generic *GenericOAuthService) GenerateState() string {
|
||||
return state
|
||||
}
|
||||
|
||||
func (generic *GenericOAuthService) GenerateVerifier() string {
|
||||
verifier := oauth2.GenerateVerifier()
|
||||
generic.verifier = verifier
|
||||
return verifier
|
||||
}
|
||||
|
||||
func (generic *GenericOAuthService) GetAuthURL(state string) string {
|
||||
return generic.config.AuthCodeURL(state, oauth2.AccessTypeOffline, oauth2.S256ChallengeOption(generic.verifier))
|
||||
}
|
||||
|
||||
@@ -53,10 +53,7 @@ func (github *GithubOAuthService) Init() error {
|
||||
httpClient := &http.Client{}
|
||||
ctx := context.Background()
|
||||
ctx = context.WithValue(ctx, oauth2.HTTPClient, httpClient)
|
||||
verifier := oauth2.GenerateVerifier()
|
||||
|
||||
github.context = ctx
|
||||
github.verifier = verifier
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -70,6 +67,12 @@ func (github *GithubOAuthService) GenerateState() string {
|
||||
return state
|
||||
}
|
||||
|
||||
func (github *GithubOAuthService) GenerateVerifier() string {
|
||||
verifier := oauth2.GenerateVerifier()
|
||||
github.verifier = verifier
|
||||
return verifier
|
||||
}
|
||||
|
||||
func (github *GithubOAuthService) GetAuthURL(state string) string {
|
||||
return github.config.AuthCodeURL(state, oauth2.AccessTypeOffline, oauth2.S256ChallengeOption(github.verifier))
|
||||
}
|
||||
|
||||
@@ -48,10 +48,7 @@ func (google *GoogleOAuthService) Init() error {
|
||||
httpClient := &http.Client{}
|
||||
ctx := context.Background()
|
||||
ctx = context.WithValue(ctx, oauth2.HTTPClient, httpClient)
|
||||
verifier := oauth2.GenerateVerifier()
|
||||
|
||||
google.context = ctx
|
||||
google.verifier = verifier
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -65,6 +62,12 @@ func (oauth *GoogleOAuthService) GenerateState() string {
|
||||
return state
|
||||
}
|
||||
|
||||
func (google *GoogleOAuthService) GenerateVerifier() string {
|
||||
verifier := oauth2.GenerateVerifier()
|
||||
google.verifier = verifier
|
||||
return verifier
|
||||
}
|
||||
|
||||
func (google *GoogleOAuthService) GetAuthURL(state string) string {
|
||||
return google.config.AuthCodeURL(state, oauth2.AccessTypeOffline, oauth2.S256ChallengeOption(google.verifier))
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
type OAuthService interface {
|
||||
Init() error
|
||||
GenerateState() string
|
||||
GenerateVerifier() string
|
||||
GetAuthURL(state string) string
|
||||
VerifyCode(code string) error
|
||||
Userinfo() (config.Claims, error)
|
||||
|
||||
Reference in New Issue
Block a user