You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
87 lines
1.9 KiB
Go
87 lines
1.9 KiB
Go
package passkey
|
|
|
|
import (
|
|
"crypto/rand"
|
|
"encoding/base64"
|
|
"sync"
|
|
"time"
|
|
|
|
"github.com/1Panel-dev/1Panel/core/utils/common"
|
|
"github.com/go-webauthn/webauthn/webauthn"
|
|
)
|
|
|
|
const (
|
|
PasskeyUserIDSettingKey = "PasskeyUserID"
|
|
PasskeyCredentialSettingKey = "PasskeyCredentials"
|
|
PasskeyMaxCredentials = 5
|
|
PasskeySessionTTL = 5 * time.Minute
|
|
PasskeySessionKindLogin = "login"
|
|
PasskeySessionKindRegister = "register"
|
|
PasskeyCredentialNameDefault = "Passkey"
|
|
)
|
|
|
|
var passkeySessions = newPasskeySessionStore()
|
|
|
|
func GetPasskeySessionStore() *passkeySessionStore {
|
|
return passkeySessions
|
|
}
|
|
|
|
type passkeySession struct {
|
|
Kind string
|
|
Name string
|
|
Session webauthn.SessionData
|
|
ExpiresAt time.Time
|
|
}
|
|
|
|
type passkeySessionStore struct {
|
|
mu sync.Mutex
|
|
items map[string]passkeySession
|
|
}
|
|
|
|
func newPasskeySessionStore() *passkeySessionStore {
|
|
return &passkeySessionStore{items: make(map[string]passkeySession)}
|
|
}
|
|
|
|
func (s *passkeySessionStore) Set(kind, name string, session webauthn.SessionData) string {
|
|
s.mu.Lock()
|
|
defer s.mu.Unlock()
|
|
|
|
sessionID := generatePasskeySessionID()
|
|
s.items[sessionID] = passkeySession{
|
|
Kind: kind,
|
|
Name: name,
|
|
Session: session,
|
|
ExpiresAt: time.Now().Add(PasskeySessionTTL),
|
|
}
|
|
return sessionID
|
|
}
|
|
|
|
func (s *passkeySessionStore) Get(sessionID string) (passkeySession, bool) {
|
|
s.mu.Lock()
|
|
defer s.mu.Unlock()
|
|
|
|
item, ok := s.items[sessionID]
|
|
if !ok {
|
|
return passkeySession{}, false
|
|
}
|
|
if time.Now().After(item.ExpiresAt) {
|
|
delete(s.items, sessionID)
|
|
return passkeySession{}, false
|
|
}
|
|
return item, true
|
|
}
|
|
|
|
func (s *passkeySessionStore) Delete(sessionID string) {
|
|
s.mu.Lock()
|
|
defer s.mu.Unlock()
|
|
delete(s.items, sessionID)
|
|
}
|
|
|
|
func generatePasskeySessionID() string {
|
|
raw := make([]byte, 32)
|
|
if _, err := rand.Read(raw); err != nil {
|
|
return common.RandStr(32)
|
|
}
|
|
return base64.RawURLEncoding.EncodeToString(raw)
|
|
}
|