fix: improvements for login and oidc (#227)

* add csrf

* caching

* caching

* caching

* caching

* security headers

* csp and security headers

* error handler csp

* select user with display name

* csp

* user selection styling

* username to loginname

* regenerate grpc

* regenerate

* change to login name
This commit is contained in:
Livio Amstutz 2020-06-17 08:06:40 +02:00 committed by GitHub
parent dfe6d0deb4
commit 1c59d18fee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
108 changed files with 19226 additions and 19220 deletions

View File

@ -24,6 +24,7 @@ export ZITADEL_USER_VERIFICATION_KEY=UserVerificationKey_1
export ZITADEL_OTP_VERIFICATION_KEY=OTPVerificationKey_1
export ZITADEL_OIDC_KEYS_ID=OIDCKey_1
export ZITADEL_COOKIE_KEY=CookieKey_1
export ZITADEL_CSRF_KEY=CookieKey_1
# Notifications
export DEBUG_MODE=TRUE
@ -47,6 +48,13 @@ export ZITADEL_CONSOLE=http://localhost:4200
export CAOS_OIDC_DEV=true
export ZITADEL_COOKIE_DOMAIN=localhost
#CSRF
export ZITADEL_CSRF_DEV=true
#CACHE
export ZITADEL_CACHE_MAXAGE=12h
export ZITADEL_CACHE_SHARED_MAXAGE=168h
#Console
export ZITADEL_CONSOLE_ENV_DIR=../../console/src/assets/

View File

@ -66,6 +66,9 @@ Auth:
Domain: $ZITADEL_COOKIE_DOMAIN
Key:
EncryptionKeyID: $ZITADEL_COOKIE_KEY
Cache:
MaxAge: $ZITADEL_CACHE_MAXAGE
SharedMaxAge: $ZITADEL_CACHE_SHARED_MAXAGE
Endpoints:
Auth:
Path: 'authorize'
@ -129,6 +132,14 @@ Login:
ZitadelURL: '$ZITADEL_CONSOLE'
LanguageCookieName: 'caos.zitadel.login.lang'
DefaultLanguage: 'de'
CSRF:
CookieName: 'caos.zitadel.login.csrf'
Key:
EncryptionKeyID: $ZITADEL_CSRF_KEY
Development: $ZITADEL_CSRF_DEV
Cache:
MaxAge: $ZITADEL_CACHE_MAXAGE
SharedMaxAge: $ZITADEL_CACHE_SHARED_MAXAGE
AuthZ:

1
go.mod
View File

@ -23,6 +23,7 @@ require (
github.com/ghodss/yaml v1.0.0
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b
github.com/golang/mock v1.4.3
github.com/gorilla/csrf v1.7.0
github.com/golang/protobuf v1.4.2
github.com/gorilla/mux v1.7.4
github.com/gorilla/schema v1.1.0

3
go.sum
View File

@ -166,6 +166,8 @@ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/gorilla/csrf v1.7.0 h1:mMPjV5/3Zd460xCavIkppUdvnl5fPXMpv2uz2Zyg7/Y=
github.com/gorilla/csrf v1.7.0/go.mod h1:+a/4tCmqhG6/w4oafeAZ9pEa3/NZOWYVbD9fV0FwIQA=
github.com/gorilla/handlers v1.4.2 h1:0QniY0USkHQ1RGCLfKxeNHK9bkDHGRYGNDFBCS+YARg=
github.com/gorilla/handlers v1.4.2/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ=
github.com/gorilla/mux v1.7.4 h1:VuZ8uybHlWmqV03+zRzdwKL4tUnIp1MAQtp1mIFE1bc=
@ -259,6 +261,7 @@ github.com/nicksnyder/go-i18n/v2 v2.0.3 h1:ks/JkQiOEhhuF6jpNvx+Wih1NIiXzUnZeZVnJ
github.com/nicksnyder/go-i18n/v2 v2.0.3/go.mod h1:oDab7q8XCYMRlcrBnaY/7B1eOectbvj6B1UPBT+p5jo=
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=

View File

@ -76,6 +76,7 @@ func createMux(ctx context.Context, g Gateway) *runtime.ServeMux {
func addInterceptors(handler http.Handler, g Gateway) http.Handler {
handler = http_mw.DefaultTraceHandler(handler)
handler = http_mw.NoCacheInterceptor(handler)
if interceptor, ok := g.(grpcGatewayCustomInterceptor); ok {
handler = interceptor.GatewayHTTPInterceptor(handler)
}

View File

@ -4,12 +4,23 @@ const (
Authorization = "authorization"
Accept = "accept"
AcceptLanguage = "accept-language"
CacheControl = "cache-control"
ContentType = "content-type"
Expires = "expires"
Location = "location"
Origin = "origin"
Pragma = "pragma"
UserAgent = "user-agent"
ForwardedFor = "x-forwarded-for"
ContentSecurityPolicy = "content-security-policy"
XXSSProtection = "x-xss-protection"
StrictTransportSecurity = "strict-transport-security"
XFrameOptions = "x-frame-options"
XContentTypeOptions = "x-content-type-options"
ReferrerPolicy = "referrer-policy"
FeaturePolicy = "feature-policy"
ZitadelOrgID = "x-zitadel-orgid"
//TODO: Remove as soon an authentification is implemented
ZitadelUserID = "x-zitadel-userid"

View File

@ -0,0 +1,128 @@
package middleware
import (
"fmt"
"net/http"
"regexp"
"strings"
"time"
"github.com/caos/zitadel/internal/api"
"github.com/caos/zitadel/internal/config/types"
)
type Cache struct {
Cacheability Cacheability
NoCache bool
NoStore bool
MaxAge time.Duration
SharedMaxAge time.Duration
NoTransform bool
Revalidation Revalidation
}
type Cacheability string
const (
CacheabilityNotSet Cacheability = ""
CacheabilityPublic = "public"
CacheabilityPrivate = "private"
)
type Revalidation string
const (
RevalidationNotSet Revalidation = ""
RevalidationMust = "must-revalidate"
RevalidationProxy = "proxy-revalidate"
)
type CacheConfig struct {
MaxAge types.Duration
SharedMaxAge types.Duration
}
var (
NeverCacheOptions = &Cache{
NoStore: true,
}
AssetOptions = func(maxAge, SharedMaxAge time.Duration) *Cache {
return &Cache{
Cacheability: CacheabilityPublic,
MaxAge: maxAge,
SharedMaxAge: SharedMaxAge,
}
}
)
func DefaultCacheInterceptor(pattern string, maxAge, sharedMaxAge time.Duration) (func(http.Handler) http.Handler, error) {
regex, err := regexp.Compile(pattern)
if err != nil {
return nil, err
}
return func(handler http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if regex.MatchString(r.URL.Path) {
AssetsCacheInterceptor(maxAge, sharedMaxAge, handler).ServeHTTP(w, r)
return
}
NoCacheInterceptor(handler).ServeHTTP(w, r)
})
}, nil
}
func NoCacheInterceptor(h http.Handler) http.Handler {
return CacheInterceptorOpts(h, NeverCacheOptions)
}
func AssetsCacheInterceptor(maxAge, sharedMaxAge time.Duration, h http.Handler) http.Handler {
return CacheInterceptorOpts(h, AssetOptions(maxAge, sharedMaxAge))
}
func CacheInterceptorOpts(h http.Handler, cache *Cache) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
cache.serializeHeaders(w)
h.ServeHTTP(w, req)
})
}
func (c *Cache) serializeHeaders(w http.ResponseWriter) {
control := make([]string, 0, 6)
pragma := false
if c.Cacheability != CacheabilityNotSet {
control = append(control, string(c.Cacheability))
control = append(control, fmt.Sprintf("max-age=%v", c.MaxAge.Seconds()))
if c.SharedMaxAge != c.MaxAge {
control = append(control, fmt.Sprintf("s-maxage=%v", c.SharedMaxAge.Seconds()))
}
}
maxAge := c.MaxAge
if maxAge == 0 {
maxAge = -time.Hour
}
expires := time.Now().UTC().Add(maxAge).Format(http.TimeFormat)
if c.NoCache {
control = append(control, fmt.Sprintf("no-cache"))
pragma = true
}
if c.NoStore {
control = append(control, fmt.Sprintf("no-store"))
pragma = true
}
if c.NoTransform {
control = append(control, fmt.Sprintf("no-transform"))
}
if c.Revalidation != RevalidationNotSet {
control = append(control, string(c.Revalidation))
}
w.Header().Set(api.CacheControl, strings.Join(control, ", "))
w.Header().Set(api.Expires, expires)
if pragma {
w.Header().Set(api.Pragma, "no-cache")
}
}

View File

@ -0,0 +1,82 @@
package middleware
import (
"net/http"
"net/http/httptest"
"testing"
"time"
"github.com/stretchr/testify/assert"
)
func TestCache_serializeHeaders(t *testing.T) {
type fields struct {
Cacheability Cacheability
NoCache bool
NoStore bool
MaxAge time.Duration
SharedMaxAge time.Duration
NoTransform bool
Revalidation Revalidation
}
tests := []struct {
name string
fields fields
wantControl string
wantExpires string
wantPragma string
}{
{
"no-store",
fields{
NoStore: true,
},
"no-store",
time.Now().UTC().Add(-1 * time.Hour).Format(http.TimeFormat),
"no-cache",
},
{
"private and max-age",
fields{
Cacheability: CacheabilityPrivate,
MaxAge: 1 * time.Hour,
SharedMaxAge: 1 * time.Hour,
},
"private, max-age=3600",
time.Now().UTC().Add(1 * time.Hour).Format(http.TimeFormat),
"",
},
{
"public, no-cache, proxy-revalidate",
fields{
Cacheability: CacheabilityPublic,
NoCache: true,
Revalidation: RevalidationProxy,
},
"public, max-age=0, no-cache, proxy-revalidate",
time.Now().UTC().Add(-1 * time.Hour).Format(http.TimeFormat),
"no-cache",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
recorder := httptest.NewRecorder()
c := &Cache{
Cacheability: tt.fields.Cacheability,
NoCache: tt.fields.NoCache,
NoStore: tt.fields.NoStore,
MaxAge: tt.fields.MaxAge,
SharedMaxAge: tt.fields.SharedMaxAge,
NoTransform: tt.fields.NoTransform,
Revalidation: tt.fields.Revalidation,
}
c.serializeHeaders(recorder)
cc := recorder.Result().Header.Get("cache-control")
assert.Equal(t, tt.wantControl, cc)
exp := recorder.Result().Header.Get("expires")
assert.Equal(t, tt.wantExpires, exp)
pragma := recorder.Result().Header.Get("pragma")
assert.Equal(t, tt.wantPragma, pragma)
})
}
}

View File

@ -0,0 +1,125 @@
package middleware
import (
"fmt"
"strings"
)
type CSP struct {
DefaultSrc CSPSourceOptions
ScriptSrc CSPSourceOptions
ObjectSrc CSPSourceOptions
StyleSrc CSPSourceOptions
ImgSrc CSPSourceOptions
MediaSrc CSPSourceOptions
FrameSrc CSPSourceOptions
FontSrc CSPSourceOptions
ConnectSrc CSPSourceOptions
FormAction CSPSourceOptions
}
var (
DefaultSCP = CSP{
DefaultSrc: CSPSourceOptsNone(),
ScriptSrc: CSPSourceOptsSelf(),
ObjectSrc: CSPSourceOptsNone(),
StyleSrc: CSPSourceOptsSelf(),
ImgSrc: CSPSourceOptsSelf(),
MediaSrc: CSPSourceOptsNone(),
FrameSrc: CSPSourceOptsNone(),
FontSrc: CSPSourceOptsSelf(),
ConnectSrc: CSPSourceOptsSelf(),
}
)
func (csp *CSP) Value(nonce string) string {
valuesMap := csp.asMap()
values := make([]string, 0, len(valuesMap))
for k, v := range valuesMap {
if v == nil {
continue
}
values = append(values, fmt.Sprintf("%v %v", k, v.String(nonce)))
}
return strings.Join(values, ";")
}
func (csp *CSP) asMap() map[string]CSPSourceOptions {
return map[string]CSPSourceOptions{
"default-src": csp.DefaultSrc,
"script-src": csp.ScriptSrc,
"object-src": csp.ObjectSrc,
"style-src": csp.StyleSrc,
"img-src": csp.ImgSrc,
"media-src": csp.MediaSrc,
"frame-src": csp.FrameSrc,
"font-src": csp.FontSrc,
"connect-src": csp.ConnectSrc,
"form-action": csp.FormAction,
}
}
type CSPSourceOptions []string
func CSPSourceOpts() CSPSourceOptions {
return CSPSourceOptions{}
}
func CSPSourceOptsNone() CSPSourceOptions {
return []string{"'none'"}
}
func CSPSourceOptsSelf() CSPSourceOptions {
return []string{"'self'"}
}
func (srcOpts CSPSourceOptions) AddSelf() CSPSourceOptions {
return append(srcOpts, "'self'")
}
func (srcOpts CSPSourceOptions) AddInline() CSPSourceOptions {
return append(srcOpts, "'unsafe-inline'")
}
func (srcOpts CSPSourceOptions) AddEval() CSPSourceOptions {
return append(srcOpts, "'unsafe-eval'")
}
func (srcOpts CSPSourceOptions) AddStrictDynamic() CSPSourceOptions {
return append(srcOpts, "'strict-dynamic'")
}
func (srcOpts CSPSourceOptions) AddHost(h ...string) CSPSourceOptions {
return append(srcOpts, h...)
}
func (srcOpts CSPSourceOptions) AddScheme(s ...string) CSPSourceOptions {
return srcOpts.add(s, "%v:")
}
func (srcOpts CSPSourceOptions) AddNonce() CSPSourceOptions {
return append(srcOpts, "'nonce-%v'")
}
func (srcOpts CSPSourceOptions) AddHash(alg, b64v string) CSPSourceOptions {
return append(srcOpts, fmt.Sprintf("'%v-%v'", alg, b64v))
}
func (srcOpts CSPSourceOptions) String(nonce string) string {
value := strings.Join(srcOpts, " ")
if !strings.Contains(value, "%v") {
return value
}
return fmt.Sprintf(value, nonce)
}
func (srcOpts CSPSourceOptions) add(values []string, format string) CSPSourceOptions {
for i, v := range values {
values[i] = fmt.Sprintf(format, v)
}
return append(srcOpts, values...)
}

View File

@ -0,0 +1,90 @@
package middleware
import (
"context"
"crypto/rand"
"encoding/base64"
"net/http"
"github.com/caos/zitadel/internal/api"
)
type key int
const (
nonceKey key = 0
DefaultNonceLength = uint(32)
)
func SecurityHeaders(csp *CSP, errorHandler func(error) http.Handler, nonceLength ...uint) func(http.Handler) http.Handler {
return func(handler http.Handler) http.Handler {
if csp == nil {
csp = &DefaultSCP
}
length := DefaultNonceLength
if len(nonceLength) > 0 {
length = nonceLength[0]
}
return &headers{
csp: csp,
handler: handler,
errorHandler: errorHandler,
nonceLength: length,
}
}
}
type headers struct {
csp *CSP
handler http.Handler
errorHandler func(err error) http.Handler
nonceLength uint
}
func (h *headers) ServeHTTP(w http.ResponseWriter, r *http.Request) {
nonce := GetNonce(r)
if nonce == "" {
var err error
nonce, err = generateNonce(h.nonceLength)
if err != nil {
h.errorHandler(err).ServeHTTP(w, r)
return
}
r = saveContext(r, nonceKey, nonce)
}
headers := w.Header()
headers.Set(api.ContentSecurityPolicy, h.csp.Value(nonce))
headers.Set(api.XXSSProtection, "1; mode=block")
headers.Set(api.StrictTransportSecurity, "max-age=31536000; includeSubDomains")
headers.Set(api.XFrameOptions, "DENY")
headers.Set(api.XContentTypeOptions, "nosniff")
headers.Set(api.ReferrerPolicy, "same-origin")
headers.Set(api.FeaturePolicy, "payment 'none'")
//PLANNED: add expect-ct
h.handler.ServeHTTP(w, r)
}
func GetNonce(r *http.Request) string {
nonce, _ := getContext(r, nonceKey).(string)
return nonce
}
func generateNonce(length uint) (string, error) {
b := make([]byte, length)
_, err := rand.Read(b)
if err != nil {
return "", err
}
return base64.StdEncoding.EncodeToString(b), nil
}
func saveContext(r *http.Request, key, value interface{}) *http.Request {
ctx := context.WithValue(r.Context(), key, value)
return r.WithContext(ctx)
}
func getContext(r *http.Request, key interface{}) interface{} {
return r.Context().Value(key)
}

View File

@ -25,11 +25,11 @@ type UserAgentCookieConfig struct {
}
func NewUserAgentHandler(config *UserAgentCookieConfig, idGenerator id.Generator) (*UserAgentHandler, error) {
keys, _, err := crypto.LoadKeys(config.Key)
key, err := crypto.LoadKey(config.Key, config.Key.EncryptionKeyID)
if err != nil {
return nil, err
}
cookieKey := []byte(keys[config.Key.EncryptionKeyID])
cookieKey := []byte(key)
handler := NewCookieHandler(
WithEncryption(cookieKey, cookieKey),
WithDomain(config.Domain),

View File

@ -13,7 +13,7 @@ type AuthRequestRepository interface {
AuthRequestByCode(ctx context.Context, code string) (*model.AuthRequest, error)
SaveAuthCode(ctx context.Context, id, code string) error
DeleteAuthRequest(ctx context.Context, id string) error
CheckUsername(ctx context.Context, id, username string) error
CheckLoginName(ctx context.Context, id, loginName string) error
SelectUser(ctx context.Context, id, userID string) error
VerifyPassword(ctx context.Context, id, userID, password string, info *model.BrowserInfo) error
VerifyMfaOTP(ctx context.Context, agentID, authRequestID string, code string, info *model.BrowserInfo) error

View File

@ -106,16 +106,16 @@ func (repo *AuthRequestRepo) DeleteAuthRequest(ctx context.Context, id string) e
return repo.AuthRequests.DeleteAuthRequest(ctx, id)
}
func (repo *AuthRequestRepo) CheckUsername(ctx context.Context, id, username string) error {
func (repo *AuthRequestRepo) CheckLoginName(ctx context.Context, id, loginName string) error {
request, err := repo.AuthRequests.GetAuthRequestByID(ctx, id)
if err != nil {
return err
}
user, err := repo.View.UserByLoginName(username)
user, err := repo.View.UserByLoginName(loginName)
if err != nil {
return err
}
request.SetUserInfo(user.ID, user.UserName, user.ResourceOwner)
request.SetUserInfo(user.ID, loginName, user.ResourceOwner)
return repo.AuthRequests.UpdateAuthRequest(ctx, request)
}
@ -128,7 +128,7 @@ func (repo *AuthRequestRepo) SelectUser(ctx context.Context, id, userID string)
if err != nil {
return err
}
request.SetUserInfo(user.ID, user.UserName, user.ResourceOwner)
request.SetUserInfo(user.ID, user.PreferredLoginName, user.ResourceOwner)
return repo.AuthRequests.UpdateAuthRequest(ctx, request)
}
@ -236,7 +236,8 @@ func (repo *AuthRequestRepo) usersForUserSelection(request *model.AuthRequest) (
for i, session := range userSessions {
users[i] = model.UserSelection{
UserID: session.UserID,
UserName: session.UserName,
DisplayName: session.DisplayName,
LoginName: session.LoginName,
UserSessionState: session.State,
}
}

View File

@ -46,8 +46,8 @@ type mockViewUserSession struct {
}
type mockUser struct {
UserID string
UserName string
UserID string
LoginName string
}
func (m *mockViewUserSession) UserSessionByIDs(string, string) (*view_model.UserSessionView, error) {
@ -61,8 +61,8 @@ func (m *mockViewUserSession) UserSessionsByAgentID(string) ([]*view_model.UserS
sessions := make([]*view_model.UserSessionView, len(m.Users))
for i, user := range m.Users {
sessions[i] = &view_model.UserSessionView{
UserID: user.UserID,
UserName: user.UserName,
UserID: user.UserID,
LoginName: user.LoginName,
}
}
return sessions, nil
@ -175,11 +175,11 @@ func TestAuthRequestRepo_nextSteps(t *testing.T) {
Users: []mockUser{
{
"id1",
"username1",
"loginname1",
},
{
"id2",
"username2",
"loginname2",
},
},
},
@ -191,12 +191,12 @@ func TestAuthRequestRepo_nextSteps(t *testing.T) {
&model.SelectUserStep{
Users: []model.UserSelection{
{
UserID: "id1",
UserName: "username1",
UserID: "id1",
LoginName: "loginname1",
},
{
UserID: "id2",
UserName: "username2",
UserID: "id2",
LoginName: "loginname2",
},
},
}},

View File

@ -203,8 +203,8 @@ func (repo *UserRepo) SkipMfaInit(ctx context.Context, userID string) error {
return repo.UserEvents.SkipMfaInit(ctx, userID)
}
func (repo *UserRepo) RequestPasswordReset(ctx context.Context, username string) error {
user, err := repo.View.UserByUsername(username)
func (repo *UserRepo) RequestPasswordReset(ctx context.Context, loginname string) error {
user, err := repo.View.UserByLoginName(loginname)
if err != nil {
return err
}

View File

@ -67,7 +67,8 @@ func (u *UserSession) Process(event *models.Event) (err error) {
}
return u.updateSession(session, event)
case es_model.UserPasswordChanged,
es_model.MfaOtpRemoved:
es_model.MfaOtpRemoved,
es_model.UserProfileChanged:
sessions, err := u.view.UserSessionsByUserID(event.AggregateID)
if err != nil {
return err
@ -91,10 +92,8 @@ func (u *UserSession) OnError(event *models.Event, err error) error {
func (u *UserSession) updateSession(session *view_model.UserSessionView, event *models.Event) error {
session.Sequence = event.Sequence
session.AppendEvent(event)
if session.UserName == "" {
if err := u.fillUserInfo(session, event.AggregateID); err != nil {
return err
}
if err := u.fillUserInfo(session, event.AggregateID); err != nil {
return err
}
return u.view.PutUserSession(session)
}
@ -105,5 +104,7 @@ func (u *UserSession) fillUserInfo(session *view_model.UserSessionView, id strin
return err
}
session.UserName = user.UserName
session.LoginName = user.PreferredLoginName
session.DisplayName = user.DisplayName
return nil
}

View File

@ -24,7 +24,7 @@ type AuthRequest struct {
levelOfAssurance LevelOfAssurance
UserID string
UserName string
LoginName string
UserOrgID string
PossibleSteps []NextStep
PasswordVerified bool
@ -96,8 +96,8 @@ func (a *AuthRequest) WithCurrentInfo(info *BrowserInfo) *AuthRequest {
return a
}
func (a *AuthRequest) SetUserInfo(userID string, userName string, userOrgID string) {
func (a *AuthRequest) SetUserInfo(userID string, loginName string, userOrgID string) {
a.UserID = userID
a.UserName = userName
a.LoginName = loginName
a.UserOrgID = userOrgID
}

View File

@ -43,7 +43,8 @@ func (s *SelectUserStep) Type() NextStepType {
type UserSelection struct {
UserID string
UserName string
DisplayName string
LoginName string
UserSessionState UserSessionState
}

View File

@ -33,6 +33,14 @@ func ReadKeys(path string) (Keys, error) {
return *keys, err
}
func LoadKey(config *KeyConfig, id string) (string, error) {
keys, _, err := LoadKeys(config)
if err != nil {
return "", err
}
return keys[id], nil
}
func LoadKeys(config *KeyConfig) (map[string]string, []string, error) {
if config == nil {
return nil, nil, errors.ThrowInvalidArgument(nil, "CRYPT-dJK8s", "config must not be nil")

View File

@ -36,8 +36,8 @@ func (l *Login) renderChangePassword(w http.ResponseWriter, r *http.Request, aut
errMessage = l.getErrorMessage(r, err)
}
data := userData{
baseData: l.getBaseData(r, authReq, "Change Password", errType, errMessage),
UserName: authReq.UserName,
baseData: l.getBaseData(r, authReq, "Change Password", errType, errMessage),
LoginName: authReq.LoginName,
}
l.renderer.RenderTemplate(w, r, l.renderer.Templates[tmplChangePassword], data, nil)
}
@ -45,8 +45,8 @@ func (l *Login) renderChangePassword(w http.ResponseWriter, r *http.Request, aut
func (l *Login) renderChangePasswordDone(w http.ResponseWriter, r *http.Request, authReq *model.AuthRequest) {
var errType, errMessage string
data := userData{
baseData: l.getBaseData(r, authReq, "Password Change Done", errType, errMessage),
UserName: authReq.UserName,
baseData: l.getBaseData(r, authReq, "Password Change Done", errType, errMessage),
LoginName: authReq.LoginName,
}
l.renderer.RenderTemplate(w, r, l.renderer.Templates[tmplChangePasswordDone], data, nil)
}

View File

@ -72,7 +72,7 @@ func (l *Login) resendPasswordSet(w http.ResponseWriter, r *http.Request, authRe
if authReq != nil {
userOrg = authReq.UserOrgID
}
err := l.authRepo.RequestPasswordReset(setContext(r.Context(), userOrg), authReq.UserName)
err := l.authRepo.RequestPasswordReset(setContext(r.Context(), userOrg), authReq.LoginName)
l.renderInitPassword(w, r, authReq, authReq.UserID, "", err)
}
@ -94,8 +94,8 @@ func (l *Login) renderInitPassword(w http.ResponseWriter, r *http.Request, authR
func (l *Login) renderInitPasswordDone(w http.ResponseWriter, r *http.Request, authReq *model.AuthRequest) {
data := userData{
baseData: l.getBaseData(r, authReq, "Password Init Done", "", ""),
UserName: authReq.UserName,
baseData: l.getBaseData(r, authReq, "Password Init Done", "", ""),
LoginName: authReq.LoginName,
}
l.renderer.RenderTemplate(w, r, l.renderer.Templates[tmplInitPasswordDone], data, nil)
}

View File

@ -93,13 +93,13 @@ func (l *Login) renderInitUser(w http.ResponseWriter, r *http.Request, authReq *
}
func (l *Login) renderInitUserDone(w http.ResponseWriter, r *http.Request, authReq *model.AuthRequest) {
var userName string
var loginName string
if authReq != nil {
userName = authReq.UserName
loginName = authReq.LoginName
}
data := userData{
baseData: l.getBaseData(r, authReq, "User Init Done", "", ""),
UserName: userName,
baseData: l.getBaseData(r, authReq, "User Init Done", "", ""),
LoginName: loginName,
}
l.renderer.RenderTemplate(w, r, l.renderer.Templates[tmplInitUserDone], data, nil)
}

View File

@ -6,12 +6,14 @@ import (
"net/http"
"github.com/caos/logging"
"github.com/gorilla/mux"
"github.com/gorilla/csrf"
"github.com/rakyll/statik/fs"
"golang.org/x/text/language"
"github.com/caos/zitadel/internal/api/auth"
"github.com/caos/zitadel/internal/api/http/middleware"
"github.com/caos/zitadel/internal/auth/repository/eventsourcing"
"github.com/caos/zitadel/internal/crypto"
"github.com/caos/zitadel/internal/form"
_ "github.com/caos/zitadel/internal/login/statik"
@ -19,7 +21,7 @@ import (
type Login struct {
endpoint string
router *mux.Router
router http.Handler
renderer *Renderer
parser *form.Parser
authRepo *eventsourcing.EsRepository
@ -33,6 +35,14 @@ type Config struct {
ZitadelURL string
LanguageCookieName string
DefaultLanguage language.Tag
CSRF CSRF
Cache middleware.CacheConfig
}
type CSRF struct {
CookieName string
Key *crypto.KeyConfig
Development bool
}
const (
@ -47,14 +57,39 @@ func StartLogin(ctx context.Context, config Config, authRepo *eventsourcing.EsRe
authRepo: authRepo,
}
statikFS, err := fs.NewWithNamespace("login")
logging.Log("CONFI-7usEW").OnError(err).Panic("unable to start listener")
logging.Log("CONFI-Ga21f").OnError(err).Panic("unable to create filesystem")
login.router = CreateRouter(login, statikFS)
csrf, err := csrfInterceptor(config.CSRF, login.csrfErrorHandler())
logging.Log("CONFI-dHR2a").OnError(err).Panic("unable to create csrfInterceptor")
cache, err := middleware.DefaultCacheInterceptor(EndpointResources, config.Cache.MaxAge.Duration, config.Cache.SharedMaxAge.Duration)
logging.Log("CONFI-BHq2a").OnError(err).Panic("unable to create cacheInterceptor")
security := middleware.SecurityHeaders(csp(), login.cspErrorHandler)
login.router = CreateRouter(login, statikFS, csrf, cache, security)
login.renderer = CreateRenderer(statikFS, config.LanguageCookieName, config.DefaultLanguage)
login.parser = form.NewParser()
login.Listen(ctx)
}
func csp() *middleware.CSP {
csp := middleware.DefaultSCP
csp.ObjectSrc = middleware.CSPSourceOptsSelf()
csp.StyleSrc = csp.StyleSrc.AddNonce()
csp.ScriptSrc = csp.ScriptSrc.AddNonce()
return &csp
}
func csrfInterceptor(config CSRF, errorHandler http.Handler) (func(http.Handler) http.Handler, error) {
csrfKey, err := crypto.LoadKey(config.Key, config.Key.EncryptionKeyID)
if err != nil {
return nil, err
}
return csrf.Protect([]byte(csrfKey),
csrf.Secure(!config.Development),
csrf.CookieName(config.CookieName),
csrf.ErrorHandler(errorHandler),
), nil
}
func (l *Login) Listen(ctx context.Context) {
if l.endpoint == "" {
l.endpoint = ":80"

View File

@ -10,7 +10,7 @@ const (
)
type loginData struct {
UserName string `schema:"username"`
LoginName string `schema:"loginName"`
}
func (l *Login) handleLogin(w http.ResponseWriter, r *http.Request) {
@ -26,7 +26,7 @@ func (l *Login) handleLogin(w http.ResponseWriter, r *http.Request) {
l.renderNextStep(w, r, authReq)
}
func (l *Login) handleUsername(w http.ResponseWriter, r *http.Request) {
func (l *Login) handleLoginName(w http.ResponseWriter, r *http.Request) {
authSession, err := l.getAuthRequest(r)
if err != nil {
l.renderError(w, r, authSession, err)
@ -35,14 +35,14 @@ func (l *Login) handleUsername(w http.ResponseWriter, r *http.Request) {
l.renderLogin(w, r, authSession, nil)
}
func (l *Login) handleUsernameCheck(w http.ResponseWriter, r *http.Request) {
func (l *Login) handleLoginNameCheck(w http.ResponseWriter, r *http.Request) {
data := new(loginData)
authReq, err := l.getAuthRequestAndParseData(r, data)
if err != nil {
l.renderError(w, r, authReq, err)
return
}
err = l.authRepo.CheckUsername(r.Context(), authReq.ID, data.UserName)
err = l.authRepo.CheckLoginName(r.Context(), authReq.ID, data.LoginName)
if err != nil {
l.renderLogin(w, r, authReq, err)
return
@ -56,8 +56,8 @@ func (l *Login) renderLogin(w http.ResponseWriter, r *http.Request, authReq *mod
errMessage = l.getErrorMessage(r, err)
}
data := userData{
baseData: l.getBaseData(r, authReq, "Login", errType, errMessage),
UserName: authReq.UserName,
baseData: l.getBaseData(r, authReq, "Login", errType, errMessage),
LoginName: authReq.LoginName,
}
l.renderer.RenderTemplate(w, r, l.renderer.Templates[tmplLogin], data, nil)
}

View File

@ -15,6 +15,6 @@ type mfaInitDoneData struct {
func (l *Login) renderMfaInitDone(w http.ResponseWriter, r *http.Request, authReq *model.AuthRequest, data *mfaDoneData) {
var errType, errMessage string
data.baseData = l.getBaseData(r, authReq, "Mfa Init Done", errType, errMessage)
data.UserName = authReq.UserName
data.LoginName = authReq.LoginName
l.renderer.RenderTemplate(w, r, l.renderer.Templates[tmplMfaInitDone], data, nil)
}

View File

@ -4,10 +4,11 @@ import (
"bytes"
"net/http"
"github.com/aaronarduino/goqrsvg"
svg "github.com/ajstarks/svgo"
"github.com/boombuler/barcode/qr"
"github.com/caos/zitadel/internal/auth_request/model"
"github.com/caos/zitadel/internal/qrcode"
)
const (
@ -67,7 +68,7 @@ func (l *Login) renderMfaInitVerify(w http.ResponseWriter, r *http.Request, auth
errMessage = l.getErrorMessage(r, err)
}
data.baseData = l.getBaseData(r, authReq, "Mfa Init Verify", errType, errMessage)
data.UserName = authReq.UserName
data.LoginName = authReq.LoginName
if data.MfaType == model.MfaTypeOTP {
code, err := generateQrCode(data.otpData.Url)
if err == nil {
@ -86,7 +87,7 @@ func generateQrCode(url string) (string, error) {
if err != nil {
return "", err
}
qs := goqrsvg.NewQrSVG(qrCode, 5)
qs := qrcode.NewQrSVG(qrCode, 5)
qs.StartQrSVG(s)
qs.WriteQrSVG(s)

View File

@ -42,8 +42,8 @@ func (l *Login) renderMfaPrompt(w http.ResponseWriter, r *http.Request, authSess
errMessage = l.getErrorMessage(r, err)
}
data := mfaData{
baseData: l.getBaseData(r, authSession, "Mfa Prompt", errType, errMessage),
UserName: authSession.UserName,
baseData: l.getBaseData(r, authSession, "Mfa Prompt", errType, errMessage),
LoginName: authSession.LoginName,
}
if mfaPromptData == nil {

View File

@ -38,8 +38,8 @@ func (l *Login) renderMfaVerify(w http.ResponseWriter, r *http.Request, authReq
errMessage = l.getErrorMessage(r, err)
}
data := userData{
baseData: l.getBaseData(r, authReq, "Mfa Verify", errType, errMessage),
UserName: authReq.UserName,
baseData: l.getBaseData(r, authReq, "Mfa Verify", errType, errMessage),
LoginName: authReq.LoginName,
}
if verificationStep != nil {
data.MfaProviders = verificationStep.MfaProviders

View File

@ -20,8 +20,8 @@ func (l *Login) renderPassword(w http.ResponseWriter, r *http.Request, authReq *
errMessage = l.getErrorMessage(r, err)
}
data := userData{
baseData: l.getBaseData(r, authReq, "Password", errType, errMessage),
UserName: authReq.UserName,
baseData: l.getBaseData(r, authReq, "Password", errType, errMessage),
LoginName: authReq.LoginName,
}
l.renderer.RenderTemplate(w, r, l.renderer.Templates[tmplPassword], data, nil)
}

View File

@ -15,7 +15,7 @@ func (l *Login) handlePasswordReset(w http.ResponseWriter, r *http.Request) {
l.renderError(w, r, authReq, err)
return
}
err = l.authRepo.RequestPasswordReset(setContext(r.Context(), authReq.UserOrgID), authReq.UserName)
err = l.authRepo.RequestPasswordReset(setContext(r.Context(), authReq.UserOrgID), authReq.LoginName)
l.renderPasswordResetDone(w, r, authReq, err)
}
@ -25,8 +25,8 @@ func (l *Login) renderPasswordResetDone(w http.ResponseWriter, r *http.Request,
errMessage = l.getErrorMessage(r, err)
}
data := userData{
baseData: l.getBaseData(r, authReq, "Password Reset Done", errType, errMessage),
UserName: authReq.UserName,
baseData: l.getBaseData(r, authReq, "Password Reset Done", errType, errMessage),
LoginName: authReq.LoginName,
}
l.renderer.RenderTemplate(w, r, l.renderer.Templates[tmplPasswordResetDone], data, nil)
}

View File

@ -71,7 +71,7 @@ func (l *Login) handleRegisterCheck(w http.ResponseWriter, r *http.Request) {
http.Redirect(w, r, l.zitadelURL, http.StatusFound)
return
}
authRequest.UserName = user.UserName
authRequest.LoginName = user.PreferredLoginName
l.renderNextStep(w, r, authRequest)
}

View File

@ -3,6 +3,11 @@ package handler
import (
"errors"
"fmt"
"html/template"
"github.com/gorilla/csrf"
"github.com/caos/zitadel/internal/api/http/middleware"
"github.com/caos/zitadel/internal/auth_request/model"
caos_errs "github.com/caos/zitadel/internal/errors"
"github.com/caos/zitadel/internal/i18n"
@ -58,11 +63,11 @@ func CreateRenderer(staticDir http.FileSystem, cookieName string, defaultLanguag
"registerUrl": func(id string) string {
return fmt.Sprintf("%s?%s=%s", EndpointRegister, queryAuthRequestID, id)
},
"usernameUrl": func() string {
return EndpointUsername
"loginNameUrl": func() string {
return EndpointLoginName
},
"usernameChangeUrl": func(id string) string {
return fmt.Sprintf("%s?%s=%s", EndpointUsername, queryAuthRequestID, id)
"loginNameChangeUrl": func(id string) string {
return fmt.Sprintf("%s?%s=%s", EndpointLoginName, queryAuthRequestID, id)
},
"userSelectionUrl": func() string {
return EndpointUserSelection
@ -189,6 +194,8 @@ func (l *Login) getBaseData(r *http.Request, authReq *model.AuthRequest, title s
Theme: l.getTheme(r),
ThemeMode: l.getThemeMode(r),
AuthReqID: getRequestID(authReq, r),
CSRF: csrf.TemplateField(r),
Nonce: middleware.GetNonce(r),
}
}
@ -217,6 +224,19 @@ func getRequestID(authReq *model.AuthRequest, r *http.Request) string {
return r.FormValue(queryAuthRequestID)
}
func (l *Login) csrfErrorHandler() http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
err := csrf.FailureReason(r)
l.renderInternalError(w, r, nil, err)
})
}
func (l *Login) cspErrorHandler(err error) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
l.renderInternalError(w, r, nil, err)
})
}
type baseData struct {
errorData
Lang string
@ -224,6 +244,8 @@ type baseData struct {
Theme string
ThemeMode string
AuthReqID string
CSRF template.HTML
Nonce string
}
type errorData struct {
@ -233,7 +255,7 @@ type errorData struct {
type userData struct {
baseData
UserName string
LoginName string
PasswordChecked string
MfaProviders []model.MfaType
SelectedMfaProvider model.MfaType
@ -246,22 +268,22 @@ type userSelectionData struct {
type mfaData struct {
baseData
UserName string
LoginName string
MfaProviders []model.MfaType
MfaRequired bool
}
type mfaVerifyData struct {
baseData
UserName string
MfaType model.MfaType
LoginName string
MfaType model.MfaType
otpData
}
type mfaDoneData struct {
baseData
UserName string
MfaType model.MfaType
LoginName string
MfaType model.MfaType
}
type otpData struct {

View File

@ -11,7 +11,7 @@ const (
EndpointHealthz = "/healthz"
EndpointReadiness = "/ready"
EndpointLogin = "/login"
EndpointUsername = "/username"
EndpointLoginName = "/loginname"
EndpointUserSelection = "/userselection"
EndpointPassword = "/password"
EndpointInitPassword = "/password/init"
@ -29,14 +29,15 @@ const (
EndpointResources = "/resources"
)
func CreateRouter(login *Login, staticDir http.FileSystem) *mux.Router {
func CreateRouter(login *Login, staticDir http.FileSystem, interceptors ...mux.MiddlewareFunc) *mux.Router {
router := mux.NewRouter()
router.Use(interceptors...)
router.HandleFunc(EndpointRoot, login.handleLogin).Methods(http.MethodGet)
router.HandleFunc(EndpointHealthz, login.handleHealthz).Methods(http.MethodGet)
router.HandleFunc(EndpointReadiness, login.handleReadiness).Methods(http.MethodGet)
router.HandleFunc(EndpointLogin, login.handleLogin).Methods(http.MethodGet, http.MethodPost)
router.HandleFunc(EndpointUsername, login.handleUsername).Methods(http.MethodGet)
router.HandleFunc(EndpointUsername, login.handleUsernameCheck).Methods(http.MethodPost)
router.HandleFunc(EndpointLoginName, login.handleLoginName).Methods(http.MethodGet)
router.HandleFunc(EndpointLoginName, login.handleLoginNameCheck).Methods(http.MethodPost)
router.HandleFunc(EndpointUserSelection, login.handleSelectUser).Methods(http.MethodPost)
router.HandleFunc(EndpointPassword, login.handlePasswordCheck).Methods(http.MethodPost)
router.HandleFunc(EndpointInitPassword, login.handleInitPassword).Methods(http.MethodGet)

View File

@ -6,7 +6,6 @@ Password:
Login:
Title: Anmeldung
Description: Gib deine Benutzerdaten ein.
Username: Benutzername
Loginname: Loginname
LoginnamePlaceHolder: username@domain

View File

@ -1,7 +1,6 @@
Login:
Title: Login
Description: Enter your logindata.
Username: Username
Loginname: Loginname
LoginnamePlaceHolder: username@domain
@ -91,7 +90,7 @@ EmailVerificationDone:
Registration:
Title: Registration
Description: Enter your Userdata. Your email address will be used as username.
Description: Enter your Userdata. Your email address will be used as loginname.
Email: E-Mail
Firstname: Firstname
Lastname: Lastname

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

View File

@ -0,0 +1,6 @@
const copyToClipboard = str => {
navigator.clipboard.writeText(str);
}
let copyButton = document.getElementsByClassName("copy")[0];
copyButton.addEventListener("click", copyToClipboard(copyButton.getAttribute("data-copy").value));

View File

@ -95,7 +95,7 @@ h1 {
}
p {
font-width: 300;
font-weight: 300;
}
header {
@ -151,9 +151,6 @@ button.primary {
button.primary:hover {
background-color: #f60075;
}
button > .sessionstate {
text-transform: lowercase;
}
input:not([type=radio]), select {
background-color: #252525;
@ -200,6 +197,102 @@ form .actions .right {
form .actions button, form .actions a {
margin: 10px 0;
}
form button.clean {
border: none;
height: auto;
color: white;
text-align: left;
text-transform: unset;
display: flex;
padding: 15px;
}
form button.clean:hover {
border: none;
background-color: #252525;
}
form button.clean * {
font-weight: 300;
}
form .user-selection-list {
margin-bottom: 80px;
}
form button.user-selection .profile-image {
width: 100px;
height: 100px;
background-image: url("/resources/images/icon-user-dark.png");
}
@media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min--moz-device-pixel-ratio: 2), only screen and (-o-min-device-pixel-ratio: 2/1), only screen and (min-device-pixel-ratio: 2), only screen and (min-resolution: 192dpi), only screen and (min-resolution: 2dppx) {
form button.user-selection .profile-image {
background-image: url("/resources/images/icon-user-dark@2x.png");
background-size: 100px 100px;
}
}
form button.user-selection:hover .profile-image {
background-image: url("/resources/images/icon-user-dark-hover.png");
}
@media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min--moz-device-pixel-ratio: 2), only screen and (-o-min-device-pixel-ratio: 2/1), only screen and (min-device-pixel-ratio: 2), only screen and (min-resolution: 192dpi), only screen and (min-resolution: 2dppx) {
form button.user-selection:hover .profile-image {
background-image: url("/resources/images/icon-user-dark-hover@2x.png");
background-size: 100px 100px;
}
}
form button.user-selection .sessionstate {
display: inline-block;
height: 20px;
width: 20px;
border-radius: 20px;
border-color: #595959;
border-style: solid;
border-width: 1px;
position: absolute;
bottom: 0px;
right: 10px;
}
form button.user-selection .sessionstate.sessionstate-0 {
background-color: #138D00;
}
form button.user-selection .sessionstate.sessionstate-1 {
background-color: #BC372E;
}
form button.user-selection > div {
position: relative;
}
form button.user-selection > div.names {
margin: 15px;
}
form button.user-selection > div.names .displayname {
font-size: 1.4rem;
}
form button.user-selection > div.names .loginname {
color: #898989;
}
.user-selection + form button.other-user {
margin-top: 80px;
}
form button.other-user .other-user-image {
width: 100px;
height: 75px;
background-image: url("/resources/images/icon-newuser-dark.png");
}
@media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min--moz-device-pixel-ratio: 2), only screen and (-o-min-device-pixel-ratio: 2/1), only screen and (min-device-pixel-ratio: 2), only screen and (min-resolution: 192dpi), only screen and (min-resolution: 2dppx) {
form button.other-user .other-user-image {
background-image: url("/resources/images/icon-newuser-dark@2x.png");
background-size: 100px 75px;
}
}
form button.other-user:hover .other-user-image {
background-image: url("/resources/images/icon-newuser-dark-hover.png");
}
@media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min--moz-device-pixel-ratio: 2), only screen and (-o-min-device-pixel-ratio: 2/1), only screen and (min-device-pixel-ratio: 2), only screen and (min-resolution: 192dpi), only screen and (min-resolution: 2dppx) {
form button.other-user:hover .other-user-image {
background-image: url("/resources/images/icon-newuser-dark-hover@2x.png");
background-size: 100px 75px;
}
}
form button.other-user > div:nth-of-type(2) {
margin: 15px;
font-size: 1.4rem;
}
#copy-secret {
visibility: hidden;
@ -209,11 +302,11 @@ form .actions button, form .actions a {
#qrcode {
text-align: center;
}
#qrcode svg rect[style*="fill:white"] {
fill: #282828 !important;
#qrcode svg rect.color {
fill: white;
}
#qrcode svg rect[style*="fill:black"] {
fill: white !important;
#qrcode svg rect.bg-color {
fill: #282828;
}
#secret .copy {

View File

@ -1 +1 @@
{"version":3,"sourceRoot":"","sources":["../../scss/fonts.scss","../../scss/main.scss","../../scss/caos/variables.scss","../../scss/variables.scss"],"names":[],"mappings":"AACA;EACI;EACA;;AAIJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAIJ;EACI;EACA;EACA;EACA;AAA6D;EAC7D;;AC5EJ;EACI;EACA,aCGW;EDFX;EACA;;;AAGJ;EACI;;;AAGJ;EACI,kBCDc;EDEd,OCDQ;;;ADIZ;EACI,OCLQ;EDMR,aCZS;EDaT;EACA;EACA;;;AAGJ;EACI;;;AAGJ;EACI;;AAEA;EACI;EACA;EACA;EACA;EACA;;;AAIR;EACI;EACA;EACA;EACA;;;AAGJ;EACI,OCnCW;EDoCX;EACA;EACA;;AAEA;EACI,OCxCY;;;AD4CpB;EACI;EACA,kBCjDc;EDkDd,OChDW;EDiDX;EACA;EACA;EACA;EACA,QE/DU;EFgEV;EACA;EACA;;AACA;EACI,kBCzDY;ED0DZ;;AAGJ;EACI,kBC/DO;EDgEP,OCjEI;EDkEJ;;AACA;EACI,kBClEQ;;ADsEhB;EACI;;;AAIR;EACI,kBE7EmB;EF8EnB,OC/EQ;EDgFR,QEzFU;EF0FV;EACA;EACA;;;AAIA;EACI;EACA;;AAGJ;EACI;;AAEA;EACI;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAIR;EACI,OE9GK;EF+GL;EACA;EACA;;AAEA;EACI;EACA;;AAIR;EACI;;AAEA;EACI;;AAGJ;EACI;;;AAKZ;EACI;EACA;;;AAGJ;EACI;;AAEA;EACI;;AAGJ;EACI;;;AAKJ;EACI;EACA;;;AAIR;EACI;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGJ;EACI;EACA;EACA;EACA;AAAkB;EAClB;EACA;EACA;EACA;EACA;EACA;EACA;AAEA;EACA;AACA;EACA;AAEA;EACA;AAEA;EACA","file":"dark.css"}
{"version":3,"sourceRoot":"","sources":["../../scss/fonts.scss","../../scss/main.scss","../../scss/caos/variables.scss","../../scss/variables.scss"],"names":[],"mappings":"AACA;EACI;EACA;;AAIJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAIJ;EACI;EACA;EACA;EACA;AAA6D;EAC7D;;AC5EJ;EACI;EACA,aCGW;EDFX;EACA;;;AAGJ;EACI;;;AAGJ;EACI,kBCDc;EDEd,OCDQ;;;ADIZ;EACI,OCLQ;EDMR,aCZS;EDaT;EACA;EACA;;;AAGJ;EACI;;;AAGJ;EACI;;AAEA;EACI;EACA;EACA;EACA;EACA;;;AAIR;EACI;EACA;EACA;EACA;;;AAGJ;EACI,OCnCW;EDoCX;EACA;EACA;;AAEA;EACI,OCxCY;;;AD4CpB;EACI;EACA,kBCjDc;EDkDd,OChDW;EDiDX;EACA;EACA;EACA;EACA,QE/DU;EFgEV;EACA;EACA;;AACA;EACI,kBCzDY;ED0DZ;;AAGJ;EACI,kBC/DO;EDgEP,OCjEI;EDkEJ;;AACA;EACI,kBClEQ;;;ADuEpB;EACI,kBE5DmB;EF6DnB,OC3EQ;ED4ER,QErFU;EFsFV;EACA;EACA;;;AAIA;EACI;EACA;;AAGJ;EACI;;AAEA;EACI;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAIR;EACI,OE7FK;EF8FL;EACA;EACA;;AAEA;EACI;EACA;;AAIR;EACI;;AAEA;EACI;;AAGJ;EACI;;AAIR;EACI;EACA;EACA,OCnII;EDoIJ;EACA;EACA;EACA;;AAEA;EACI;EACA,kBE7HW;;AFgIf;EACI;;AAIR;EACI;;AAIA;EACI;EACA;EE1JV;;AACA;EFuJM;IEtJJ;IACA;;;AF4JQ;EE/JV;;AACA;EF8JU;IE7JR;IACA;;;AFiKI;EACI;EACA;EACA;EACA;EACA,cE5JO;EF6JP;EACA;EACA;EACA;EACA;;AAEA;EACI;;AAGJ;EACI;;AAKR;EACI;;AAEA;EACI;;AAEA;EACI;;AAEJ;EACI,OExLP;;AF+LL;EACI;;AAEJ;EACI;EACA;EEhNV;;AACA;EF6MM;IE5MJ;IACA;;;AFkNQ;EErNV;;AACA;EFoNU;IEnNR;IACA;;;AFuNI;EACI;EACA;;;AAKZ;EACI;EACA;;;AAGJ;EACI;;AAEA;EACI,MC1OI;;AD6OR;EACI,MC/OU;;;ADoPd;EACI;EACA;;;AAIR;EACI;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGJ;EACI;EACA;EACA;EACA;AAAkB;EAClB;EACA;EACA;EACA;EACA;EACA;EACA;AAEA;EACA;AACA;EACA;AAEA;EACA;AAEA;EACA","file":"dark.css"}

View File

@ -95,7 +95,7 @@ h1 {
}
p {
font-width: 300;
font-weight: 300;
}
header {
@ -151,9 +151,6 @@ button.primary {
button.primary:hover {
background-color: #f60075;
}
button > .sessionstate {
text-transform: lowercase;
}
input:not([type=radio]), select {
background-color: #252525;
@ -200,6 +197,102 @@ form .actions .right {
form .actions button, form .actions a {
margin: 10px 0;
}
form button.clean {
border: none;
height: auto;
color: white;
text-align: left;
text-transform: unset;
display: flex;
padding: 15px;
}
form button.clean:hover {
border: none;
background-color: #252525;
}
form button.clean * {
font-weight: 300;
}
form .user-selection-list {
margin-bottom: 80px;
}
form button.user-selection .profile-image {
width: 100px;
height: 100px;
background-image: url("/resources/images/icon-user-dark.png");
}
@media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min--moz-device-pixel-ratio: 2), only screen and (-o-min-device-pixel-ratio: 2/1), only screen and (min-device-pixel-ratio: 2), only screen and (min-resolution: 192dpi), only screen and (min-resolution: 2dppx) {
form button.user-selection .profile-image {
background-image: url("/resources/images/icon-user-dark@2x.png");
background-size: 100px 100px;
}
}
form button.user-selection:hover .profile-image {
background-image: url("/resources/images/icon-user-dark-hover.png");
}
@media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min--moz-device-pixel-ratio: 2), only screen and (-o-min-device-pixel-ratio: 2/1), only screen and (min-device-pixel-ratio: 2), only screen and (min-resolution: 192dpi), only screen and (min-resolution: 2dppx) {
form button.user-selection:hover .profile-image {
background-image: url("/resources/images/icon-user-dark-hover@2x.png");
background-size: 100px 100px;
}
}
form button.user-selection .sessionstate {
display: inline-block;
height: 20px;
width: 20px;
border-radius: 20px;
border-color: #595959;
border-style: solid;
border-width: 1px;
position: absolute;
bottom: 0px;
right: 10px;
}
form button.user-selection .sessionstate.sessionstate-0 {
background-color: #138D00;
}
form button.user-selection .sessionstate.sessionstate-1 {
background-color: #BC372E;
}
form button.user-selection > div {
position: relative;
}
form button.user-selection > div.names {
margin: 15px;
}
form button.user-selection > div.names .displayname {
font-size: 1.4rem;
}
form button.user-selection > div.names .loginname {
color: #898989;
}
.user-selection + form button.other-user {
margin-top: 80px;
}
form button.other-user .other-user-image {
width: 100px;
height: 75px;
background-image: url("/resources/images/icon-newuser-dark.png");
}
@media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min--moz-device-pixel-ratio: 2), only screen and (-o-min-device-pixel-ratio: 2/1), only screen and (min-device-pixel-ratio: 2), only screen and (min-resolution: 192dpi), only screen and (min-resolution: 2dppx) {
form button.other-user .other-user-image {
background-image: url("/resources/images/icon-newuser-dark@2x.png");
background-size: 100px 75px;
}
}
form button.other-user:hover .other-user-image {
background-image: url("/resources/images/icon-newuser-dark-hover.png");
}
@media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min--moz-device-pixel-ratio: 2), only screen and (-o-min-device-pixel-ratio: 2/1), only screen and (min-device-pixel-ratio: 2), only screen and (min-resolution: 192dpi), only screen and (min-resolution: 2dppx) {
form button.other-user:hover .other-user-image {
background-image: url("/resources/images/icon-newuser-dark-hover@2x.png");
background-size: 100px 75px;
}
}
form button.other-user > div:nth-of-type(2) {
margin: 15px;
font-size: 1.4rem;
}
#copy-secret {
visibility: hidden;
@ -209,11 +302,11 @@ form .actions button, form .actions a {
#qrcode {
text-align: center;
}
#qrcode svg rect[style*="fill:white"] {
fill: #282828 !important;
#qrcode svg rect.color {
fill: white;
}
#qrcode svg rect[style*="fill:black"] {
fill: white !important;
#qrcode svg rect.bg-color {
fill: #282828;
}
#secret .copy {
@ -282,6 +375,48 @@ html button.primary {
html button.primary:hover {
background-color: #f60075;
}
html button.clean {
color: #282828;
}
html button.user-selection .profile-image {
background-image: url("/resources/images/icon-user-light.png");
}
@media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min--moz-device-pixel-ratio: 2), only screen and (-o-min-device-pixel-ratio: 2/1), only screen and (min-device-pixel-ratio: 2), only screen and (min-resolution: 192dpi), only screen and (min-resolution: 2dppx) {
html button.user-selection .profile-image {
background-image: url("/resources/images/icon-user-light@2x.png");
background-size: 100px 100px;
}
}
html button.user-selection:hover {
background-color: #252525;
}
html button.user-selection:hover .profile-image {
background-image: url("/resources/images/icon-user-light-hover.png");
}
@media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min--moz-device-pixel-ratio: 2), only screen and (-o-min-device-pixel-ratio: 2/1), only screen and (min-device-pixel-ratio: 2), only screen and (min-resolution: 192dpi), only screen and (min-resolution: 2dppx) {
html button.user-selection:hover .profile-image {
background-image: url("/resources/images/icon-user-light-hover@2x.png");
background-size: 100px 100px;
}
}
html button.other-user .other-user-image {
background-image: url("/resources/images/icon-newuser-light.png");
}
@media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min--moz-device-pixel-ratio: 2), only screen and (-o-min-device-pixel-ratio: 2/1), only screen and (min-device-pixel-ratio: 2), only screen and (min-resolution: 192dpi), only screen and (min-resolution: 2dppx) {
html button.other-user .other-user-image {
background-image: url("/resources/images/icon-newuser-light@2x.png");
background-size: 100px 75px;
}
}
html button.other-user:hover .other-user-image {
background-image: url("/resources/images/icon-newuser-light-hover.png");
}
@media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min--moz-device-pixel-ratio: 2), only screen and (-o-min-device-pixel-ratio: 2/1), only screen and (min-device-pixel-ratio: 2), only screen and (min-resolution: 192dpi), only screen and (min-resolution: 2dppx) {
html button.other-user:hover .other-user-image {
background-image: url("/resources/images/icon-newuser-light-hover@2x.png");
background-size: 100px 75px;
}
}
html input {
background-color: white;
color: #282828;

View File

@ -1 +1 @@
{"version":3,"sourceRoot":"","sources":["../../scss/fonts.scss","../../scss/main.scss","../../scss/caos/variables.scss","../../scss/variables.scss","../../scss/light.scss"],"names":[],"mappings":"AACA;EACI;EACA;;AAIJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAIJ;EACI;EACA;EACA;EACA;AAA6D;EAC7D;;AC5EJ;EACI;EACA,aCGW;EDFX;EACA;;;AAGJ;EACI;;;AAGJ;EACI,kBCDc;EDEd,OCDQ;;;ADIZ;EACI,OCLQ;EDMR,aCZS;EDaT;EACA;EACA;;;AAGJ;EACI;;;AAGJ;EACI;;AAEA;EACI;EACA;EACA;EACA;EACA;;;AAIR;EACI;EACA;EACA;EACA;;;AAGJ;EACI,OCnCW;EDoCX;EACA;EACA;;AAEA;EACI,OCxCY;;;AD4CpB;EACI;EACA,kBCjDc;EDkDd,OChDW;EDiDX;EACA;EACA;EACA;EACA,QE/DU;EFgEV;EACA;EACA;;AACA;EACI,kBCzDY;ED0DZ;;AAGJ;EACI,kBC/DO;EDgEP,OCjEI;EDkEJ;;AACA;EACI,kBClEQ;;ADsEhB;EACI;;;AAIR;EACI,kBE7EmB;EF8EnB,OC/EQ;EDgFR,QEzFU;EF0FV;EACA;EACA;;;AAIA;EACI;EACA;;AAGJ;EACI;;AAEA;EACI;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAIR;EACI,OE9GK;EF+GL;EACA;EACA;;AAEA;EACI;EACA;;AAIR;EACI;;AAEA;EACI;;AAGJ;EACI;;;AAKZ;EACI;EACA;;;AAGJ;EACI;;AAEA;EACI;;AAGJ;EACI;;;AAKJ;EACI;EACA;;;AAIR;EACI;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGJ;EACI;EACA;EACA;EACA;AAAkB;EAClB;EACA;EACA;EACA;EACA;EACA;EACA;AAEA;EACA;AACA;EACA;AAEA;EACA;AAEA;EACA;;;AG1MJ;EACI,kBFYQ;EEXR,OFUc;;AERd;EACI;;AAGJ;EACI,OFGU;;AEAd;EACI;EACA;EACA;;AAEA;EACI,kBFIa;EEHb;;AAGJ;EACI,kBFTG;EEUH,OFXA;EEYA;EACA;;AACA;EACI,kBFbI;;AEkBhB;EACI,kBFrBI;EEsBJ,OFvBU;;AE2BV;EACI;;AAGJ;EACI;;AAIR;EACI","file":"light.css"}
{"version":3,"sourceRoot":"","sources":["../../scss/fonts.scss","../../scss/main.scss","../../scss/caos/variables.scss","../../scss/variables.scss","../../scss/light.scss"],"names":[],"mappings":"AACA;EACI;EACA;;AAIJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAIJ;EACI;EACA;EACA;EACA;AAA6D;EAC7D;;AC5EJ;EACI;EACA,aCGW;EDFX;EACA;;;AAGJ;EACI;;;AAGJ;EACI,kBCDc;EDEd,OCDQ;;;ADIZ;EACI,OCLQ;EDMR,aCZS;EDaT;EACA;EACA;;;AAGJ;EACI;;;AAGJ;EACI;;AAEA;EACI;EACA;EACA;EACA;EACA;;;AAIR;EACI;EACA;EACA;EACA;;;AAGJ;EACI,OCnCW;EDoCX;EACA;EACA;;AAEA;EACI,OCxCY;;;AD4CpB;EACI;EACA,kBCjDc;EDkDd,OChDW;EDiDX;EACA;EACA;EACA;EACA,QE/DU;EFgEV;EACA;EACA;;AACA;EACI,kBCzDY;ED0DZ;;AAGJ;EACI,kBC/DO;EDgEP,OCjEI;EDkEJ;;AACA;EACI,kBClEQ;;;ADuEpB;EACI,kBE5DmB;EF6DnB,OC3EQ;ED4ER,QErFU;EFsFV;EACA;EACA;;;AAIA;EACI;EACA;;AAGJ;EACI;;AAEA;EACI;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAIR;EACI,OE7FK;EF8FL;EACA;EACA;;AAEA;EACI;EACA;;AAIR;EACI;;AAEA;EACI;;AAGJ;EACI;;AAIR;EACI;EACA;EACA,OCnII;EDoIJ;EACA;EACA;EACA;;AAEA;EACI;EACA,kBE7HW;;AFgIf;EACI;;AAIR;EACI;;AAIA;EACI;EACA;EE1JV;;AACA;EFuJM;IEtJJ;IACA;;;AF4JQ;EE/JV;;AACA;EF8JU;IE7JR;IACA;;;AFiKI;EACI;EACA;EACA;EACA;EACA,cE5JO;EF6JP;EACA;EACA;EACA;EACA;;AAEA;EACI;;AAGJ;EACI;;AAKR;EACI;;AAEA;EACI;;AAEA;EACI;;AAEJ;EACI,OExLP;;AF+LL;EACI;;AAEJ;EACI;EACA;EEhNV;;AACA;EF6MM;IE5MJ;IACA;;;AFkNQ;EErNV;;AACA;EFoNU;IEnNR;IACA;;;AFuNI;EACI;EACA;;;AAKZ;EACI;EACA;;;AAGJ;EACI;;AAEA;EACI,MC1OI;;AD6OR;EACI,MC/OU;;;ADoPd;EACI;EACA;;;AAIR;EACI;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGJ;EACI;EACA;EACA;EACA;AAAkB;EAClB;EACA;EACA;EACA;EACA;EACA;EACA;AAEA;EACA;AACA;EACA;AAEA;EACA;AAEA;EACA;;;AGtSJ;EACI,kBFYQ;EEXR,OFUc;;AERd;EACI;;AAGJ;EACI,OFGU;;AEAd;EACI;EACA;EACA;;AAEA;EACI,kBFIa;EEHb;;AAGJ;EACI,kBFTG;EEUH,OFXA;EEYA;EACA;;AACA;EACI,kBFbI;;AEiBZ;EACI,OFrBM;;AEyBN;EDxBV;;AACA;ECuBU;IDtBR;IACA;;;ACyBQ;EACI,kBDfO;;ACiBP;ED/Bd;;AACA;EC8Bc;ID7BZ;IACA;;;ACmCQ;EDtCV;;AACA;ECqCU;IDpCR;IACA;;;ACwCY;ED3Cd;;AACA;EC0Cc;IDzCZ;IACA;;;AC+CA;EACI,kBFnDI;EEoDJ,OFrDU;;AEyDV;EACI;;AAGJ;EACI;;AAIR;EACI","file":"light.css"}

View File

@ -30,6 +30,36 @@ html {
background-color: $primaryColorHover;
}
}
&.clean {
color: $fontColorLight;
}
&.user-selection {
.profile-image {
@include retina-background-image($profileImgLight, "png", false, 100px, 100px);
}
&:hover {
background-color: $buttonBackgroundColorHover;
.profile-image {
@include retina-background-image($profileImgLight, "png", true, 100px, 100px);
}
}
}
&.other-user {
.other-user-image {
@include retina-background-image($otherUserImgLight, "png", false, 100px, 75px);
}
&:hover {
.other-user-image {
@include retina-background-image($otherUserImgLight, "png", true, 100px, 75px);
}
}
}
}
input {

View File

@ -25,7 +25,7 @@ h1 {
}
p {
font-width: 300;
font-weight: 300;
}
header {
@ -83,10 +83,6 @@ button {
background-color: $primaryColorHover;
}
}
& > .sessionstate {
text-transform: lowercase;
}
}
input:not([type='radio']), select {
@ -143,6 +139,102 @@ form {
margin: 10px 0;
}
}
button.clean {
border: none;
height: auto;
color: $fontColor;
text-align: left;
text-transform: unset;
display: flex;
padding: 15px;
&:hover {
border: none;
background-color: $buttonBackgroundColorHover;
}
* {
font-weight: 300;
}
}
.user-selection-list {
margin-bottom: 80px;
}
button.user-selection {
.profile-image {
width: 100px;
height: 100px;
@include retina-background-image($profileImgDark, "png", false, 100px, 100px);
}
&:hover {
.profile-image {
@include retina-background-image($profileImgDark, "png", true, 100px, 100px);
}
}
.sessionstate {
display: inline-block;
height: 20px;
width: 20px;
border-radius: 20px;
border-color: $inputBorderColor;
border-style: solid;
border-width: 1px;
position: absolute;
bottom: 0px;
right: 10px;
&.sessionstate-0 {
background-color: #138D00;
}
&.sessionstate-1 {
background-color: #BC372E;
}
}
& > div {
position: relative;
&.names {
margin: 15px;
.displayname {
font-size: 1.4rem;
}
.loginname {
color: $labelColor;
}
}
}
}
button.other-user {
.user-selection+&{
margin-top: 80px;
}
.other-user-image {
width: 100px;
height: 75px;
@include retina-background-image($otherUserImgDark, "png", false, 100px, 75px);
}
&:hover {
.other-user-image {
@include retina-background-image($otherUserImgDark, "png", true, 100px, 75px);
}
}
& > div:nth-of-type(2) {
margin: 15px;
font-size: 1.4rem;
}
}
}
#copy-secret {
@ -153,12 +245,12 @@ form {
#qrcode {
text-align: center;
svg rect[style*="fill:white"] {
fill: $backgroundColor !important;
svg rect.color {
fill: $fontColor;
}
svg rect[style*="fill:black"] {
fill: $fontColor !important;
svg rect.bg-color {
fill: $backgroundColor;
}
}

View File

@ -4,7 +4,20 @@ $headerFont: Aileron;
// ----- LAYOUT ------------
$inputHeight: 50px;
$retina: "only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min--moz-device-pixel-ratio: 2), only screen and (-o-min-device-pixel-ratio: 2/1), only screen and (min-device-pixel-ratio: 2), only screen and (min-resolution: 192dpi), only screen and (min-resolution: 2dppx)";
@mixin retina-background-image($file, $type, $hover, $width, $height) {
$hovername: '';
@if $hover {
$hovername: '-hover';
}
$filename :$file + $hovername;
background-image: url($filename + '.' + $type);
@media #{$retina} {
background-image: url($filename + '@2x.' + $type);
background-size: $width $height;
}
}
// ----- DARK-THEME --------
$backgroundColor: #282828;
@ -14,6 +27,9 @@ $primaryColorHover: lighten($primaryColor, 10%);
$labelColor: #898989;
$inputBorderColor: #595959;
$inputBackgroundColor: #252525;
$buttonBackgroundColorHover: $inputBackgroundColor;
$profileImgDark: "/resources/images/icon-user-dark";
$otherUserImgDark: "/resources/images/icon-newuser-dark";
// ----- LIGHT-THEME --------
@ -21,3 +37,6 @@ $backgroundColorLight: $fontColor;
$fontColorLight: $backgroundColor;
$primaryColorLight: $primaryColor;
$primaryColorHoverLight: lighten($primaryColorLight, 10%);
$buttonBackgroundColorHoverLight: #EFEFEF;
$profileImgLight: "/resources/images/icon-user-light";
$otherUserImgLight: "/resources/images/icon-newuser-light";

View File

@ -95,7 +95,7 @@ h1 {
}
p {
font-width: 300;
font-weight: 300;
}
header {
@ -151,9 +151,6 @@ button.primary {
button.primary:hover {
background-color: #6778f8;
}
button > .sessionstate {
text-transform: lowercase;
}
input:not([type=radio]), select {
background-color: #252525;
@ -200,6 +197,102 @@ form .actions .right {
form .actions button, form .actions a {
margin: 10px 0;
}
form button.clean {
border: none;
height: auto;
color: #FFFFFF;
text-align: left;
text-transform: unset;
display: flex;
padding: 15px;
}
form button.clean:hover {
border: none;
background-color: #252525;
}
form button.clean * {
font-weight: 300;
}
form .user-selection-list {
margin-bottom: 80px;
}
form button.user-selection .profile-image {
width: 100px;
height: 100px;
background-image: url("/resources/images/icon-user-dark.png");
}
@media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min--moz-device-pixel-ratio: 2), only screen and (-o-min-device-pixel-ratio: 2/1), only screen and (min-device-pixel-ratio: 2), only screen and (min-resolution: 192dpi), only screen and (min-resolution: 2dppx) {
form button.user-selection .profile-image {
background-image: url("/resources/images/icon-user-dark@2x.png");
background-size: 100px 100px;
}
}
form button.user-selection:hover .profile-image {
background-image: url("/resources/images/icon-user-dark-hover.png");
}
@media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min--moz-device-pixel-ratio: 2), only screen and (-o-min-device-pixel-ratio: 2/1), only screen and (min-device-pixel-ratio: 2), only screen and (min-resolution: 192dpi), only screen and (min-resolution: 2dppx) {
form button.user-selection:hover .profile-image {
background-image: url("/resources/images/icon-user-dark-hover@2x.png");
background-size: 100px 100px;
}
}
form button.user-selection .sessionstate {
display: inline-block;
height: 20px;
width: 20px;
border-radius: 20px;
border-color: #595959;
border-style: solid;
border-width: 1px;
position: absolute;
bottom: 0px;
right: 10px;
}
form button.user-selection .sessionstate.sessionstate-0 {
background-color: #138D00;
}
form button.user-selection .sessionstate.sessionstate-1 {
background-color: #BC372E;
}
form button.user-selection > div {
position: relative;
}
form button.user-selection > div.names {
margin: 15px;
}
form button.user-selection > div.names .displayname {
font-size: 1.4rem;
}
form button.user-selection > div.names .loginname {
color: #898989;
}
.user-selection + form button.other-user {
margin-top: 80px;
}
form button.other-user .other-user-image {
width: 100px;
height: 75px;
background-image: url("/resources/images/icon-newuser-dark.png");
}
@media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min--moz-device-pixel-ratio: 2), only screen and (-o-min-device-pixel-ratio: 2/1), only screen and (min-device-pixel-ratio: 2), only screen and (min-resolution: 192dpi), only screen and (min-resolution: 2dppx) {
form button.other-user .other-user-image {
background-image: url("/resources/images/icon-newuser-dark@2x.png");
background-size: 100px 75px;
}
}
form button.other-user:hover .other-user-image {
background-image: url("/resources/images/icon-newuser-dark-hover.png");
}
@media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min--moz-device-pixel-ratio: 2), only screen and (-o-min-device-pixel-ratio: 2/1), only screen and (min-device-pixel-ratio: 2), only screen and (min-resolution: 192dpi), only screen and (min-resolution: 2dppx) {
form button.other-user:hover .other-user-image {
background-image: url("/resources/images/icon-newuser-dark-hover@2x.png");
background-size: 100px 75px;
}
}
form button.other-user > div:nth-of-type(2) {
margin: 15px;
font-size: 1.4rem;
}
#copy-secret {
visibility: hidden;
@ -209,11 +302,11 @@ form .actions button, form .actions a {
#qrcode {
text-align: center;
}
#qrcode svg rect[style*="fill:white"] {
fill: #282828 !important;
#qrcode svg rect.color {
fill: #FFFFFF;
}
#qrcode svg rect[style*="fill:black"] {
fill: #FFFFFF !important;
#qrcode svg rect.bg-color {
fill: #282828;
}
#secret .copy {

View File

@ -1 +1 @@
{"version":3,"sourceRoot":"","sources":["../../scss/fonts.scss","../../scss/main.scss","../../scss/variables.scss"],"names":[],"mappings":"AACA;EACI;EACA;;AAIJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAIJ;EACI;EACA;EACA;EACA;AAA6D;EAC7D;;AC5EJ;EACI;EACA,aCHW;EDIX;EACA;;;AAGJ;EACI;;;AAGJ;EACI,kBCLc;EDMd,OCLQ;;;ADQZ;EACI,OCTQ;EDUR,aClBS;EDmBT;EACA;EACA;;;AAGJ;EACI;;;AAGJ;EACI;;AAEA;EACI;EACA;EACA;EACA;EACA;;;AAIR;EACI;EACA;EACA;EACA;;;AAGJ;EACI,OCvCW;EDwCX;EACA;EACA;;AAEA;EACI,OC5CY;;;ADgDpB;EACI;EACA,kBCrDc;EDsDd,OCpDW;EDqDX;EACA;EACA;EACA;EACA,QC/DU;EDgEV;EACA;EACA;;AACA;EACI,kBC7DY;ED8DZ;;AAGJ;EACI,kBCnEO;EDoEP,OCrEI;EDsEJ;;AACA;EACI,kBCtEQ;;AD0EhB;EACI;;;AAIR;EACI,kBC7EmB;ED8EnB,OCnFQ;EDoFR,QCzFU;ED0FV;EACA;EACA;;;AAIA;EACI;EACA;;AAGJ;EACI;;AAEA;EACI;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAIR;EACI,OC9GK;ED+GL;EACA;EACA;;AAEA;EACI;EACA;;AAIR;EACI;;AAEA;EACI;;AAGJ;EACI;;;AAKZ;EACI;EACA;;;AAGJ;EACI;;AAEA;EACI;;AAGJ;EACI;;;AAKJ;EACI;EACA;;;AAIR;EACI;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGJ;EACI;EACA;EACA;EACA;AAAkB;EAClB;EACA;EACA;EACA;EACA;EACA;EACA;AAEA;EACA;AACA;EACA;AAEA;EACA;AAEA;EACA","file":"dark.css"}
{"version":3,"sourceRoot":"","sources":["../../scss/fonts.scss","../../scss/main.scss","../../scss/variables.scss"],"names":[],"mappings":"AACA;EACI;EACA;;AAIJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAIJ;EACI;EACA;EACA;EACA;AAA6D;EAC7D;;AC5EJ;EACI;EACA,aCHW;EDIX;EACA;;;AAGJ;EACI;;;AAGJ;EACI,kBCQc;EDPd,OCQQ;;;ADLZ;EACI,OCIQ;EDHR,aClBS;EDmBT;EACA;EACA;;;AAGJ;EACI;;;AAGJ;EACI;;AAEA;EACI;EACA;EACA;EACA;EACA;;;AAIR;EACI;EACA;EACA;EACA;;;AAGJ;EACI,OC1BW;ED2BX;EACA;EACA;;AAEA;EACI,OC/BY;;;ADmCpB;EACI;EACA,kBCxCc;EDyCd,OCvCW;EDwCX;EACA;EACA;EACA;EACA,QC/DU;EDgEV;EACA;EACA;;AACA;EACI,kBChDY;EDiDZ;;AAGJ;EACI,kBCtDO;EDuDP,OCxDI;EDyDJ;;AACA;EACI,kBCzDQ;;;AD8DpB;EACI,kBC5DmB;ED6DnB,OClEQ;EDmER,QCrFU;EDsFV;EACA;EACA;;;AAIA;EACI;EACA;;AAGJ;EACI;;AAEA;EACI;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAIR;EACI,OC7FK;ED8FL;EACA;EACA;;AAEA;EACI;EACA;;AAIR;EACI;;AAEA;EACI;;AAGJ;EACI;;AAIR;EACI;EACA;EACA,OC1HI;ED2HJ;EACA;EACA;EACA;;AAEA;EACI;EACA,kBC7HW;;ADgIf;EACI;;AAIR;EACI;;AAIA;EACI;EACA;EC1JV;;AACA;EDuJM;ICtJJ;IACA;;;AD4JQ;EC/JV;;AACA;ED8JU;IC7JR;IACA;;;ADiKI;EACI;EACA;EACA;EACA;EACA,cC5JO;ED6JP;EACA;EACA;EACA;EACA;;AAEA;EACI;;AAGJ;EACI;;AAKR;EACI;;AAEA;EACI;;AAEA;EACI;;AAEJ;EACI,OCxLP;;AD+LL;EACI;;AAEJ;EACI;EACA;EChNV;;AACA;ED6MM;IC5MJ;IACA;;;ADkNQ;ECrNV;;AACA;EDoNU;ICnNR;IACA;;;ADuNI;EACI;EACA;;;AAKZ;EACI;EACA;;;AAGJ;EACI;;AAEA;EACI,MCjOI;;ADoOR;EACI,MCtOU;;;AD2Od;EACI;EACA;;;AAIR;EACI;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGJ;EACI;EACA;EACA;EACA;AAAkB;EAClB;EACA;EACA;EACA;EACA;EACA;EACA;AAEA;EACA;AACA;EACA;AAEA;EACA;AAEA;EACA","file":"dark.css"}

View File

@ -95,7 +95,7 @@ h1 {
}
p {
font-width: 300;
font-weight: 300;
}
header {
@ -151,9 +151,6 @@ button.primary {
button.primary:hover {
background-color: #6778f8;
}
button > .sessionstate {
text-transform: lowercase;
}
input:not([type=radio]), select {
background-color: #252525;
@ -200,6 +197,102 @@ form .actions .right {
form .actions button, form .actions a {
margin: 10px 0;
}
form button.clean {
border: none;
height: auto;
color: #FFFFFF;
text-align: left;
text-transform: unset;
display: flex;
padding: 15px;
}
form button.clean:hover {
border: none;
background-color: #252525;
}
form button.clean * {
font-weight: 300;
}
form .user-selection-list {
margin-bottom: 80px;
}
form button.user-selection .profile-image {
width: 100px;
height: 100px;
background-image: url("/resources/images/icon-user-dark.png");
}
@media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min--moz-device-pixel-ratio: 2), only screen and (-o-min-device-pixel-ratio: 2/1), only screen and (min-device-pixel-ratio: 2), only screen and (min-resolution: 192dpi), only screen and (min-resolution: 2dppx) {
form button.user-selection .profile-image {
background-image: url("/resources/images/icon-user-dark@2x.png");
background-size: 100px 100px;
}
}
form button.user-selection:hover .profile-image {
background-image: url("/resources/images/icon-user-dark-hover.png");
}
@media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min--moz-device-pixel-ratio: 2), only screen and (-o-min-device-pixel-ratio: 2/1), only screen and (min-device-pixel-ratio: 2), only screen and (min-resolution: 192dpi), only screen and (min-resolution: 2dppx) {
form button.user-selection:hover .profile-image {
background-image: url("/resources/images/icon-user-dark-hover@2x.png");
background-size: 100px 100px;
}
}
form button.user-selection .sessionstate {
display: inline-block;
height: 20px;
width: 20px;
border-radius: 20px;
border-color: #595959;
border-style: solid;
border-width: 1px;
position: absolute;
bottom: 0px;
right: 10px;
}
form button.user-selection .sessionstate.sessionstate-0 {
background-color: #138D00;
}
form button.user-selection .sessionstate.sessionstate-1 {
background-color: #BC372E;
}
form button.user-selection > div {
position: relative;
}
form button.user-selection > div.names {
margin: 15px;
}
form button.user-selection > div.names .displayname {
font-size: 1.4rem;
}
form button.user-selection > div.names .loginname {
color: #898989;
}
.user-selection + form button.other-user {
margin-top: 80px;
}
form button.other-user .other-user-image {
width: 100px;
height: 75px;
background-image: url("/resources/images/icon-newuser-dark.png");
}
@media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min--moz-device-pixel-ratio: 2), only screen and (-o-min-device-pixel-ratio: 2/1), only screen and (min-device-pixel-ratio: 2), only screen and (min-resolution: 192dpi), only screen and (min-resolution: 2dppx) {
form button.other-user .other-user-image {
background-image: url("/resources/images/icon-newuser-dark@2x.png");
background-size: 100px 75px;
}
}
form button.other-user:hover .other-user-image {
background-image: url("/resources/images/icon-newuser-dark-hover.png");
}
@media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min--moz-device-pixel-ratio: 2), only screen and (-o-min-device-pixel-ratio: 2/1), only screen and (min-device-pixel-ratio: 2), only screen and (min-resolution: 192dpi), only screen and (min-resolution: 2dppx) {
form button.other-user:hover .other-user-image {
background-image: url("/resources/images/icon-newuser-dark-hover@2x.png");
background-size: 100px 75px;
}
}
form button.other-user > div:nth-of-type(2) {
margin: 15px;
font-size: 1.4rem;
}
#copy-secret {
visibility: hidden;
@ -209,11 +302,11 @@ form .actions button, form .actions a {
#qrcode {
text-align: center;
}
#qrcode svg rect[style*="fill:white"] {
fill: #282828 !important;
#qrcode svg rect.color {
fill: #FFFFFF;
}
#qrcode svg rect[style*="fill:black"] {
fill: #FFFFFF !important;
#qrcode svg rect.bg-color {
fill: #282828;
}
#secret .copy {
@ -282,6 +375,48 @@ html button.primary {
html button.primary:hover {
background-color: #6778f8;
}
html button.clean {
color: #282828;
}
html button.user-selection .profile-image {
background-image: url("/resources/images/icon-user-light.png");
}
@media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min--moz-device-pixel-ratio: 2), only screen and (-o-min-device-pixel-ratio: 2/1), only screen and (min-device-pixel-ratio: 2), only screen and (min-resolution: 192dpi), only screen and (min-resolution: 2dppx) {
html button.user-selection .profile-image {
background-image: url("/resources/images/icon-user-light@2x.png");
background-size: 100px 100px;
}
}
html button.user-selection:hover {
background-color: #252525;
}
html button.user-selection:hover .profile-image {
background-image: url("/resources/images/icon-user-light-hover.png");
}
@media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min--moz-device-pixel-ratio: 2), only screen and (-o-min-device-pixel-ratio: 2/1), only screen and (min-device-pixel-ratio: 2), only screen and (min-resolution: 192dpi), only screen and (min-resolution: 2dppx) {
html button.user-selection:hover .profile-image {
background-image: url("/resources/images/icon-user-light-hover@2x.png");
background-size: 100px 100px;
}
}
html button.other-user .other-user-image {
background-image: url("/resources/images/icon-newuser-light.png");
}
@media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min--moz-device-pixel-ratio: 2), only screen and (-o-min-device-pixel-ratio: 2/1), only screen and (min-device-pixel-ratio: 2), only screen and (min-resolution: 192dpi), only screen and (min-resolution: 2dppx) {
html button.other-user .other-user-image {
background-image: url("/resources/images/icon-newuser-light@2x.png");
background-size: 100px 75px;
}
}
html button.other-user:hover .other-user-image {
background-image: url("/resources/images/icon-newuser-light-hover.png");
}
@media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min--moz-device-pixel-ratio: 2), only screen and (-o-min-device-pixel-ratio: 2/1), only screen and (min-device-pixel-ratio: 2), only screen and (min-resolution: 192dpi), only screen and (min-resolution: 2dppx) {
html button.other-user:hover .other-user-image {
background-image: url("/resources/images/icon-newuser-light-hover@2x.png");
background-size: 100px 75px;
}
}
html input {
background-color: #FFFFFF;
color: #282828;

View File

@ -1 +1 @@
{"version":3,"sourceRoot":"","sources":["../../scss/fonts.scss","../../scss/main.scss","../../scss/variables.scss","../../scss/light.scss"],"names":[],"mappings":"AACA;EACI;EACA;;AAIJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAIJ;EACI;EACA;EACA;EACA;AAA6D;EAC7D;;AC5EJ;EACI;EACA,aCHW;EDIX;EACA;;;AAGJ;EACI;;;AAGJ;EACI,kBCLc;EDMd,OCLQ;;;ADQZ;EACI,OCTQ;EDUR,aClBS;EDmBT;EACA;EACA;;;AAGJ;EACI;;;AAGJ;EACI;;AAEA;EACI;EACA;EACA;EACA;EACA;;;AAIR;EACI;EACA;EACA;EACA;;;AAGJ;EACI,OCvCW;EDwCX;EACA;EACA;;AAEA;EACI,OC5CY;;;ADgDpB;EACI;EACA,kBCrDc;EDsDd,OCpDW;EDqDX;EACA;EACA;EACA;EACA,QC/DU;EDgEV;EACA;EACA;;AACA;EACI,kBC7DY;ED8DZ;;AAGJ;EACI,kBCnEO;EDoEP,OCrEI;EDsEJ;;AACA;EACI,kBCtEQ;;AD0EhB;EACI;;;AAIR;EACI,kBC7EmB;ED8EnB,OCnFQ;EDoFR,QCzFU;ED0FV;EACA;EACA;;;AAIA;EACI;EACA;;AAGJ;EACI;;AAEA;EACI;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAIR;EACI,OC9GK;ED+GL;EACA;EACA;;AAEA;EACI;EACA;;AAIR;EACI;;AAEA;EACI;;AAGJ;EACI;;;AAKZ;EACI;EACA;;;AAGJ;EACI;;AAEA;EACI;;AAGJ;EACI;;;AAKJ;EACI;EACA;;;AAIR;EACI;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGJ;EACI;EACA;EACA;EACA;AAAkB;EAClB;EACA;EACA;EACA;EACA;EACA;EACA;AAEA;EACA;AACA;EACA;AAEA;EACA;AAEA;EACA;;;AE1MJ;EACI,kBDQQ;ECPR,ODMc;;ACJd;EACI;;AAGJ;EACI,ODDU;;ACId;EACI,kBDJI;ECKJ,ODJO;ECKP;;AAEA;EACI,kBDGa;ECFb;;AAGJ;EACI,kBDbG;ECcH,ODfA;ECgBA;EACA;;AACA;EACI,kBDjBI;;ACsBhB;EACI,kBDzBI;EC0BJ,OD3BU;;AC+BV;EACI;;AAGJ;EACI;;AAIR;EACI","file":"light.css"}
{"version":3,"sourceRoot":"","sources":["../../scss/fonts.scss","../../scss/main.scss","../../scss/variables.scss","../../scss/light.scss"],"names":[],"mappings":"AACA;EACI;EACA;;AAIJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;;AAIJ;EACI;EACA;EACA;EACA;AAA6D;EAC7D;;AC5EJ;EACI;EACA,aCHW;EDIX;EACA;;;AAGJ;EACI;;;AAGJ;EACI,kBCQc;EDPd,OCQQ;;;ADLZ;EACI,OCIQ;EDHR,aClBS;EDmBT;EACA;EACA;;;AAGJ;EACI;;;AAGJ;EACI;;AAEA;EACI;EACA;EACA;EACA;EACA;;;AAIR;EACI;EACA;EACA;EACA;;;AAGJ;EACI,OC1BW;ED2BX;EACA;EACA;;AAEA;EACI,OC/BY;;;ADmCpB;EACI;EACA,kBCxCc;EDyCd,OCvCW;EDwCX;EACA;EACA;EACA;EACA,QC/DU;EDgEV;EACA;EACA;;AACA;EACI,kBChDY;EDiDZ;;AAGJ;EACI,kBCtDO;EDuDP,OCxDI;EDyDJ;;AACA;EACI,kBCzDQ;;;AD8DpB;EACI,kBC5DmB;ED6DnB,OClEQ;EDmER,QCrFU;EDsFV;EACA;EACA;;;AAIA;EACI;EACA;;AAGJ;EACI;;AAEA;EACI;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AAIR;EACI,OC7FK;ED8FL;EACA;EACA;;AAEA;EACI;EACA;;AAIR;EACI;;AAEA;EACI;;AAGJ;EACI;;AAIR;EACI;EACA;EACA,OC1HI;ED2HJ;EACA;EACA;EACA;;AAEA;EACI;EACA,kBC7HW;;ADgIf;EACI;;AAIR;EACI;;AAIA;EACI;EACA;EC1JV;;AACA;EDuJM;ICtJJ;IACA;;;AD4JQ;EC/JV;;AACA;ED8JU;IC7JR;IACA;;;ADiKI;EACI;EACA;EACA;EACA;EACA,cC5JO;ED6JP;EACA;EACA;EACA;EACA;;AAEA;EACI;;AAGJ;EACI;;AAKR;EACI;;AAEA;EACI;;AAEA;EACI;;AAEJ;EACI,OCxLP;;AD+LL;EACI;;AAEJ;EACI;EACA;EChNV;;AACA;ED6MM;IC5MJ;IACA;;;ADkNQ;ECrNV;;AACA;EDoNU;ICnNR;IACA;;;ADuNI;EACI;EACA;;;AAKZ;EACI;EACA;;;AAGJ;EACI;;AAEA;EACI,MCjOI;;ADoOR;EACI,MCtOU;;;AD2Od;EACI;EACA;;;AAIR;EACI;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGJ;EACI;EACA;EACA;EACA;AAAkB;EAClB;EACA;EACA;EACA;EACA;EACA;EACA;AAEA;EACA;AACA;EACA;AAEA;EACA;AAEA;EACA;;;AEtSJ;EACI,kBDqBQ;ECpBR,ODmBc;;ACjBd;EACI;;AAGJ;EACI,ODYU;;ACTd;EACI,kBDSI;ECRJ,ODSO;ECRP;;AAEA;EACI,kBDmBa;EClBb;;AAGJ;EACI;EACA,ODFA;ECGA;EACA;;AACA;EACI,kBDJI;;ACQZ;EACI,ODZM;;ACgBN;EDxBV;;AACA;ECuBU;IDtBR;IACA;;;ACyBQ;EACI,kBDfO;;ACiBP;ED/Bd;;AACA;EC8Bc;ID7BZ;IACA;;;ACmCQ;EDtCV;;AACA;ECqCU;IDpCR;IACA;;;ACwCY;ED3Cd;;AACA;EC0Cc;IDzCZ;IACA;;;AC+CA;EACI,kBD1CI;EC2CJ,OD5CU;;ACgDV;EACI;;AAGJ;EACI;;AAIR;EACI","file":"light.css"}

View File

@ -6,6 +6,8 @@
<form action="{{ changePasswordUrl }}" method="POST">
{{ .CSRF }}
<input type="hidden" name="authRequestID" value="{{ .AuthReqID }}" />
<div class="fields">

View File

@ -6,6 +6,8 @@
<form action="{{ loginUrl }}" method="POST">
{{ .CSRF }}
<input type="hidden" name="authRequestID" value="{{ .AuthReqID }}" />

View File

@ -6,6 +6,8 @@
<form action="{{ initPasswordUrl }}" method="POST">
{{ .CSRF }}
<input type="hidden" name="authRequestID" value="{{ .AuthReqID }}" />
<input type="hidden" name="userID" value="{{ .UserID }}" />

View File

@ -5,6 +5,8 @@
<p>{{t "PasswordSetDone.Description"}}</p>
<form action="{{ loginUrl }}" method="POST">
{{ .CSRF }}
<input type="hidden" name="authRequestID" value="{{ .AuthReqID }}" />
<div class="actions">

View File

@ -6,6 +6,8 @@
<form action="{{ initUserUrl }}" method="POST">
{{ .CSRF }}
<input type="hidden" name="authRequestID" value="{{ .AuthReqID }}" />
<input type="hidden" name="userID" value="{{ .UserID }}" />

View File

@ -5,6 +5,8 @@
<p>{{t "InitUserDone.Description"}}</p>
<form action="{{ loginUrl }}" method="POST">
{{ .CSRF }}
<input type="hidden" name="authRequestID" value="{{ .AuthReqID }}" />
<div class="actions">

View File

@ -4,14 +4,16 @@
<h1>{{t "Login.Title"}}</h1>
<p>{{t "Login.Description"}}</p>
<form action="{{ usernameUrl }}" method="POST">
<form action="{{ loginNameUrl }}" method="POST">
{{ .CSRF }}
<input type="hidden" name="authRequestID" value="{{ .AuthReqID }}" />
<div class="fields">
<div class="field">
<label class="label" for="username">{{t "Login.Loginname"}}</label>
<input class="input" type="text" id="username" name="username" placeholder="{{t "Login.LoginnamePlaceHolder"}}" value="{{ .UserName }}" autocomplete="username" autofocus required>
<label class="label" for="loginName">{{t "Login.Loginname"}}</label>
<input class="input" type="text" id="loginName" name="loginName" placeholder="{{t "Login.LoginnamePlaceHolder"}}" value="{{ .LoginName }}" autocomplete="username" autofocus required>
</div>
</div>

View File

@ -5,6 +5,8 @@
<p>{{t "LogoutDone.Description"}}</p>
<form action="{{ loginUrl }}" method="POST">
{{ .CSRF }}
<div class="actions">
<button class="primary right" type="submit">{{t "Actions.Login"}}</button>
</div>

View File

@ -6,6 +6,8 @@
<form action="{{ mailVerificationUrl }}" method="POST">
{{ .CSRF }}
<input type="hidden" name="authRequestID" value="{{ .AuthReqID }}" />
<input type="hidden" name="userID" value="{{ .UserID }}" />

View File

@ -6,6 +6,8 @@
<form action="{{ loginUrl }}" method="POST">
{{ .CSRF }}
<input type="hidden" name="authRequestID" value="{{ .AuthReqID }}" />

View File

@ -6,6 +6,8 @@
<form action="{{ loginUrl }}" method="POST">
{{ .CSRF }}
<input type="hidden" name="authRequestID" value="{{ .AuthReqID }}" />
<input type="hidden" name="mfaType" value="{{ .MfaType }}" />

View File

@ -6,6 +6,8 @@
<form action="{{ mfaInitVerifyUrl }}" method="POST">
{{ .CSRF }}
<input type="hidden" name="authRequestID" value="{{ .AuthReqID }}" />
<input type="hidden" name="mfaType" value="{{ .MfaType }}" />
<input type="hidden" name="url" value="{{ .Url }}" />
@ -21,7 +23,7 @@
<span class="label" for="secret">{{t "MfaInitVerify.Secret"}}</span>
<span class="input" id="secret">
{{.Secret}}
<span class="copy material-icons" onclick="copyToClipboard('{{ .Secret }}')">content_copy</span>
<span class="copy material-icons" data-copy="{{ .Secret }}" >content_copy</span>
</span>
</div>
<div class="field">
@ -36,12 +38,7 @@
</div>
</form>
<script>
const copyToClipboard = str => {
navigator.clipboard.writeText(str);
}
</script>
<script src="{{ resourceUrl "scripts/copy_to_clipboard.js" }}"></script>
{{template "main-bottom" .}}

View File

@ -5,6 +5,8 @@
<form action="{{ mfaPromptUrl }}" method="POST">
{{ .CSRF }}
<input type="hidden" name="authRequestID" value="{{ .AuthReqID }}" />
<div class="fields">

View File

@ -6,6 +6,8 @@
<form action="{{ mfaVerifyUrl }}" method="POST">
{{ .CSRF }}
<input type="hidden" name="authRequestID" value="{{ .AuthReqID }}" />
<input type="hidden" name="mfaType" value="{{ .SelectedMfaProvider }}" />

View File

@ -5,8 +5,10 @@
<form action="{{ passwordUrl }}" method="POST">
{{ .CSRF }}
<input type="hidden" name="authRequestID" value="{{ .AuthReqID }}" />
<input type="hidden" name="username" value="{{ .UserName }}" />
<input type="hidden" name="loginName" value="{{ .LoginName }}" />
<div class="fields">
<div class="field">
@ -19,7 +21,7 @@
<div class="actions">
<button class="primary right" type="submit">{{t "Actions.Next"}}</button>
<a href="{{ usernameChangeUrl .AuthReqID }}">
<a href="{{ loginNameChangeUrl .AuthReqID }}">
<button class="secondary" type="button">{{t "Actions.Back"}}</button>
</a>
<a href="{{ passwordResetUrl .AuthReqID }}">

View File

@ -5,6 +5,8 @@
<p>{{t "PasswordResetDone.Description"}}</p>
<form action="{{ loginUrl }}" method="POST">
{{ .CSRF }}
<input type="hidden" name="authRequestID" value="{{ .AuthReqID }}" />
<div class="actions">

View File

@ -5,6 +5,8 @@
<form action="{{ registrationUrl }}" method="POST">
{{ .CSRF }}
<input type="hidden" name="authRequestID" value="{{ .AuthReqID }}" />
<div class="fields">

View File

@ -6,17 +6,32 @@
<form action="{{ userSelectionUrl }}" method="POST">
{{ .CSRF }}
<input type="hidden" name="authRequestID" value="{{ .AuthReqID }}" />
<div class="actions">
{{ range $user := .Users }}
{{ $sessionState := (t (printf "UserSelection.SessionState%v" $user.UserSessionState)) }}
<button type="submit" name="userID" value="{{$user.UserID}}" class="primary">
<span class="username">{{$user.UserName}}</span>
<span class="sessionstate">({{$sessionState}})</span>
</button>
{{ if .Users }}
<div class="user-selection-list">
{{ range $user := .Users }}
{{ $sessionState := (printf "sessionstate-%v" $user.UserSessionState) }}
<button type="submit" name="userID" value="{{$user.UserID}}" class="clean user-selection">
<div>
<div class="profile-image"></div>
<div class="sessionstate {{$sessionState}}"></div>
</div>
<div class="names">
<div class="displayname">{{$user.DisplayName}}</div>
<div class="loginname">{{$user.LoginName}}</div>
</div>
</button>
{{ end }}
</div>
{{ end }}
<button type="submit" name="userID" value="0" class="primary">{{t "UserSelection.OtherUser"}}</button>
<button type="submit" name="userID" value="0" class="clean other-user">
<div class="other-user-image"></div>
<div>{{t "UserSelection.OtherUser"}}</div>
</button>
</div>
</form>

73
internal/qrcode/qr_svg.go Normal file
View File

@ -0,0 +1,73 @@
package qrcode
import (
"errors"
"image/color"
"github.com/ajstarks/svgo"
"github.com/boombuler/barcode"
)
// QrSVG holds the data related to the size, location,
// and block size of the QR Code. Holds unexported fields.
type QrSVG struct {
qr barcode.Barcode
qrWidth int
blockSize int
startingX int
startingY int
}
// NewQrSVG contructs a QrSVG struct. It takes a QR Code in the form
// of barcode.Barcode and sets the "pixel" or block size of QR Code in
// the SVG file.
func NewQrSVG(qr barcode.Barcode, blockSize int) QrSVG {
return QrSVG{
qr: qr,
qrWidth: qr.Bounds().Max.X,
blockSize: blockSize,
startingX: 0,
startingY: 0,
}
}
// WriteQrSVG writes the QR Code to SVG.
func (qs *QrSVG) WriteQrSVG(s *svg.SVG) error {
if qs.qr.Metadata().CodeKind == "QR Code" {
currY := qs.startingY
for x := 0; x < qs.qrWidth; x++ {
currX := qs.startingX
for y := 0; y < qs.qrWidth; y++ {
if qs.qr.At(x, y) == color.Black {
s.Rect(currX, currY, qs.blockSize, qs.blockSize, "class=\"color\"")
} else if qs.qr.At(x, y) == color.White {
s.Rect(currX, currY, qs.blockSize, qs.blockSize, "class=\"bg-color\"")
}
currX += qs.blockSize
}
currY += qs.blockSize
}
return nil
}
return errors.New("can not write to SVG: Not a QR code")
}
// SetStartPoint sets the top left start point of QR Code.
// This takes an X and Y value and then adds four white "blocks"
// to create the "quiet zone" around the QR Code.
func (qs *QrSVG) SetStartPoint(x, y int) {
qs.startingX = x + (qs.blockSize * 4)
qs.startingY = y + (qs.blockSize * 4)
}
// StartQrSVG creates a start for writing an SVG file that
// only contains a barcode. This is similar to the svg.Start() method.
// This fucntion should only be used if you only want to write a QR code
// to the SVG. Otherwise use the regular svg.Start() method to start your
// SVG file.
func (qs *QrSVG) StartQrSVG(s *svg.SVG) {
width := (qs.qrWidth * qs.blockSize) + (qs.blockSize * 8)
qs.SetStartPoint(0, 0)
s.Start(width, width)
}

View File

@ -0,0 +1,493 @@
package qrcode
import (
"bytes"
"os"
"testing"
"github.com/ajstarks/svgo"
"github.com/boombuler/barcode/qr"
)
func Test_goqrsvg(t *testing.T) {
buf := bytes.NewBufferString("")
s := svg.New(buf)
// Create the barcode
qrCode, _ := qr.Encode("Hello World", qr.M, qr.Auto)
// Write QR code to SVG
qs := NewQrSVG(qrCode, 5)
qs.StartQrSVG(s)
qs.WriteQrSVG(s)
s.End()
// Check if output the same as correctOutput
if buf.String() != correctOutput {
t.Error("Something is not right... The SVG created is not the same as correctOutput.")
}
}
func ExampleNewQrSVG() {
s := svg.New(os.Stdout)
// Create the barcode
qrCode, _ := qr.Encode("Hello World", qr.M, qr.Auto)
// Write QR code to SVG
qs := NewQrSVG(qrCode, 5)
qs.StartQrSVG(s)
qs.WriteQrSVG(s)
s.End()
}
const correctOutput = `<?xml version="1.0"?>
<!-- Generated by SVGo -->
<svg width="145" height="145"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<rect x="20" y="20" width="5" height="5" class="color" />
<rect x="25" y="20" width="5" height="5" class="color" />
<rect x="30" y="20" width="5" height="5" class="color" />
<rect x="35" y="20" width="5" height="5" class="color" />
<rect x="40" y="20" width="5" height="5" class="color" />
<rect x="45" y="20" width="5" height="5" class="color" />
<rect x="50" y="20" width="5" height="5" class="color" />
<rect x="55" y="20" width="5" height="5" class="bg-color" />
<rect x="60" y="20" width="5" height="5" class="color" />
<rect x="65" y="20" width="5" height="5" class="color" />
<rect x="70" y="20" width="5" height="5" class="bg-color" />
<rect x="75" y="20" width="5" height="5" class="color" />
<rect x="80" y="20" width="5" height="5" class="bg-color" />
<rect x="85" y="20" width="5" height="5" class="bg-color" />
<rect x="90" y="20" width="5" height="5" class="color" />
<rect x="95" y="20" width="5" height="5" class="color" />
<rect x="100" y="20" width="5" height="5" class="color" />
<rect x="105" y="20" width="5" height="5" class="color" />
<rect x="110" y="20" width="5" height="5" class="color" />
<rect x="115" y="20" width="5" height="5" class="color" />
<rect x="120" y="20" width="5" height="5" class="color" />
<rect x="20" y="25" width="5" height="5" class="color" />
<rect x="25" y="25" width="5" height="5" class="bg-color" />
<rect x="30" y="25" width="5" height="5" class="bg-color" />
<rect x="35" y="25" width="5" height="5" class="bg-color" />
<rect x="40" y="25" width="5" height="5" class="bg-color" />
<rect x="45" y="25" width="5" height="5" class="bg-color" />
<rect x="50" y="25" width="5" height="5" class="color" />
<rect x="55" y="25" width="5" height="5" class="bg-color" />
<rect x="60" y="25" width="5" height="5" class="bg-color" />
<rect x="65" y="25" width="5" height="5" class="bg-color" />
<rect x="70" y="25" width="5" height="5" class="color" />
<rect x="75" y="25" width="5" height="5" class="bg-color" />
<rect x="80" y="25" width="5" height="5" class="color" />
<rect x="85" y="25" width="5" height="5" class="bg-color" />
<rect x="90" y="25" width="5" height="5" class="color" />
<rect x="95" y="25" width="5" height="5" class="bg-color" />
<rect x="100" y="25" width="5" height="5" class="bg-color" />
<rect x="105" y="25" width="5" height="5" class="bg-color" />
<rect x="110" y="25" width="5" height="5" class="bg-color" />
<rect x="115" y="25" width="5" height="5" class="bg-color" />
<rect x="120" y="25" width="5" height="5" class="color" />
<rect x="20" y="30" width="5" height="5" class="color" />
<rect x="25" y="30" width="5" height="5" class="bg-color" />
<rect x="30" y="30" width="5" height="5" class="color" />
<rect x="35" y="30" width="5" height="5" class="color" />
<rect x="40" y="30" width="5" height="5" class="color" />
<rect x="45" y="30" width="5" height="5" class="bg-color" />
<rect x="50" y="30" width="5" height="5" class="color" />
<rect x="55" y="30" width="5" height="5" class="bg-color" />
<rect x="60" y="30" width="5" height="5" class="color" />
<rect x="65" y="30" width="5" height="5" class="bg-color" />
<rect x="70" y="30" width="5" height="5" class="color" />
<rect x="75" y="30" width="5" height="5" class="color" />
<rect x="80" y="30" width="5" height="5" class="color" />
<rect x="85" y="30" width="5" height="5" class="bg-color" />
<rect x="90" y="30" width="5" height="5" class="color" />
<rect x="95" y="30" width="5" height="5" class="bg-color" />
<rect x="100" y="30" width="5" height="5" class="color" />
<rect x="105" y="30" width="5" height="5" class="color" />
<rect x="110" y="30" width="5" height="5" class="color" />
<rect x="115" y="30" width="5" height="5" class="bg-color" />
<rect x="120" y="30" width="5" height="5" class="color" />
<rect x="20" y="35" width="5" height="5" class="color" />
<rect x="25" y="35" width="5" height="5" class="bg-color" />
<rect x="30" y="35" width="5" height="5" class="color" />
<rect x="35" y="35" width="5" height="5" class="color" />
<rect x="40" y="35" width="5" height="5" class="color" />
<rect x="45" y="35" width="5" height="5" class="bg-color" />
<rect x="50" y="35" width="5" height="5" class="color" />
<rect x="55" y="35" width="5" height="5" class="bg-color" />
<rect x="60" y="35" width="5" height="5" class="color" />
<rect x="65" y="35" width="5" height="5" class="color" />
<rect x="70" y="35" width="5" height="5" class="color" />
<rect x="75" y="35" width="5" height="5" class="bg-color" />
<rect x="80" y="35" width="5" height="5" class="bg-color" />
<rect x="85" y="35" width="5" height="5" class="bg-color" />
<rect x="90" y="35" width="5" height="5" class="color" />
<rect x="95" y="35" width="5" height="5" class="bg-color" />
<rect x="100" y="35" width="5" height="5" class="color" />
<rect x="105" y="35" width="5" height="5" class="color" />
<rect x="110" y="35" width="5" height="5" class="color" />
<rect x="115" y="35" width="5" height="5" class="bg-color" />
<rect x="120" y="35" width="5" height="5" class="color" />
<rect x="20" y="40" width="5" height="5" class="color" />
<rect x="25" y="40" width="5" height="5" class="bg-color" />
<rect x="30" y="40" width="5" height="5" class="color" />
<rect x="35" y="40" width="5" height="5" class="color" />
<rect x="40" y="40" width="5" height="5" class="color" />
<rect x="45" y="40" width="5" height="5" class="bg-color" />
<rect x="50" y="40" width="5" height="5" class="color" />
<rect x="55" y="40" width="5" height="5" class="bg-color" />
<rect x="60" y="40" width="5" height="5" class="color" />
<rect x="65" y="40" width="5" height="5" class="color" />
<rect x="70" y="40" width="5" height="5" class="color" />
<rect x="75" y="40" width="5" height="5" class="color" />
<rect x="80" y="40" width="5" height="5" class="bg-color" />
<rect x="85" y="40" width="5" height="5" class="bg-color" />
<rect x="90" y="40" width="5" height="5" class="color" />
<rect x="95" y="40" width="5" height="5" class="bg-color" />
<rect x="100" y="40" width="5" height="5" class="color" />
<rect x="105" y="40" width="5" height="5" class="color" />
<rect x="110" y="40" width="5" height="5" class="color" />
<rect x="115" y="40" width="5" height="5" class="bg-color" />
<rect x="120" y="40" width="5" height="5" class="color" />
<rect x="20" y="45" width="5" height="5" class="color" />
<rect x="25" y="45" width="5" height="5" class="bg-color" />
<rect x="30" y="45" width="5" height="5" class="bg-color" />
<rect x="35" y="45" width="5" height="5" class="bg-color" />
<rect x="40" y="45" width="5" height="5" class="bg-color" />
<rect x="45" y="45" width="5" height="5" class="bg-color" />
<rect x="50" y="45" width="5" height="5" class="color" />
<rect x="55" y="45" width="5" height="5" class="bg-color" />
<rect x="60" y="45" width="5" height="5" class="color" />
<rect x="65" y="45" width="5" height="5" class="color" />
<rect x="70" y="45" width="5" height="5" class="bg-color" />
<rect x="75" y="45" width="5" height="5" class="bg-color" />
<rect x="80" y="45" width="5" height="5" class="bg-color" />
<rect x="85" y="45" width="5" height="5" class="bg-color" />
<rect x="90" y="45" width="5" height="5" class="color" />
<rect x="95" y="45" width="5" height="5" class="bg-color" />
<rect x="100" y="45" width="5" height="5" class="bg-color" />
<rect x="105" y="45" width="5" height="5" class="bg-color" />
<rect x="110" y="45" width="5" height="5" class="bg-color" />
<rect x="115" y="45" width="5" height="5" class="bg-color" />
<rect x="120" y="45" width="5" height="5" class="color" />
<rect x="20" y="50" width="5" height="5" class="color" />
<rect x="25" y="50" width="5" height="5" class="color" />
<rect x="30" y="50" width="5" height="5" class="color" />
<rect x="35" y="50" width="5" height="5" class="color" />
<rect x="40" y="50" width="5" height="5" class="color" />
<rect x="45" y="50" width="5" height="5" class="color" />
<rect x="50" y="50" width="5" height="5" class="color" />
<rect x="55" y="50" width="5" height="5" class="bg-color" />
<rect x="60" y="50" width="5" height="5" class="color" />
<rect x="65" y="50" width="5" height="5" class="bg-color" />
<rect x="70" y="50" width="5" height="5" class="color" />
<rect x="75" y="50" width="5" height="5" class="bg-color" />
<rect x="80" y="50" width="5" height="5" class="color" />
<rect x="85" y="50" width="5" height="5" class="bg-color" />
<rect x="90" y="50" width="5" height="5" class="color" />
<rect x="95" y="50" width="5" height="5" class="color" />
<rect x="100" y="50" width="5" height="5" class="color" />
<rect x="105" y="50" width="5" height="5" class="color" />
<rect x="110" y="50" width="5" height="5" class="color" />
<rect x="115" y="50" width="5" height="5" class="color" />
<rect x="120" y="50" width="5" height="5" class="color" />
<rect x="20" y="55" width="5" height="5" class="bg-color" />
<rect x="25" y="55" width="5" height="5" class="bg-color" />
<rect x="30" y="55" width="5" height="5" class="bg-color" />
<rect x="35" y="55" width="5" height="5" class="bg-color" />
<rect x="40" y="55" width="5" height="5" class="bg-color" />
<rect x="45" y="55" width="5" height="5" class="bg-color" />
<rect x="50" y="55" width="5" height="5" class="bg-color" />
<rect x="55" y="55" width="5" height="5" class="bg-color" />
<rect x="60" y="55" width="5" height="5" class="bg-color" />
<rect x="65" y="55" width="5" height="5" class="bg-color" />
<rect x="70" y="55" width="5" height="5" class="color" />
<rect x="75" y="55" width="5" height="5" class="bg-color" />
<rect x="80" y="55" width="5" height="5" class="bg-color" />
<rect x="85" y="55" width="5" height="5" class="bg-color" />
<rect x="90" y="55" width="5" height="5" class="bg-color" />
<rect x="95" y="55" width="5" height="5" class="bg-color" />
<rect x="100" y="55" width="5" height="5" class="bg-color" />
<rect x="105" y="55" width="5" height="5" class="bg-color" />
<rect x="110" y="55" width="5" height="5" class="bg-color" />
<rect x="115" y="55" width="5" height="5" class="bg-color" />
<rect x="120" y="55" width="5" height="5" class="bg-color" />
<rect x="20" y="60" width="5" height="5" class="bg-color" />
<rect x="25" y="60" width="5" height="5" class="bg-color" />
<rect x="30" y="60" width="5" height="5" class="color" />
<rect x="35" y="60" width="5" height="5" class="color" />
<rect x="40" y="60" width="5" height="5" class="color" />
<rect x="45" y="60" width="5" height="5" class="color" />
<rect x="50" y="60" width="5" height="5" class="color" />
<rect x="55" y="60" width="5" height="5" class="color" />
<rect x="60" y="60" width="5" height="5" class="bg-color" />
<rect x="65" y="60" width="5" height="5" class="color" />
<rect x="70" y="60" width="5" height="5" class="bg-color" />
<rect x="75" y="60" width="5" height="5" class="color" />
<rect x="80" y="60" width="5" height="5" class="bg-color" />
<rect x="85" y="60" width="5" height="5" class="color" />
<rect x="90" y="60" width="5" height="5" class="bg-color" />
<rect x="95" y="60" width="5" height="5" class="color" />
<rect x="100" y="60" width="5" height="5" class="color" />
<rect x="105" y="60" width="5" height="5" class="color" />
<rect x="110" y="60" width="5" height="5" class="color" />
<rect x="115" y="60" width="5" height="5" class="bg-color" />
<rect x="120" y="60" width="5" height="5" class="color" />
<rect x="20" y="65" width="5" height="5" class="bg-color" />
<rect x="25" y="65" width="5" height="5" class="bg-color" />
<rect x="30" y="65" width="5" height="5" class="bg-color" />
<rect x="35" y="65" width="5" height="5" class="color" />
<rect x="40" y="65" width="5" height="5" class="bg-color" />
<rect x="45" y="65" width="5" height="5" class="bg-color" />
<rect x="50" y="65" width="5" height="5" class="bg-color" />
<rect x="55" y="65" width="5" height="5" class="color" />
<rect x="60" y="65" width="5" height="5" class="bg-color" />
<rect x="65" y="65" width="5" height="5" class="bg-color" />
<rect x="70" y="65" width="5" height="5" class="color" />
<rect x="75" y="65" width="5" height="5" class="color" />
<rect x="80" y="65" width="5" height="5" class="bg-color" />
<rect x="85" y="65" width="5" height="5" class="bg-color" />
<rect x="90" y="65" width="5" height="5" class="bg-color" />
<rect x="95" y="65" width="5" height="5" class="bg-color" />
<rect x="100" y="65" width="5" height="5" class="bg-color" />
<rect x="105" y="65" width="5" height="5" class="color" />
<rect x="110" y="65" width="5" height="5" class="color" />
<rect x="115" y="65" width="5" height="5" class="bg-color" />
<rect x="120" y="65" width="5" height="5" class="bg-color" />
<rect x="20" y="70" width="5" height="5" class="color" />
<rect x="25" y="70" width="5" height="5" class="color" />
<rect x="30" y="70" width="5" height="5" class="color" />
<rect x="35" y="70" width="5" height="5" class="bg-color" />
<rect x="40" y="70" width="5" height="5" class="bg-color" />
<rect x="45" y="70" width="5" height="5" class="color" />
<rect x="50" y="70" width="5" height="5" class="color" />
<rect x="55" y="70" width="5" height="5" class="bg-color" />
<rect x="60" y="70" width="5" height="5" class="bg-color" />
<rect x="65" y="70" width="5" height="5" class="bg-color" />
<rect x="70" y="70" width="5" height="5" class="bg-color" />
<rect x="75" y="70" width="5" height="5" class="bg-color" />
<rect x="80" y="70" width="5" height="5" class="bg-color" />
<rect x="85" y="70" width="5" height="5" class="color" />
<rect x="90" y="70" width="5" height="5" class="bg-color" />
<rect x="95" y="70" width="5" height="5" class="bg-color" />
<rect x="100" y="70" width="5" height="5" class="bg-color" />
<rect x="105" y="70" width="5" height="5" class="color" />
<rect x="110" y="70" width="5" height="5" class="bg-color" />
<rect x="115" y="70" width="5" height="5" class="color" />
<rect x="120" y="70" width="5" height="5" class="color" />
<rect x="20" y="75" width="5" height="5" class="bg-color" />
<rect x="25" y="75" width="5" height="5" class="bg-color" />
<rect x="30" y="75" width="5" height="5" class="bg-color" />
<rect x="35" y="75" width="5" height="5" class="color" />
<rect x="40" y="75" width="5" height="5" class="bg-color" />
<rect x="45" y="75" width="5" height="5" class="color" />
<rect x="50" y="75" width="5" height="5" class="bg-color" />
<rect x="55" y="75" width="5" height="5" class="bg-color" />
<rect x="60" y="75" width="5" height="5" class="color" />
<rect x="65" y="75" width="5" height="5" class="color" />
<rect x="70" y="75" width="5" height="5" class="bg-color" />
<rect x="75" y="75" width="5" height="5" class="color" />
<rect x="80" y="75" width="5" height="5" class="bg-color" />
<rect x="85" y="75" width="5" height="5" class="bg-color" />
<rect x="90" y="75" width="5" height="5" class="color" />
<rect x="95" y="75" width="5" height="5" class="bg-color" />
<rect x="100" y="75" width="5" height="5" class="color" />
<rect x="105" y="75" width="5" height="5" class="bg-color" />
<rect x="110" y="75" width="5" height="5" class="bg-color" />
<rect x="115" y="75" width="5" height="5" class="bg-color" />
<rect x="120" y="75" width="5" height="5" class="color" />
<rect x="20" y="80" width="5" height="5" class="color" />
<rect x="25" y="80" width="5" height="5" class="color" />
<rect x="30" y="80" width="5" height="5" class="color" />
<rect x="35" y="80" width="5" height="5" class="color" />
<rect x="40" y="80" width="5" height="5" class="color" />
<rect x="45" y="80" width="5" height="5" class="bg-color" />
<rect x="50" y="80" width="5" height="5" class="color" />
<rect x="55" y="80" width="5" height="5" class="bg-color" />
<rect x="60" y="80" width="5" height="5" class="bg-color" />
<rect x="65" y="80" width="5" height="5" class="color" />
<rect x="70" y="80" width="5" height="5" class="color" />
<rect x="75" y="80" width="5" height="5" class="color" />
<rect x="80" y="80" width="5" height="5" class="color" />
<rect x="85" y="80" width="5" height="5" class="color" />
<rect x="90" y="80" width="5" height="5" class="bg-color" />
<rect x="95" y="80" width="5" height="5" class="bg-color" />
<rect x="100" y="80" width="5" height="5" class="bg-color" />
<rect x="105" y="80" width="5" height="5" class="color" />
<rect x="110" y="80" width="5" height="5" class="color" />
<rect x="115" y="80" width="5" height="5" class="color" />
<rect x="120" y="80" width="5" height="5" class="color" />
<rect x="20" y="85" width="5" height="5" class="bg-color" />
<rect x="25" y="85" width="5" height="5" class="bg-color" />
<rect x="30" y="85" width="5" height="5" class="bg-color" />
<rect x="35" y="85" width="5" height="5" class="bg-color" />
<rect x="40" y="85" width="5" height="5" class="bg-color" />
<rect x="45" y="85" width="5" height="5" class="bg-color" />
<rect x="50" y="85" width="5" height="5" class="bg-color" />
<rect x="55" y="85" width="5" height="5" class="bg-color" />
<rect x="60" y="85" width="5" height="5" class="bg-color" />
<rect x="65" y="85" width="5" height="5" class="color" />
<rect x="70" y="85" width="5" height="5" class="color" />
<rect x="75" y="85" width="5" height="5" class="color" />
<rect x="80" y="85" width="5" height="5" class="color" />
<rect x="85" y="85" width="5" height="5" class="bg-color" />
<rect x="90" y="85" width="5" height="5" class="bg-color" />
<rect x="95" y="85" width="5" height="5" class="color" />
<rect x="100" y="85" width="5" height="5" class="bg-color" />
<rect x="105" y="85" width="5" height="5" class="color" />
<rect x="110" y="85" width="5" height="5" class="bg-color" />
<rect x="115" y="85" width="5" height="5" class="color" />
<rect x="120" y="85" width="5" height="5" class="bg-color" />
<rect x="20" y="90" width="5" height="5" class="color" />
<rect x="25" y="90" width="5" height="5" class="color" />
<rect x="30" y="90" width="5" height="5" class="color" />
<rect x="35" y="90" width="5" height="5" class="color" />
<rect x="40" y="90" width="5" height="5" class="color" />
<rect x="45" y="90" width="5" height="5" class="color" />
<rect x="50" y="90" width="5" height="5" class="color" />
<rect x="55" y="90" width="5" height="5" class="bg-color" />
<rect x="60" y="90" width="5" height="5" class="color" />
<rect x="65" y="90" width="5" height="5" class="color" />
<rect x="70" y="90" width="5" height="5" class="color" />
<rect x="75" y="90" width="5" height="5" class="bg-color" />
<rect x="80" y="90" width="5" height="5" class="color" />
<rect x="85" y="90" width="5" height="5" class="bg-color" />
<rect x="90" y="90" width="5" height="5" class="color" />
<rect x="95" y="90" width="5" height="5" class="bg-color" />
<rect x="100" y="90" width="5" height="5" class="color" />
<rect x="105" y="90" width="5" height="5" class="color" />
<rect x="110" y="90" width="5" height="5" class="bg-color" />
<rect x="115" y="90" width="5" height="5" class="bg-color" />
<rect x="120" y="90" width="5" height="5" class="color" />
<rect x="20" y="95" width="5" height="5" class="color" />
<rect x="25" y="95" width="5" height="5" class="bg-color" />
<rect x="30" y="95" width="5" height="5" class="bg-color" />
<rect x="35" y="95" width="5" height="5" class="bg-color" />
<rect x="40" y="95" width="5" height="5" class="bg-color" />
<rect x="45" y="95" width="5" height="5" class="bg-color" />
<rect x="50" y="95" width="5" height="5" class="color" />
<rect x="55" y="95" width="5" height="5" class="bg-color" />
<rect x="60" y="95" width="5" height="5" class="color" />
<rect x="65" y="95" width="5" height="5" class="color" />
<rect x="70" y="95" width="5" height="5" class="bg-color" />
<rect x="75" y="95" width="5" height="5" class="bg-color" />
<rect x="80" y="95" width="5" height="5" class="bg-color" />
<rect x="85" y="95" width="5" height="5" class="bg-color" />
<rect x="90" y="95" width="5" height="5" class="bg-color" />
<rect x="95" y="95" width="5" height="5" class="color" />
<rect x="100" y="95" width="5" height="5" class="color" />
<rect x="105" y="95" width="5" height="5" class="color" />
<rect x="110" y="95" width="5" height="5" class="color" />
<rect x="115" y="95" width="5" height="5" class="bg-color" />
<rect x="120" y="95" width="5" height="5" class="bg-color" />
<rect x="20" y="100" width="5" height="5" class="color" />
<rect x="25" y="100" width="5" height="5" class="bg-color" />
<rect x="30" y="100" width="5" height="5" class="color" />
<rect x="35" y="100" width="5" height="5" class="color" />
<rect x="40" y="100" width="5" height="5" class="color" />
<rect x="45" y="100" width="5" height="5" class="bg-color" />
<rect x="50" y="100" width="5" height="5" class="color" />
<rect x="55" y="100" width="5" height="5" class="bg-color" />
<rect x="60" y="100" width="5" height="5" class="color" />
<rect x="65" y="100" width="5" height="5" class="color" />
<rect x="70" y="100" width="5" height="5" class="bg-color" />
<rect x="75" y="100" width="5" height="5" class="color" />
<rect x="80" y="100" width="5" height="5" class="bg-color" />
<rect x="85" y="100" width="5" height="5" class="bg-color" />
<rect x="90" y="100" width="5" height="5" class="bg-color" />
<rect x="95" y="100" width="5" height="5" class="bg-color" />
<rect x="100" y="100" width="5" height="5" class="bg-color" />
<rect x="105" y="100" width="5" height="5" class="color" />
<rect x="110" y="100" width="5" height="5" class="bg-color" />
<rect x="115" y="100" width="5" height="5" class="color" />
<rect x="120" y="100" width="5" height="5" class="color" />
<rect x="20" y="105" width="5" height="5" class="color" />
<rect x="25" y="105" width="5" height="5" class="bg-color" />
<rect x="30" y="105" width="5" height="5" class="color" />
<rect x="35" y="105" width="5" height="5" class="color" />
<rect x="40" y="105" width="5" height="5" class="color" />
<rect x="45" y="105" width="5" height="5" class="bg-color" />
<rect x="50" y="105" width="5" height="5" class="color" />
<rect x="55" y="105" width="5" height="5" class="bg-color" />
<rect x="60" y="105" width="5" height="5" class="color" />
<rect x="65" y="105" width="5" height="5" class="color" />
<rect x="70" y="105" width="5" height="5" class="color" />
<rect x="75" y="105" width="5" height="5" class="color" />
<rect x="80" y="105" width="5" height="5" class="bg-color" />
<rect x="85" y="105" width="5" height="5" class="color" />
<rect x="90" y="105" width="5" height="5" class="bg-color" />
<rect x="95" y="105" width="5" height="5" class="color" />
<rect x="100" y="105" width="5" height="5" class="bg-color" />
<rect x="105" y="105" width="5" height="5" class="color" />
<rect x="110" y="105" width="5" height="5" class="bg-color" />
<rect x="115" y="105" width="5" height="5" class="color" />
<rect x="120" y="105" width="5" height="5" class="bg-color" />
<rect x="20" y="110" width="5" height="5" class="color" />
<rect x="25" y="110" width="5" height="5" class="bg-color" />
<rect x="30" y="110" width="5" height="5" class="color" />
<rect x="35" y="110" width="5" height="5" class="color" />
<rect x="40" y="110" width="5" height="5" class="color" />
<rect x="45" y="110" width="5" height="5" class="bg-color" />
<rect x="50" y="110" width="5" height="5" class="color" />
<rect x="55" y="110" width="5" height="5" class="bg-color" />
<rect x="60" y="110" width="5" height="5" class="color" />
<rect x="65" y="110" width="5" height="5" class="color" />
<rect x="70" y="110" width="5" height="5" class="color" />
<rect x="75" y="110" width="5" height="5" class="color" />
<rect x="80" y="110" width="5" height="5" class="bg-color" />
<rect x="85" y="110" width="5" height="5" class="bg-color" />
<rect x="90" y="110" width="5" height="5" class="color" />
<rect x="95" y="110" width="5" height="5" class="color" />
<rect x="100" y="110" width="5" height="5" class="bg-color" />
<rect x="105" y="110" width="5" height="5" class="bg-color" />
<rect x="110" y="110" width="5" height="5" class="color" />
<rect x="115" y="110" width="5" height="5" class="color" />
<rect x="120" y="110" width="5" height="5" class="bg-color" />
<rect x="20" y="115" width="5" height="5" class="color" />
<rect x="25" y="115" width="5" height="5" class="bg-color" />
<rect x="30" y="115" width="5" height="5" class="bg-color" />
<rect x="35" y="115" width="5" height="5" class="bg-color" />
<rect x="40" y="115" width="5" height="5" class="bg-color" />
<rect x="45" y="115" width="5" height="5" class="bg-color" />
<rect x="50" y="115" width="5" height="5" class="color" />
<rect x="55" y="115" width="5" height="5" class="bg-color" />
<rect x="60" y="115" width="5" height="5" class="bg-color" />
<rect x="65" y="115" width="5" height="5" class="bg-color" />
<rect x="70" y="115" width="5" height="5" class="color" />
<rect x="75" y="115" width="5" height="5" class="bg-color" />
<rect x="80" y="115" width="5" height="5" class="bg-color" />
<rect x="85" y="115" width="5" height="5" class="bg-color" />
<rect x="90" y="115" width="5" height="5" class="color" />
<rect x="95" y="115" width="5" height="5" class="color" />
<rect x="100" y="115" width="5" height="5" class="bg-color" />
<rect x="105" y="115" width="5" height="5" class="bg-color" />
<rect x="110" y="115" width="5" height="5" class="bg-color" />
<rect x="115" y="115" width="5" height="5" class="bg-color" />
<rect x="120" y="115" width="5" height="5" class="color" />
<rect x="20" y="120" width="5" height="5" class="color" />
<rect x="25" y="120" width="5" height="5" class="color" />
<rect x="30" y="120" width="5" height="5" class="color" />
<rect x="35" y="120" width="5" height="5" class="color" />
<rect x="40" y="120" width="5" height="5" class="color" />
<rect x="45" y="120" width="5" height="5" class="color" />
<rect x="50" y="120" width="5" height="5" class="color" />
<rect x="55" y="120" width="5" height="5" class="bg-color" />
<rect x="60" y="120" width="5" height="5" class="bg-color" />
<rect x="65" y="120" width="5" height="5" class="color" />
<rect x="70" y="120" width="5" height="5" class="bg-color" />
<rect x="75" y="120" width="5" height="5" class="bg-color" />
<rect x="80" y="120" width="5" height="5" class="color" />
<rect x="85" y="120" width="5" height="5" class="bg-color" />
<rect x="90" y="120" width="5" height="5" class="bg-color" />
<rect x="95" y="120" width="5" height="5" class="color" />
<rect x="100" y="120" width="5" height="5" class="color" />
<rect x="105" y="120" width="5" height="5" class="bg-color" />
<rect x="110" y="120" width="5" height="5" class="bg-color" />
<rect x="115" y="120" width="5" height="5" class="bg-color" />
<rect x="120" y="120" width="5" height="5" class="bg-color" />
</svg>
`

14
internal/qrcode/readme.md Normal file
View File

@ -0,0 +1,14 @@
# QR Code to SVG
This package is a copy of https://github.com/aaronarduino/goqrsvg with the difference of creating the svg with `class` attribute instead of inline `style`:
```go
s.Rect(currX, currY, qs.blockSize, qs.blockSize, "class=\"color\"")
```
and not
```go
s.Rect(currX, currY, qs.blockSize, qs.blockSize, "fill:black;stroke:none")
```
This allows the svg to be styled by css more easily and does not compromise Content Security Policy (CSP).

View File

@ -81,6 +81,12 @@ func (u *User) CheckOrgIamPolicy(policy *org_model.OrgIamPolicy) error {
return nil
}
func (u *User) SetNamesAsDisplayname() {
if u.Profile != nil && u.DisplayName == "" && u.FirstName != "" && u.LastName != "" {
u.DisplayName = u.FirstName + " " + u.LastName
}
}
func (u *User) IsValid() bool {
return u.Profile != nil && u.FirstName != "" && u.LastName != "" && u.UserName != "" && u.Email != nil && u.Email.IsValid() && u.Phone == nil || (u.Phone != nil && u.Phone.IsValid())
}

View File

@ -15,6 +15,8 @@ type UserSessionView struct {
UserAgentID string
UserID string
UserName string
LoginName string
DisplayName string
PasswordVerification time.Time
MfaSoftwareVerification time.Time
MfaSoftwareVerificationType req_model.MfaType

View File

@ -109,6 +109,7 @@ func (es *UserEventstore) PrepareCreateUser(ctx context.Context, user *usr_model
if err != nil {
return nil, nil, err
}
user.SetNamesAsDisplayname()
if !user.IsValid() {
return nil, nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-9dk45", "User is invalid")
}
@ -161,6 +162,7 @@ func (es *UserEventstore) PrepareRegisterUser(ctx context.Context, user *usr_mod
if err != nil {
return nil, nil, err
}
user.SetNamesAsDisplayname()
if !user.IsValid() || user.Password == nil || user.SecretString == "" {
return nil, nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-9dk45", "Errors.User.InvalidData")
}

View File

@ -27,7 +27,9 @@ type UserSessionView struct {
State int32 `json:"-" gorm:"column:state"`
UserAgentID string `json:"userAgentID" gorm:"column:user_agent_id;primary_key"`
UserID string `json:"userID" gorm:"column:user_id;primary_key"`
UserName string `json:"userName" gorm:"column:user_name"`
UserName string `json:"-" gorm:"column:user_name"`
LoginName string `json:"-" gorm:"column:login_name"`
DisplayName string `json:"-" gorm:"column:user_display_name"`
PasswordVerification time.Time `json:"-" gorm:"column:password_verification"`
MfaSoftwareVerification time.Time `json:"-" gorm:"column:mfa_software_verification"`
MfaSoftwareVerificationType int32 `json:"-" gorm:"column:mfa_software_verification_type"`
@ -54,6 +56,8 @@ func UserSessionToModel(userSession *UserSessionView) *model.UserSessionView {
UserAgentID: userSession.UserAgentID,
UserID: userSession.UserID,
UserName: userSession.UserName,
LoginName: userSession.LoginName,
DisplayName: userSession.DisplayName,
PasswordVerification: userSession.PasswordVerification,
MfaSoftwareVerification: userSession.MfaSoftwareVerification,
MfaSoftwareVerificationType: req_model.MfaType(userSession.MfaSoftwareVerificationType),

View File

@ -0,0 +1,6 @@
BEGIN;
ALTER TABLE auth.user_sessions ADD COLUMN user_display_name TEXT;
ALTER TABLE auth.user_sessions ADD COLUMN login_name TEXT;
COMMIT;

File diff suppressed because it is too large Load Diff

View File

@ -38,6 +38,15 @@ func request_AdminService_Healthz_0(ctx context.Context, marshaler runtime.Marsh
}
func local_request_AdminService_Healthz_0(ctx context.Context, marshaler runtime.Marshaler, server AdminServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq empty.Empty
var metadata runtime.ServerMetadata
msg, err := server.Healthz(ctx, &protoReq)
return msg, metadata, err
}
func request_AdminService_Ready_0(ctx context.Context, marshaler runtime.Marshaler, client AdminServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq empty.Empty
var metadata runtime.ServerMetadata
@ -47,6 +56,15 @@ func request_AdminService_Ready_0(ctx context.Context, marshaler runtime.Marshal
}
func local_request_AdminService_Ready_0(ctx context.Context, marshaler runtime.Marshaler, server AdminServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq empty.Empty
var metadata runtime.ServerMetadata
msg, err := server.Ready(ctx, &protoReq)
return msg, metadata, err
}
func request_AdminService_Validate_0(ctx context.Context, marshaler runtime.Marshaler, client AdminServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq empty.Empty
var metadata runtime.ServerMetadata
@ -56,6 +74,15 @@ func request_AdminService_Validate_0(ctx context.Context, marshaler runtime.Mars
}
func local_request_AdminService_Validate_0(ctx context.Context, marshaler runtime.Marshaler, server AdminServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq empty.Empty
var metadata runtime.ServerMetadata
msg, err := server.Validate(ctx, &protoReq)
return msg, metadata, err
}
var (
filter_AdminService_IsOrgUnique_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)}
)
@ -64,7 +91,10 @@ func request_AdminService_IsOrgUnique_0(ctx context.Context, marshaler runtime.M
var protoReq UniqueOrgRequest
var metadata runtime.ServerMetadata
if err := runtime.PopulateQueryParameters(&protoReq, req.URL.Query(), filter_AdminService_IsOrgUnique_0); err != nil {
if err := req.ParseForm(); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_AdminService_IsOrgUnique_0); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
@ -73,6 +103,19 @@ func request_AdminService_IsOrgUnique_0(ctx context.Context, marshaler runtime.M
}
func local_request_AdminService_IsOrgUnique_0(ctx context.Context, marshaler runtime.Marshaler, server AdminServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq UniqueOrgRequest
var metadata runtime.ServerMetadata
if err := runtime.PopulateQueryParameters(&protoReq, req.URL.Query(), filter_AdminService_IsOrgUnique_0); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := server.IsOrgUnique(ctx, &protoReq)
return msg, metadata, err
}
func request_AdminService_GetOrgByID_0(ctx context.Context, marshaler runtime.Marshaler, client AdminServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq OrgID
var metadata runtime.ServerMetadata
@ -100,6 +143,33 @@ func request_AdminService_GetOrgByID_0(ctx context.Context, marshaler runtime.Ma
}
func local_request_AdminService_GetOrgByID_0(ctx context.Context, marshaler runtime.Marshaler, server AdminServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq OrgID
var metadata runtime.ServerMetadata
var (
val string
ok bool
err error
_ = err
)
val, ok = pathParams["id"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id")
}
protoReq.Id, err = runtime.String(val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err)
}
msg, err := server.GetOrgByID(ctx, &protoReq)
return msg, metadata, err
}
func request_AdminService_SearchOrgs_0(ctx context.Context, marshaler runtime.Marshaler, client AdminServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq OrgSearchRequest
var metadata runtime.ServerMetadata
@ -117,6 +187,23 @@ func request_AdminService_SearchOrgs_0(ctx context.Context, marshaler runtime.Ma
}
func local_request_AdminService_SearchOrgs_0(ctx context.Context, marshaler runtime.Marshaler, server AdminServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq OrgSearchRequest
var metadata runtime.ServerMetadata
newReader, berr := utilities.IOReaderFactory(req.Body)
if berr != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
}
if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := server.SearchOrgs(ctx, &protoReq)
return msg, metadata, err
}
func request_AdminService_SetUpOrg_0(ctx context.Context, marshaler runtime.Marshaler, client AdminServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq OrgSetUpRequest
var metadata runtime.ServerMetadata
@ -134,6 +221,23 @@ func request_AdminService_SetUpOrg_0(ctx context.Context, marshaler runtime.Mars
}
func local_request_AdminService_SetUpOrg_0(ctx context.Context, marshaler runtime.Marshaler, server AdminServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq OrgSetUpRequest
var metadata runtime.ServerMetadata
newReader, berr := utilities.IOReaderFactory(req.Body)
if berr != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
}
if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := server.SetUpOrg(ctx, &protoReq)
return msg, metadata, err
}
func request_AdminService_GetOrgIamPolicy_0(ctx context.Context, marshaler runtime.Marshaler, client AdminServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq OrgIamPolicyID
var metadata runtime.ServerMetadata
@ -161,6 +265,33 @@ func request_AdminService_GetOrgIamPolicy_0(ctx context.Context, marshaler runti
}
func local_request_AdminService_GetOrgIamPolicy_0(ctx context.Context, marshaler runtime.Marshaler, server AdminServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq OrgIamPolicyID
var metadata runtime.ServerMetadata
var (
val string
ok bool
err error
_ = err
)
val, ok = pathParams["org_id"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "org_id")
}
protoReq.OrgId, err = runtime.String(val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "org_id", err)
}
msg, err := server.GetOrgIamPolicy(ctx, &protoReq)
return msg, metadata, err
}
func request_AdminService_CreateOrgIamPolicy_0(ctx context.Context, marshaler runtime.Marshaler, client AdminServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq OrgIamPolicyRequest
var metadata runtime.ServerMetadata
@ -196,6 +327,41 @@ func request_AdminService_CreateOrgIamPolicy_0(ctx context.Context, marshaler ru
}
func local_request_AdminService_CreateOrgIamPolicy_0(ctx context.Context, marshaler runtime.Marshaler, server AdminServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq OrgIamPolicyRequest
var metadata runtime.ServerMetadata
newReader, berr := utilities.IOReaderFactory(req.Body)
if berr != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
}
if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
var (
val string
ok bool
err error
_ = err
)
val, ok = pathParams["org_id"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "org_id")
}
protoReq.OrgId, err = runtime.String(val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "org_id", err)
}
msg, err := server.CreateOrgIamPolicy(ctx, &protoReq)
return msg, metadata, err
}
func request_AdminService_UpdateOrgIamPolicy_0(ctx context.Context, marshaler runtime.Marshaler, client AdminServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq OrgIamPolicyRequest
var metadata runtime.ServerMetadata
@ -231,6 +397,41 @@ func request_AdminService_UpdateOrgIamPolicy_0(ctx context.Context, marshaler ru
}
func local_request_AdminService_UpdateOrgIamPolicy_0(ctx context.Context, marshaler runtime.Marshaler, server AdminServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq OrgIamPolicyRequest
var metadata runtime.ServerMetadata
newReader, berr := utilities.IOReaderFactory(req.Body)
if berr != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
}
if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
var (
val string
ok bool
err error
_ = err
)
val, ok = pathParams["org_id"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "org_id")
}
protoReq.OrgId, err = runtime.String(val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "org_id", err)
}
msg, err := server.UpdateOrgIamPolicy(ctx, &protoReq)
return msg, metadata, err
}
func request_AdminService_DeleteOrgIamPolicy_0(ctx context.Context, marshaler runtime.Marshaler, client AdminServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq OrgIamPolicyID
var metadata runtime.ServerMetadata
@ -258,6 +459,261 @@ func request_AdminService_DeleteOrgIamPolicy_0(ctx context.Context, marshaler ru
}
func local_request_AdminService_DeleteOrgIamPolicy_0(ctx context.Context, marshaler runtime.Marshaler, server AdminServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq OrgIamPolicyID
var metadata runtime.ServerMetadata
var (
val string
ok bool
err error
_ = err
)
val, ok = pathParams["org_id"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "org_id")
}
protoReq.OrgId, err = runtime.String(val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "org_id", err)
}
msg, err := server.DeleteOrgIamPolicy(ctx, &protoReq)
return msg, metadata, err
}
// RegisterAdminServiceHandlerServer registers the http handlers for service AdminService to "mux".
// UnaryRPC :call AdminServiceServer directly.
// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906.
func RegisterAdminServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux, server AdminServiceServer, opts []grpc.DialOption) error {
mux.Handle("GET", pattern_AdminService_Healthz_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateContext(ctx, mux, req)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_AdminService_Healthz_0(rctx, inboundMarshaler, server, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_AdminService_Healthz_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("GET", pattern_AdminService_Ready_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateContext(ctx, mux, req)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_AdminService_Ready_0(rctx, inboundMarshaler, server, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_AdminService_Ready_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("GET", pattern_AdminService_Validate_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateContext(ctx, mux, req)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_AdminService_Validate_0(rctx, inboundMarshaler, server, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_AdminService_Validate_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("GET", pattern_AdminService_IsOrgUnique_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateContext(ctx, mux, req)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_AdminService_IsOrgUnique_0(rctx, inboundMarshaler, server, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_AdminService_IsOrgUnique_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("GET", pattern_AdminService_GetOrgByID_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateContext(ctx, mux, req)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_AdminService_GetOrgByID_0(rctx, inboundMarshaler, server, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_AdminService_GetOrgByID_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("POST", pattern_AdminService_SearchOrgs_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateContext(ctx, mux, req)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_AdminService_SearchOrgs_0(rctx, inboundMarshaler, server, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_AdminService_SearchOrgs_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("POST", pattern_AdminService_SetUpOrg_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateContext(ctx, mux, req)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_AdminService_SetUpOrg_0(rctx, inboundMarshaler, server, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_AdminService_SetUpOrg_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("GET", pattern_AdminService_GetOrgIamPolicy_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateContext(ctx, mux, req)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_AdminService_GetOrgIamPolicy_0(rctx, inboundMarshaler, server, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_AdminService_GetOrgIamPolicy_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("POST", pattern_AdminService_CreateOrgIamPolicy_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateContext(ctx, mux, req)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_AdminService_CreateOrgIamPolicy_0(rctx, inboundMarshaler, server, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_AdminService_CreateOrgIamPolicy_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("PUT", pattern_AdminService_UpdateOrgIamPolicy_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateContext(ctx, mux, req)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_AdminService_UpdateOrgIamPolicy_0(rctx, inboundMarshaler, server, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_AdminService_UpdateOrgIamPolicy_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("DELETE", pattern_AdminService_DeleteOrgIamPolicy_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateContext(ctx, mux, req)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_AdminService_DeleteOrgIamPolicy_0(rctx, inboundMarshaler, server, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_AdminService_DeleteOrgIamPolicy_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
return nil
}
// RegisterAdminServiceHandlerFromEndpoint is same as RegisterAdminServiceHandler but
// automatically dials to "endpoint" and closes the connection when "ctx" gets done.
func RegisterAdminServiceHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) {
@ -520,27 +976,27 @@ func RegisterAdminServiceHandlerClient(ctx context.Context, mux *runtime.ServeMu
}
var (
pattern_AdminService_Healthz_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0}, []string{"healthz"}, ""))
pattern_AdminService_Healthz_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0}, []string{"healthz"}, "", runtime.AssumeColonVerbOpt(true)))
pattern_AdminService_Ready_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0}, []string{"ready"}, ""))
pattern_AdminService_Ready_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0}, []string{"ready"}, "", runtime.AssumeColonVerbOpt(true)))
pattern_AdminService_Validate_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0}, []string{"validate"}, ""))
pattern_AdminService_Validate_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0}, []string{"validate"}, "", runtime.AssumeColonVerbOpt(true)))
pattern_AdminService_IsOrgUnique_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"orgs", "_isunique"}, ""))
pattern_AdminService_IsOrgUnique_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"orgs", "_isunique"}, "", runtime.AssumeColonVerbOpt(true)))
pattern_AdminService_GetOrgByID_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 1, 0, 4, 1, 5, 1}, []string{"orgs", "id"}, ""))
pattern_AdminService_GetOrgByID_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 1, 0, 4, 1, 5, 1}, []string{"orgs", "id"}, "", runtime.AssumeColonVerbOpt(true)))
pattern_AdminService_SearchOrgs_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"orgs", "_search"}, ""))
pattern_AdminService_SearchOrgs_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"orgs", "_search"}, "", runtime.AssumeColonVerbOpt(true)))
pattern_AdminService_SetUpOrg_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"orgs", "_setup"}, ""))
pattern_AdminService_SetUpOrg_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"orgs", "_setup"}, "", runtime.AssumeColonVerbOpt(true)))
pattern_AdminService_GetOrgIamPolicy_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 1, 0, 4, 1, 5, 1, 2, 2}, []string{"orgs", "org_id", "iampolicy"}, ""))
pattern_AdminService_GetOrgIamPolicy_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 1, 0, 4, 1, 5, 1, 2, 2}, []string{"orgs", "org_id", "iampolicy"}, "", runtime.AssumeColonVerbOpt(true)))
pattern_AdminService_CreateOrgIamPolicy_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 1, 0, 4, 1, 5, 1, 2, 2}, []string{"orgs", "org_id", "iampolicy"}, ""))
pattern_AdminService_CreateOrgIamPolicy_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 1, 0, 4, 1, 5, 1, 2, 2}, []string{"orgs", "org_id", "iampolicy"}, "", runtime.AssumeColonVerbOpt(true)))
pattern_AdminService_UpdateOrgIamPolicy_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 1, 0, 4, 1, 5, 1, 2, 2}, []string{"orgs", "org_id", "iampolicy"}, ""))
pattern_AdminService_UpdateOrgIamPolicy_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 1, 0, 4, 1, 5, 1, 2, 2}, []string{"orgs", "org_id", "iampolicy"}, "", runtime.AssumeColonVerbOpt(true)))
pattern_AdminService_DeleteOrgIamPolicy_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 1, 0, 4, 1, 5, 1, 2, 2}, []string{"orgs", "org_id", "iampolicy"}, ""))
pattern_AdminService_DeleteOrgIamPolicy_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 1, 0, 4, 1, 5, 1, 2, 2}, []string{"orgs", "org_id", "iampolicy"}, "", runtime.AssumeColonVerbOpt(true)))
)
var (

View File

@ -274,7 +274,7 @@
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/protobufStruct"
"type": "object"
}
}
},
@ -285,19 +285,6 @@
}
},
"definitions": {
"protobufListValue": {
"type": "object",
"properties": {
"values": {
"type": "array",
"items": {
"$ref": "#/definitions/protobufValue"
},
"description": "Repeated field of dynamically typed values."
}
},
"description": "`ListValue` is a wrapper around a repeated field of values.\n\nThe JSON representation for `ListValue` is JSON array."
},
"protobufNullValue": {
"type": "string",
"enum": [
@ -306,51 +293,6 @@
"default": "NULL_VALUE",
"description": "`NullValue` is a singleton enumeration to represent the null value for the\n`Value` type union.\n\n The JSON representation for `NullValue` is JSON `null`.\n\n - NULL_VALUE: Null value."
},
"protobufStruct": {
"type": "object",
"properties": {
"fields": {
"type": "object",
"additionalProperties": {
"$ref": "#/definitions/protobufValue"
},
"description": "Unordered map of dynamically typed values."
}
},
"description": "`Struct` represents a structured data value, consisting of fields\nwhich map to dynamically typed values. In some languages, `Struct`\nmight be supported by a native representation. For example, in\nscripting languages like JS a struct is represented as an\nobject. The details of that representation are described together\nwith the proto support for the language.\n\nThe JSON representation for `Struct` is JSON object."
},
"protobufValue": {
"type": "object",
"properties": {
"null_value": {
"$ref": "#/definitions/protobufNullValue",
"description": "Represents a null value."
},
"number_value": {
"type": "number",
"format": "double",
"description": "Represents a double value."
},
"string_value": {
"type": "string",
"description": "Represents a string value."
},
"bool_value": {
"type": "boolean",
"format": "boolean",
"description": "Represents a boolean value."
},
"struct_value": {
"$ref": "#/definitions/protobufStruct",
"description": "Represents a structured value."
},
"list_value": {
"$ref": "#/definitions/protobufListValue",
"description": "Represents a repeated `Value`."
}
},
"description": "`Value` represents a dynamically typed value which can be either\nnull, a number, a string, a boolean, a recursive struct value, or a\nlist of values. A producer of value is expected to set one of that\nvariants, absence of any variant indicates an error.\n\nThe JSON representation for `Value` is JSON value."
},
"v1CreateOrgRequest": {
"type": "object",
"properties": {
@ -377,9 +319,6 @@
"nick_name": {
"type": "string"
},
"display_name": {
"type": "string"
},
"preferred_language": {
"type": "string"
},

View File

@ -32,7 +32,6 @@ func userCreateRequestToModel(user *CreateUserRequest) *usr_model.User {
return &usr_model.User{
Profile: &usr_model.Profile{
UserName: user.UserName,
DisplayName: user.DisplayName,
FirstName: user.FirstName,
LastName: user.LastName,
NickName: user.NickName,

View File

@ -220,19 +220,18 @@ message CreateUserRequest {
string first_name = 2 [(validate.rules).string = {min_len: 1, max_len: 200}];
string last_name = 3 [(validate.rules).string = {min_len: 1, max_len: 200}];
string nick_name = 4 [(validate.rules).string = {max_len: 200}];
string display_name = 5 [(validate.rules).string = {max_len: 200}];
string preferred_language = 6 [(validate.rules).string = {max_len: 200}];
Gender gender = 7;
string email = 8 [(validate.rules).string = {min_len: 1, max_len: 200, email: true}];
bool is_email_verified = 9;
string phone = 11 [(validate.rules).string = {max_len: 20}];
bool is_phone_verified = 12;
string country = 13 [(validate.rules).string = {max_len: 200}];
string locality = 14 [(validate.rules).string = {max_len: 200}];
string postal_code = 15 [(validate.rules).string = {max_len: 200}];
string region = 16 [(validate.rules).string = {max_len: 200}];
string street_address = 17 [(validate.rules).string = {max_len: 200}];
string password = 18 [(validate.rules).string = {max_len: 72}];
string preferred_language = 5 [(validate.rules).string = {max_len: 200}];
Gender gender = 6;
string email = 7 [(validate.rules).string = {min_len: 1, max_len: 200, email: true}];
bool is_email_verified = 8;
string phone = 9 [(validate.rules).string = {max_len: 20}];
bool is_phone_verified = 10;
string country = 11 [(validate.rules).string = {max_len: 200}];
string locality = 12 [(validate.rules).string = {max_len: 200}];
string postal_code = 13 [(validate.rules).string = {max_len: 200}];
string region = 14 [(validate.rules).string = {max_len: 200}];
string street_address = 15 [(validate.rules).string = {max_len: 200}];
string password = 16 [(validate.rules).string = {max_len: 72}];
}
message User {

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -520,7 +520,7 @@
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/protobufStruct"
"type": "object"
}
}
},
@ -531,19 +531,6 @@
}
},
"definitions": {
"protobufListValue": {
"type": "object",
"properties": {
"values": {
"type": "array",
"items": {
"$ref": "#/definitions/protobufValue"
},
"description": "Repeated field of dynamically typed values."
}
},
"description": "`ListValue` is a wrapper around a repeated field of values.\n\nThe JSON representation for `ListValue` is JSON array."
},
"protobufNullValue": {
"type": "string",
"enum": [
@ -552,51 +539,6 @@
"default": "NULL_VALUE",
"description": "`NullValue` is a singleton enumeration to represent the null value for the\n`Value` type union.\n\n The JSON representation for `NullValue` is JSON `null`.\n\n - NULL_VALUE: Null value."
},
"protobufStruct": {
"type": "object",
"properties": {
"fields": {
"type": "object",
"additionalProperties": {
"$ref": "#/definitions/protobufValue"
},
"description": "Unordered map of dynamically typed values."
}
},
"description": "`Struct` represents a structured data value, consisting of fields\nwhich map to dynamically typed values. In some languages, `Struct`\nmight be supported by a native representation. For example, in\nscripting languages like JS a struct is represented as an\nobject. The details of that representation are described together\nwith the proto support for the language.\n\nThe JSON representation for `Struct` is JSON object."
},
"protobufValue": {
"type": "object",
"properties": {
"null_value": {
"$ref": "#/definitions/protobufNullValue",
"description": "Represents a null value."
},
"number_value": {
"type": "number",
"format": "double",
"description": "Represents a double value."
},
"string_value": {
"type": "string",
"description": "Represents a string value."
},
"bool_value": {
"type": "boolean",
"format": "boolean",
"description": "Represents a boolean value."
},
"struct_value": {
"$ref": "#/definitions/protobufStruct",
"description": "Represents a structured value."
},
"list_value": {
"$ref": "#/definitions/protobufListValue",
"description": "Represents a repeated `Value`."
}
},
"description": "`Value` represents a dynamically typed value which can be either\nnull, a number, a string, a boolean, a recursive struct value, or a\nlist of values. A producer of value is expected to set one of that\nvariants, absence of any variant indicates an error.\n\nThe JSON representation for `Value` is JSON value."
},
"v1Gender": {
"type": "string",
"enum": [
@ -826,9 +768,6 @@
"nick_name": {
"type": "string"
},
"display_name": {
"type": "string"
},
"preferred_language": {
"type": "string"
},

View File

@ -138,14 +138,14 @@ func (mr *MockAuthServiceClientMockRecorder) GetMyMfas(arg0, arg1 interface{}, a
}
// GetMyUserAddress mocks base method
func (m *MockAuthServiceClient) GetMyUserAddress(arg0 context.Context, arg1 *emptypb.Empty, arg2 ...grpc0.CallOption) (*grpc.UserAddress, error) {
func (m *MockAuthServiceClient) GetMyUserAddress(arg0 context.Context, arg1 *emptypb.Empty, arg2 ...grpc0.CallOption) (*grpc.UserAddressView, error) {
m.ctrl.T.Helper()
varargs := []interface{}{arg0, arg1}
for _, a := range arg2 {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "GetMyUserAddress", varargs...)
ret0, _ := ret[0].(*grpc.UserAddress)
ret0, _ := ret[0].(*grpc.UserAddressView)
ret1, _ := ret[1].(error)
return ret0, ret1
}
@ -158,14 +158,14 @@ func (mr *MockAuthServiceClientMockRecorder) GetMyUserAddress(arg0, arg1 interfa
}
// GetMyUserEmail mocks base method
func (m *MockAuthServiceClient) GetMyUserEmail(arg0 context.Context, arg1 *emptypb.Empty, arg2 ...grpc0.CallOption) (*grpc.UserEmail, error) {
func (m *MockAuthServiceClient) GetMyUserEmail(arg0 context.Context, arg1 *emptypb.Empty, arg2 ...grpc0.CallOption) (*grpc.UserEmailView, error) {
m.ctrl.T.Helper()
varargs := []interface{}{arg0, arg1}
for _, a := range arg2 {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "GetMyUserEmail", varargs...)
ret0, _ := ret[0].(*grpc.UserEmail)
ret0, _ := ret[0].(*grpc.UserEmailView)
ret1, _ := ret[1].(error)
return ret0, ret1
}
@ -178,14 +178,14 @@ func (mr *MockAuthServiceClientMockRecorder) GetMyUserEmail(arg0, arg1 interface
}
// GetMyUserPhone mocks base method
func (m *MockAuthServiceClient) GetMyUserPhone(arg0 context.Context, arg1 *emptypb.Empty, arg2 ...grpc0.CallOption) (*grpc.UserPhone, error) {
func (m *MockAuthServiceClient) GetMyUserPhone(arg0 context.Context, arg1 *emptypb.Empty, arg2 ...grpc0.CallOption) (*grpc.UserPhoneView, error) {
m.ctrl.T.Helper()
varargs := []interface{}{arg0, arg1}
for _, a := range arg2 {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "GetMyUserPhone", varargs...)
ret0, _ := ret[0].(*grpc.UserPhone)
ret0, _ := ret[0].(*grpc.UserPhoneView)
ret1, _ := ret[1].(error)
return ret0, ret1
}
@ -198,14 +198,14 @@ func (mr *MockAuthServiceClientMockRecorder) GetMyUserPhone(arg0, arg1 interface
}
// GetMyUserProfile mocks base method
func (m *MockAuthServiceClient) GetMyUserProfile(arg0 context.Context, arg1 *emptypb.Empty, arg2 ...grpc0.CallOption) (*grpc.UserProfile, error) {
func (m *MockAuthServiceClient) GetMyUserProfile(arg0 context.Context, arg1 *emptypb.Empty, arg2 ...grpc0.CallOption) (*grpc.UserProfileView, error) {
m.ctrl.T.Helper()
varargs := []interface{}{arg0, arg1}
for _, a := range arg2 {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "GetMyUserProfile", varargs...)
ret0, _ := ret[0].(*grpc.UserProfile)
ret0, _ := ret[0].(*grpc.UserProfileView)
ret1, _ := ret[1].(error)
return ret0, ret1
}

View File

@ -66,7 +66,6 @@ func updateProfileToModel(ctx context.Context, u *UpdateUserProfileRequest) *usr
FirstName: u.FirstName,
LastName: u.LastName,
NickName: u.NickName,
DisplayName: u.DisplayName,
PreferredLanguage: preferredLanguage,
Gender: genderToModel(u.Gender),
}

View File

@ -55,7 +55,7 @@ func (o *OPStorage) GetUserinfoFromScopes(ctx context.Context, userID string, sc
userInfo.FamilyName = user.LastName
userInfo.GivenName = user.FirstName
userInfo.Nickname = user.NickName
userInfo.PreferredUsername = user.UserName
userInfo.PreferredUsername = user.PreferredLoginName
userInfo.UpdatedAt = user.ChangeDate
userInfo.Gender = oidc.Gender(getGender(user.Gender))
case scopePhone:

Some files were not shown because too many files have changed in this diff Show More