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
@ -24,6 +24,7 @@ export ZITADEL_USER_VERIFICATION_KEY=UserVerificationKey_1
|
|||||||
export ZITADEL_OTP_VERIFICATION_KEY=OTPVerificationKey_1
|
export ZITADEL_OTP_VERIFICATION_KEY=OTPVerificationKey_1
|
||||||
export ZITADEL_OIDC_KEYS_ID=OIDCKey_1
|
export ZITADEL_OIDC_KEYS_ID=OIDCKey_1
|
||||||
export ZITADEL_COOKIE_KEY=CookieKey_1
|
export ZITADEL_COOKIE_KEY=CookieKey_1
|
||||||
|
export ZITADEL_CSRF_KEY=CookieKey_1
|
||||||
|
|
||||||
# Notifications
|
# Notifications
|
||||||
export DEBUG_MODE=TRUE
|
export DEBUG_MODE=TRUE
|
||||||
@ -47,6 +48,13 @@ export ZITADEL_CONSOLE=http://localhost:4200
|
|||||||
export CAOS_OIDC_DEV=true
|
export CAOS_OIDC_DEV=true
|
||||||
export ZITADEL_COOKIE_DOMAIN=localhost
|
export ZITADEL_COOKIE_DOMAIN=localhost
|
||||||
|
|
||||||
|
#CSRF
|
||||||
|
export ZITADEL_CSRF_DEV=true
|
||||||
|
|
||||||
|
#CACHE
|
||||||
|
export ZITADEL_CACHE_MAXAGE=12h
|
||||||
|
export ZITADEL_CACHE_SHARED_MAXAGE=168h
|
||||||
|
|
||||||
#Console
|
#Console
|
||||||
export ZITADEL_CONSOLE_ENV_DIR=../../console/src/assets/
|
export ZITADEL_CONSOLE_ENV_DIR=../../console/src/assets/
|
||||||
|
|
||||||
|
@ -66,6 +66,9 @@ Auth:
|
|||||||
Domain: $ZITADEL_COOKIE_DOMAIN
|
Domain: $ZITADEL_COOKIE_DOMAIN
|
||||||
Key:
|
Key:
|
||||||
EncryptionKeyID: $ZITADEL_COOKIE_KEY
|
EncryptionKeyID: $ZITADEL_COOKIE_KEY
|
||||||
|
Cache:
|
||||||
|
MaxAge: $ZITADEL_CACHE_MAXAGE
|
||||||
|
SharedMaxAge: $ZITADEL_CACHE_SHARED_MAXAGE
|
||||||
Endpoints:
|
Endpoints:
|
||||||
Auth:
|
Auth:
|
||||||
Path: 'authorize'
|
Path: 'authorize'
|
||||||
@ -129,6 +132,14 @@ Login:
|
|||||||
ZitadelURL: '$ZITADEL_CONSOLE'
|
ZitadelURL: '$ZITADEL_CONSOLE'
|
||||||
LanguageCookieName: 'caos.zitadel.login.lang'
|
LanguageCookieName: 'caos.zitadel.login.lang'
|
||||||
DefaultLanguage: 'de'
|
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:
|
AuthZ:
|
||||||
|
1
go.mod
@ -23,6 +23,7 @@ require (
|
|||||||
github.com/ghodss/yaml v1.0.0
|
github.com/ghodss/yaml v1.0.0
|
||||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b
|
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b
|
||||||
github.com/golang/mock v1.4.3
|
github.com/golang/mock v1.4.3
|
||||||
|
github.com/gorilla/csrf v1.7.0
|
||||||
github.com/golang/protobuf v1.4.2
|
github.com/golang/protobuf v1.4.2
|
||||||
github.com/gorilla/mux v1.7.4
|
github.com/gorilla/mux v1.7.4
|
||||||
github.com/gorilla/schema v1.1.0
|
github.com/gorilla/schema v1.1.0
|
||||||
|
3
go.sum
@ -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.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 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM=
|
||||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
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 h1:0QniY0USkHQ1RGCLfKxeNHK9bkDHGRYGNDFBCS+YARg=
|
||||||
github.com/gorilla/handlers v1.4.2/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ=
|
github.com/gorilla/handlers v1.4.2/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ=
|
||||||
github.com/gorilla/mux v1.7.4 h1:VuZ8uybHlWmqV03+zRzdwKL4tUnIp1MAQtp1mIFE1bc=
|
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/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/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.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/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 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
@ -76,6 +76,7 @@ func createMux(ctx context.Context, g Gateway) *runtime.ServeMux {
|
|||||||
|
|
||||||
func addInterceptors(handler http.Handler, g Gateway) http.Handler {
|
func addInterceptors(handler http.Handler, g Gateway) http.Handler {
|
||||||
handler = http_mw.DefaultTraceHandler(handler)
|
handler = http_mw.DefaultTraceHandler(handler)
|
||||||
|
handler = http_mw.NoCacheInterceptor(handler)
|
||||||
if interceptor, ok := g.(grpcGatewayCustomInterceptor); ok {
|
if interceptor, ok := g.(grpcGatewayCustomInterceptor); ok {
|
||||||
handler = interceptor.GatewayHTTPInterceptor(handler)
|
handler = interceptor.GatewayHTTPInterceptor(handler)
|
||||||
}
|
}
|
||||||
|
@ -4,12 +4,23 @@ const (
|
|||||||
Authorization = "authorization"
|
Authorization = "authorization"
|
||||||
Accept = "accept"
|
Accept = "accept"
|
||||||
AcceptLanguage = "accept-language"
|
AcceptLanguage = "accept-language"
|
||||||
|
CacheControl = "cache-control"
|
||||||
ContentType = "content-type"
|
ContentType = "content-type"
|
||||||
|
Expires = "expires"
|
||||||
Location = "location"
|
Location = "location"
|
||||||
Origin = "origin"
|
Origin = "origin"
|
||||||
|
Pragma = "pragma"
|
||||||
UserAgent = "user-agent"
|
UserAgent = "user-agent"
|
||||||
ForwardedFor = "x-forwarded-for"
|
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"
|
ZitadelOrgID = "x-zitadel-orgid"
|
||||||
//TODO: Remove as soon an authentification is implemented
|
//TODO: Remove as soon an authentification is implemented
|
||||||
ZitadelUserID = "x-zitadel-userid"
|
ZitadelUserID = "x-zitadel-userid"
|
||||||
|
128
internal/api/http/middleware/cache_interceptor.go
Normal 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")
|
||||||
|
}
|
||||||
|
}
|
82
internal/api/http/middleware/cache_interceptor_test.go
Normal 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)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
125
internal/api/http/middleware/csp.go
Normal 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...)
|
||||||
|
}
|
90
internal/api/http/middleware/security_headers.go
Normal 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)
|
||||||
|
}
|
@ -25,11 +25,11 @@ type UserAgentCookieConfig struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewUserAgentHandler(config *UserAgentCookieConfig, idGenerator id.Generator) (*UserAgentHandler, error) {
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
cookieKey := []byte(keys[config.Key.EncryptionKeyID])
|
cookieKey := []byte(key)
|
||||||
handler := NewCookieHandler(
|
handler := NewCookieHandler(
|
||||||
WithEncryption(cookieKey, cookieKey),
|
WithEncryption(cookieKey, cookieKey),
|
||||||
WithDomain(config.Domain),
|
WithDomain(config.Domain),
|
||||||
|
@ -13,7 +13,7 @@ type AuthRequestRepository interface {
|
|||||||
AuthRequestByCode(ctx context.Context, code string) (*model.AuthRequest, error)
|
AuthRequestByCode(ctx context.Context, code string) (*model.AuthRequest, error)
|
||||||
SaveAuthCode(ctx context.Context, id, code string) error
|
SaveAuthCode(ctx context.Context, id, code string) error
|
||||||
DeleteAuthRequest(ctx context.Context, id 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
|
SelectUser(ctx context.Context, id, userID string) error
|
||||||
VerifyPassword(ctx context.Context, id, userID, password string, info *model.BrowserInfo) 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
|
VerifyMfaOTP(ctx context.Context, agentID, authRequestID string, code string, info *model.BrowserInfo) error
|
||||||
|
@ -106,16 +106,16 @@ func (repo *AuthRequestRepo) DeleteAuthRequest(ctx context.Context, id string) e
|
|||||||
return repo.AuthRequests.DeleteAuthRequest(ctx, id)
|
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)
|
request, err := repo.AuthRequests.GetAuthRequestByID(ctx, id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
user, err := repo.View.UserByLoginName(username)
|
user, err := repo.View.UserByLoginName(loginName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
request.SetUserInfo(user.ID, user.UserName, user.ResourceOwner)
|
request.SetUserInfo(user.ID, loginName, user.ResourceOwner)
|
||||||
return repo.AuthRequests.UpdateAuthRequest(ctx, request)
|
return repo.AuthRequests.UpdateAuthRequest(ctx, request)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,7 +128,7 @@ func (repo *AuthRequestRepo) SelectUser(ctx context.Context, id, userID string)
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
request.SetUserInfo(user.ID, user.UserName, user.ResourceOwner)
|
request.SetUserInfo(user.ID, user.PreferredLoginName, user.ResourceOwner)
|
||||||
return repo.AuthRequests.UpdateAuthRequest(ctx, request)
|
return repo.AuthRequests.UpdateAuthRequest(ctx, request)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -236,7 +236,8 @@ func (repo *AuthRequestRepo) usersForUserSelection(request *model.AuthRequest) (
|
|||||||
for i, session := range userSessions {
|
for i, session := range userSessions {
|
||||||
users[i] = model.UserSelection{
|
users[i] = model.UserSelection{
|
||||||
UserID: session.UserID,
|
UserID: session.UserID,
|
||||||
UserName: session.UserName,
|
DisplayName: session.DisplayName,
|
||||||
|
LoginName: session.LoginName,
|
||||||
UserSessionState: session.State,
|
UserSessionState: session.State,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -46,8 +46,8 @@ type mockViewUserSession struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type mockUser struct {
|
type mockUser struct {
|
||||||
UserID string
|
UserID string
|
||||||
UserName string
|
LoginName string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *mockViewUserSession) UserSessionByIDs(string, string) (*view_model.UserSessionView, error) {
|
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))
|
sessions := make([]*view_model.UserSessionView, len(m.Users))
|
||||||
for i, user := range m.Users {
|
for i, user := range m.Users {
|
||||||
sessions[i] = &view_model.UserSessionView{
|
sessions[i] = &view_model.UserSessionView{
|
||||||
UserID: user.UserID,
|
UserID: user.UserID,
|
||||||
UserName: user.UserName,
|
LoginName: user.LoginName,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return sessions, nil
|
return sessions, nil
|
||||||
@ -175,11 +175,11 @@ func TestAuthRequestRepo_nextSteps(t *testing.T) {
|
|||||||
Users: []mockUser{
|
Users: []mockUser{
|
||||||
{
|
{
|
||||||
"id1",
|
"id1",
|
||||||
"username1",
|
"loginname1",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id2",
|
"id2",
|
||||||
"username2",
|
"loginname2",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -191,12 +191,12 @@ func TestAuthRequestRepo_nextSteps(t *testing.T) {
|
|||||||
&model.SelectUserStep{
|
&model.SelectUserStep{
|
||||||
Users: []model.UserSelection{
|
Users: []model.UserSelection{
|
||||||
{
|
{
|
||||||
UserID: "id1",
|
UserID: "id1",
|
||||||
UserName: "username1",
|
LoginName: "loginname1",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
UserID: "id2",
|
UserID: "id2",
|
||||||
UserName: "username2",
|
LoginName: "loginname2",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}},
|
}},
|
||||||
|
@ -203,8 +203,8 @@ func (repo *UserRepo) SkipMfaInit(ctx context.Context, userID string) error {
|
|||||||
return repo.UserEvents.SkipMfaInit(ctx, userID)
|
return repo.UserEvents.SkipMfaInit(ctx, userID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (repo *UserRepo) RequestPasswordReset(ctx context.Context, username string) error {
|
func (repo *UserRepo) RequestPasswordReset(ctx context.Context, loginname string) error {
|
||||||
user, err := repo.View.UserByUsername(username)
|
user, err := repo.View.UserByLoginName(loginname)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -67,7 +67,8 @@ func (u *UserSession) Process(event *models.Event) (err error) {
|
|||||||
}
|
}
|
||||||
return u.updateSession(session, event)
|
return u.updateSession(session, event)
|
||||||
case es_model.UserPasswordChanged,
|
case es_model.UserPasswordChanged,
|
||||||
es_model.MfaOtpRemoved:
|
es_model.MfaOtpRemoved,
|
||||||
|
es_model.UserProfileChanged:
|
||||||
sessions, err := u.view.UserSessionsByUserID(event.AggregateID)
|
sessions, err := u.view.UserSessionsByUserID(event.AggregateID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
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 {
|
func (u *UserSession) updateSession(session *view_model.UserSessionView, event *models.Event) error {
|
||||||
session.Sequence = event.Sequence
|
session.Sequence = event.Sequence
|
||||||
session.AppendEvent(event)
|
session.AppendEvent(event)
|
||||||
if session.UserName == "" {
|
if err := u.fillUserInfo(session, event.AggregateID); err != nil {
|
||||||
if err := u.fillUserInfo(session, event.AggregateID); err != nil {
|
return err
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return u.view.PutUserSession(session)
|
return u.view.PutUserSession(session)
|
||||||
}
|
}
|
||||||
@ -105,5 +104,7 @@ func (u *UserSession) fillUserInfo(session *view_model.UserSessionView, id strin
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
session.UserName = user.UserName
|
session.UserName = user.UserName
|
||||||
|
session.LoginName = user.PreferredLoginName
|
||||||
|
session.DisplayName = user.DisplayName
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@ type AuthRequest struct {
|
|||||||
|
|
||||||
levelOfAssurance LevelOfAssurance
|
levelOfAssurance LevelOfAssurance
|
||||||
UserID string
|
UserID string
|
||||||
UserName string
|
LoginName string
|
||||||
UserOrgID string
|
UserOrgID string
|
||||||
PossibleSteps []NextStep
|
PossibleSteps []NextStep
|
||||||
PasswordVerified bool
|
PasswordVerified bool
|
||||||
@ -96,8 +96,8 @@ func (a *AuthRequest) WithCurrentInfo(info *BrowserInfo) *AuthRequest {
|
|||||||
return a
|
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.UserID = userID
|
||||||
a.UserName = userName
|
a.LoginName = loginName
|
||||||
a.UserOrgID = userOrgID
|
a.UserOrgID = userOrgID
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,8 @@ func (s *SelectUserStep) Type() NextStepType {
|
|||||||
|
|
||||||
type UserSelection struct {
|
type UserSelection struct {
|
||||||
UserID string
|
UserID string
|
||||||
UserName string
|
DisplayName string
|
||||||
|
LoginName string
|
||||||
UserSessionState UserSessionState
|
UserSessionState UserSessionState
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,6 +33,14 @@ func ReadKeys(path string) (Keys, error) {
|
|||||||
return *keys, err
|
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) {
|
func LoadKeys(config *KeyConfig) (map[string]string, []string, error) {
|
||||||
if config == nil {
|
if config == nil {
|
||||||
return nil, nil, errors.ThrowInvalidArgument(nil, "CRYPT-dJK8s", "config must not be nil")
|
return nil, nil, errors.ThrowInvalidArgument(nil, "CRYPT-dJK8s", "config must not be nil")
|
||||||
|
@ -36,8 +36,8 @@ func (l *Login) renderChangePassword(w http.ResponseWriter, r *http.Request, aut
|
|||||||
errMessage = l.getErrorMessage(r, err)
|
errMessage = l.getErrorMessage(r, err)
|
||||||
}
|
}
|
||||||
data := userData{
|
data := userData{
|
||||||
baseData: l.getBaseData(r, authReq, "Change Password", errType, errMessage),
|
baseData: l.getBaseData(r, authReq, "Change Password", errType, errMessage),
|
||||||
UserName: authReq.UserName,
|
LoginName: authReq.LoginName,
|
||||||
}
|
}
|
||||||
l.renderer.RenderTemplate(w, r, l.renderer.Templates[tmplChangePassword], data, nil)
|
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) {
|
func (l *Login) renderChangePasswordDone(w http.ResponseWriter, r *http.Request, authReq *model.AuthRequest) {
|
||||||
var errType, errMessage string
|
var errType, errMessage string
|
||||||
data := userData{
|
data := userData{
|
||||||
baseData: l.getBaseData(r, authReq, "Password Change Done", errType, errMessage),
|
baseData: l.getBaseData(r, authReq, "Password Change Done", errType, errMessage),
|
||||||
UserName: authReq.UserName,
|
LoginName: authReq.LoginName,
|
||||||
}
|
}
|
||||||
l.renderer.RenderTemplate(w, r, l.renderer.Templates[tmplChangePasswordDone], data, nil)
|
l.renderer.RenderTemplate(w, r, l.renderer.Templates[tmplChangePasswordDone], data, nil)
|
||||||
}
|
}
|
||||||
|
@ -72,7 +72,7 @@ func (l *Login) resendPasswordSet(w http.ResponseWriter, r *http.Request, authRe
|
|||||||
if authReq != nil {
|
if authReq != nil {
|
||||||
userOrg = authReq.UserOrgID
|
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)
|
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) {
|
func (l *Login) renderInitPasswordDone(w http.ResponseWriter, r *http.Request, authReq *model.AuthRequest) {
|
||||||
data := userData{
|
data := userData{
|
||||||
baseData: l.getBaseData(r, authReq, "Password Init Done", "", ""),
|
baseData: l.getBaseData(r, authReq, "Password Init Done", "", ""),
|
||||||
UserName: authReq.UserName,
|
LoginName: authReq.LoginName,
|
||||||
}
|
}
|
||||||
l.renderer.RenderTemplate(w, r, l.renderer.Templates[tmplInitPasswordDone], data, nil)
|
l.renderer.RenderTemplate(w, r, l.renderer.Templates[tmplInitPasswordDone], data, nil)
|
||||||
}
|
}
|
||||||
|
@ -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) {
|
func (l *Login) renderInitUserDone(w http.ResponseWriter, r *http.Request, authReq *model.AuthRequest) {
|
||||||
var userName string
|
var loginName string
|
||||||
if authReq != nil {
|
if authReq != nil {
|
||||||
userName = authReq.UserName
|
loginName = authReq.LoginName
|
||||||
}
|
}
|
||||||
data := userData{
|
data := userData{
|
||||||
baseData: l.getBaseData(r, authReq, "User Init Done", "", ""),
|
baseData: l.getBaseData(r, authReq, "User Init Done", "", ""),
|
||||||
UserName: userName,
|
LoginName: loginName,
|
||||||
}
|
}
|
||||||
l.renderer.RenderTemplate(w, r, l.renderer.Templates[tmplInitUserDone], data, nil)
|
l.renderer.RenderTemplate(w, r, l.renderer.Templates[tmplInitUserDone], data, nil)
|
||||||
}
|
}
|
||||||
|
@ -6,12 +6,14 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/caos/logging"
|
"github.com/caos/logging"
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/csrf"
|
||||||
"github.com/rakyll/statik/fs"
|
"github.com/rakyll/statik/fs"
|
||||||
"golang.org/x/text/language"
|
"golang.org/x/text/language"
|
||||||
|
|
||||||
"github.com/caos/zitadel/internal/api/auth"
|
"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/auth/repository/eventsourcing"
|
||||||
|
"github.com/caos/zitadel/internal/crypto"
|
||||||
"github.com/caos/zitadel/internal/form"
|
"github.com/caos/zitadel/internal/form"
|
||||||
|
|
||||||
_ "github.com/caos/zitadel/internal/login/statik"
|
_ "github.com/caos/zitadel/internal/login/statik"
|
||||||
@ -19,7 +21,7 @@ import (
|
|||||||
|
|
||||||
type Login struct {
|
type Login struct {
|
||||||
endpoint string
|
endpoint string
|
||||||
router *mux.Router
|
router http.Handler
|
||||||
renderer *Renderer
|
renderer *Renderer
|
||||||
parser *form.Parser
|
parser *form.Parser
|
||||||
authRepo *eventsourcing.EsRepository
|
authRepo *eventsourcing.EsRepository
|
||||||
@ -33,6 +35,14 @@ type Config struct {
|
|||||||
ZitadelURL string
|
ZitadelURL string
|
||||||
LanguageCookieName string
|
LanguageCookieName string
|
||||||
DefaultLanguage language.Tag
|
DefaultLanguage language.Tag
|
||||||
|
CSRF CSRF
|
||||||
|
Cache middleware.CacheConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
type CSRF struct {
|
||||||
|
CookieName string
|
||||||
|
Key *crypto.KeyConfig
|
||||||
|
Development bool
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -47,14 +57,39 @@ func StartLogin(ctx context.Context, config Config, authRepo *eventsourcing.EsRe
|
|||||||
authRepo: authRepo,
|
authRepo: authRepo,
|
||||||
}
|
}
|
||||||
statikFS, err := fs.NewWithNamespace("login")
|
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.renderer = CreateRenderer(statikFS, config.LanguageCookieName, config.DefaultLanguage)
|
||||||
login.parser = form.NewParser()
|
login.parser = form.NewParser()
|
||||||
login.Listen(ctx)
|
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) {
|
func (l *Login) Listen(ctx context.Context) {
|
||||||
if l.endpoint == "" {
|
if l.endpoint == "" {
|
||||||
l.endpoint = ":80"
|
l.endpoint = ":80"
|
||||||
|
@ -10,7 +10,7 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type loginData struct {
|
type loginData struct {
|
||||||
UserName string `schema:"username"`
|
LoginName string `schema:"loginName"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Login) handleLogin(w http.ResponseWriter, r *http.Request) {
|
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)
|
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)
|
authSession, err := l.getAuthRequest(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
l.renderError(w, r, authSession, err)
|
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)
|
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)
|
data := new(loginData)
|
||||||
authReq, err := l.getAuthRequestAndParseData(r, data)
|
authReq, err := l.getAuthRequestAndParseData(r, data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
l.renderError(w, r, authReq, err)
|
l.renderError(w, r, authReq, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
err = l.authRepo.CheckUsername(r.Context(), authReq.ID, data.UserName)
|
err = l.authRepo.CheckLoginName(r.Context(), authReq.ID, data.LoginName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
l.renderLogin(w, r, authReq, err)
|
l.renderLogin(w, r, authReq, err)
|
||||||
return
|
return
|
||||||
@ -56,8 +56,8 @@ func (l *Login) renderLogin(w http.ResponseWriter, r *http.Request, authReq *mod
|
|||||||
errMessage = l.getErrorMessage(r, err)
|
errMessage = l.getErrorMessage(r, err)
|
||||||
}
|
}
|
||||||
data := userData{
|
data := userData{
|
||||||
baseData: l.getBaseData(r, authReq, "Login", errType, errMessage),
|
baseData: l.getBaseData(r, authReq, "Login", errType, errMessage),
|
||||||
UserName: authReq.UserName,
|
LoginName: authReq.LoginName,
|
||||||
}
|
}
|
||||||
l.renderer.RenderTemplate(w, r, l.renderer.Templates[tmplLogin], data, nil)
|
l.renderer.RenderTemplate(w, r, l.renderer.Templates[tmplLogin], data, nil)
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,6 @@ type mfaInitDoneData struct {
|
|||||||
func (l *Login) renderMfaInitDone(w http.ResponseWriter, r *http.Request, authReq *model.AuthRequest, data *mfaDoneData) {
|
func (l *Login) renderMfaInitDone(w http.ResponseWriter, r *http.Request, authReq *model.AuthRequest, data *mfaDoneData) {
|
||||||
var errType, errMessage string
|
var errType, errMessage string
|
||||||
data.baseData = l.getBaseData(r, authReq, "Mfa Init Done", errType, errMessage)
|
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)
|
l.renderer.RenderTemplate(w, r, l.renderer.Templates[tmplMfaInitDone], data, nil)
|
||||||
}
|
}
|
||||||
|
@ -4,10 +4,11 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/aaronarduino/goqrsvg"
|
|
||||||
svg "github.com/ajstarks/svgo"
|
svg "github.com/ajstarks/svgo"
|
||||||
"github.com/boombuler/barcode/qr"
|
"github.com/boombuler/barcode/qr"
|
||||||
|
|
||||||
"github.com/caos/zitadel/internal/auth_request/model"
|
"github.com/caos/zitadel/internal/auth_request/model"
|
||||||
|
"github.com/caos/zitadel/internal/qrcode"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -67,7 +68,7 @@ func (l *Login) renderMfaInitVerify(w http.ResponseWriter, r *http.Request, auth
|
|||||||
errMessage = l.getErrorMessage(r, err)
|
errMessage = l.getErrorMessage(r, err)
|
||||||
}
|
}
|
||||||
data.baseData = l.getBaseData(r, authReq, "Mfa Init Verify", errType, errMessage)
|
data.baseData = l.getBaseData(r, authReq, "Mfa Init Verify", errType, errMessage)
|
||||||
data.UserName = authReq.UserName
|
data.LoginName = authReq.LoginName
|
||||||
if data.MfaType == model.MfaTypeOTP {
|
if data.MfaType == model.MfaTypeOTP {
|
||||||
code, err := generateQrCode(data.otpData.Url)
|
code, err := generateQrCode(data.otpData.Url)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
@ -86,7 +87,7 @@ func generateQrCode(url string) (string, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
qs := goqrsvg.NewQrSVG(qrCode, 5)
|
qs := qrcode.NewQrSVG(qrCode, 5)
|
||||||
qs.StartQrSVG(s)
|
qs.StartQrSVG(s)
|
||||||
qs.WriteQrSVG(s)
|
qs.WriteQrSVG(s)
|
||||||
|
|
||||||
|
@ -42,8 +42,8 @@ func (l *Login) renderMfaPrompt(w http.ResponseWriter, r *http.Request, authSess
|
|||||||
errMessage = l.getErrorMessage(r, err)
|
errMessage = l.getErrorMessage(r, err)
|
||||||
}
|
}
|
||||||
data := mfaData{
|
data := mfaData{
|
||||||
baseData: l.getBaseData(r, authSession, "Mfa Prompt", errType, errMessage),
|
baseData: l.getBaseData(r, authSession, "Mfa Prompt", errType, errMessage),
|
||||||
UserName: authSession.UserName,
|
LoginName: authSession.LoginName,
|
||||||
}
|
}
|
||||||
|
|
||||||
if mfaPromptData == nil {
|
if mfaPromptData == nil {
|
||||||
|
@ -38,8 +38,8 @@ func (l *Login) renderMfaVerify(w http.ResponseWriter, r *http.Request, authReq
|
|||||||
errMessage = l.getErrorMessage(r, err)
|
errMessage = l.getErrorMessage(r, err)
|
||||||
}
|
}
|
||||||
data := userData{
|
data := userData{
|
||||||
baseData: l.getBaseData(r, authReq, "Mfa Verify", errType, errMessage),
|
baseData: l.getBaseData(r, authReq, "Mfa Verify", errType, errMessage),
|
||||||
UserName: authReq.UserName,
|
LoginName: authReq.LoginName,
|
||||||
}
|
}
|
||||||
if verificationStep != nil {
|
if verificationStep != nil {
|
||||||
data.MfaProviders = verificationStep.MfaProviders
|
data.MfaProviders = verificationStep.MfaProviders
|
||||||
|
@ -20,8 +20,8 @@ func (l *Login) renderPassword(w http.ResponseWriter, r *http.Request, authReq *
|
|||||||
errMessage = l.getErrorMessage(r, err)
|
errMessage = l.getErrorMessage(r, err)
|
||||||
}
|
}
|
||||||
data := userData{
|
data := userData{
|
||||||
baseData: l.getBaseData(r, authReq, "Password", errType, errMessage),
|
baseData: l.getBaseData(r, authReq, "Password", errType, errMessage),
|
||||||
UserName: authReq.UserName,
|
LoginName: authReq.LoginName,
|
||||||
}
|
}
|
||||||
l.renderer.RenderTemplate(w, r, l.renderer.Templates[tmplPassword], data, nil)
|
l.renderer.RenderTemplate(w, r, l.renderer.Templates[tmplPassword], data, nil)
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ func (l *Login) handlePasswordReset(w http.ResponseWriter, r *http.Request) {
|
|||||||
l.renderError(w, r, authReq, err)
|
l.renderError(w, r, authReq, err)
|
||||||
return
|
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)
|
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)
|
errMessage = l.getErrorMessage(r, err)
|
||||||
}
|
}
|
||||||
data := userData{
|
data := userData{
|
||||||
baseData: l.getBaseData(r, authReq, "Password Reset Done", errType, errMessage),
|
baseData: l.getBaseData(r, authReq, "Password Reset Done", errType, errMessage),
|
||||||
UserName: authReq.UserName,
|
LoginName: authReq.LoginName,
|
||||||
}
|
}
|
||||||
l.renderer.RenderTemplate(w, r, l.renderer.Templates[tmplPasswordResetDone], data, nil)
|
l.renderer.RenderTemplate(w, r, l.renderer.Templates[tmplPasswordResetDone], data, nil)
|
||||||
}
|
}
|
||||||
|
@ -71,7 +71,7 @@ func (l *Login) handleRegisterCheck(w http.ResponseWriter, r *http.Request) {
|
|||||||
http.Redirect(w, r, l.zitadelURL, http.StatusFound)
|
http.Redirect(w, r, l.zitadelURL, http.StatusFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
authRequest.UserName = user.UserName
|
authRequest.LoginName = user.PreferredLoginName
|
||||||
l.renderNextStep(w, r, authRequest)
|
l.renderNextStep(w, r, authRequest)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,6 +3,11 @@ package handler
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"html/template"
|
||||||
|
|
||||||
|
"github.com/gorilla/csrf"
|
||||||
|
|
||||||
|
"github.com/caos/zitadel/internal/api/http/middleware"
|
||||||
"github.com/caos/zitadel/internal/auth_request/model"
|
"github.com/caos/zitadel/internal/auth_request/model"
|
||||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||||
"github.com/caos/zitadel/internal/i18n"
|
"github.com/caos/zitadel/internal/i18n"
|
||||||
@ -58,11 +63,11 @@ func CreateRenderer(staticDir http.FileSystem, cookieName string, defaultLanguag
|
|||||||
"registerUrl": func(id string) string {
|
"registerUrl": func(id string) string {
|
||||||
return fmt.Sprintf("%s?%s=%s", EndpointRegister, queryAuthRequestID, id)
|
return fmt.Sprintf("%s?%s=%s", EndpointRegister, queryAuthRequestID, id)
|
||||||
},
|
},
|
||||||
"usernameUrl": func() string {
|
"loginNameUrl": func() string {
|
||||||
return EndpointUsername
|
return EndpointLoginName
|
||||||
},
|
},
|
||||||
"usernameChangeUrl": func(id string) string {
|
"loginNameChangeUrl": func(id string) string {
|
||||||
return fmt.Sprintf("%s?%s=%s", EndpointUsername, queryAuthRequestID, id)
|
return fmt.Sprintf("%s?%s=%s", EndpointLoginName, queryAuthRequestID, id)
|
||||||
},
|
},
|
||||||
"userSelectionUrl": func() string {
|
"userSelectionUrl": func() string {
|
||||||
return EndpointUserSelection
|
return EndpointUserSelection
|
||||||
@ -189,6 +194,8 @@ func (l *Login) getBaseData(r *http.Request, authReq *model.AuthRequest, title s
|
|||||||
Theme: l.getTheme(r),
|
Theme: l.getTheme(r),
|
||||||
ThemeMode: l.getThemeMode(r),
|
ThemeMode: l.getThemeMode(r),
|
||||||
AuthReqID: getRequestID(authReq, 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)
|
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 {
|
type baseData struct {
|
||||||
errorData
|
errorData
|
||||||
Lang string
|
Lang string
|
||||||
@ -224,6 +244,8 @@ type baseData struct {
|
|||||||
Theme string
|
Theme string
|
||||||
ThemeMode string
|
ThemeMode string
|
||||||
AuthReqID string
|
AuthReqID string
|
||||||
|
CSRF template.HTML
|
||||||
|
Nonce string
|
||||||
}
|
}
|
||||||
|
|
||||||
type errorData struct {
|
type errorData struct {
|
||||||
@ -233,7 +255,7 @@ type errorData struct {
|
|||||||
|
|
||||||
type userData struct {
|
type userData struct {
|
||||||
baseData
|
baseData
|
||||||
UserName string
|
LoginName string
|
||||||
PasswordChecked string
|
PasswordChecked string
|
||||||
MfaProviders []model.MfaType
|
MfaProviders []model.MfaType
|
||||||
SelectedMfaProvider model.MfaType
|
SelectedMfaProvider model.MfaType
|
||||||
@ -246,22 +268,22 @@ type userSelectionData struct {
|
|||||||
|
|
||||||
type mfaData struct {
|
type mfaData struct {
|
||||||
baseData
|
baseData
|
||||||
UserName string
|
LoginName string
|
||||||
MfaProviders []model.MfaType
|
MfaProviders []model.MfaType
|
||||||
MfaRequired bool
|
MfaRequired bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type mfaVerifyData struct {
|
type mfaVerifyData struct {
|
||||||
baseData
|
baseData
|
||||||
UserName string
|
LoginName string
|
||||||
MfaType model.MfaType
|
MfaType model.MfaType
|
||||||
otpData
|
otpData
|
||||||
}
|
}
|
||||||
|
|
||||||
type mfaDoneData struct {
|
type mfaDoneData struct {
|
||||||
baseData
|
baseData
|
||||||
UserName string
|
LoginName string
|
||||||
MfaType model.MfaType
|
MfaType model.MfaType
|
||||||
}
|
}
|
||||||
|
|
||||||
type otpData struct {
|
type otpData struct {
|
||||||
|
@ -11,7 +11,7 @@ const (
|
|||||||
EndpointHealthz = "/healthz"
|
EndpointHealthz = "/healthz"
|
||||||
EndpointReadiness = "/ready"
|
EndpointReadiness = "/ready"
|
||||||
EndpointLogin = "/login"
|
EndpointLogin = "/login"
|
||||||
EndpointUsername = "/username"
|
EndpointLoginName = "/loginname"
|
||||||
EndpointUserSelection = "/userselection"
|
EndpointUserSelection = "/userselection"
|
||||||
EndpointPassword = "/password"
|
EndpointPassword = "/password"
|
||||||
EndpointInitPassword = "/password/init"
|
EndpointInitPassword = "/password/init"
|
||||||
@ -29,14 +29,15 @@ const (
|
|||||||
EndpointResources = "/resources"
|
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 := mux.NewRouter()
|
||||||
|
router.Use(interceptors...)
|
||||||
router.HandleFunc(EndpointRoot, login.handleLogin).Methods(http.MethodGet)
|
router.HandleFunc(EndpointRoot, login.handleLogin).Methods(http.MethodGet)
|
||||||
router.HandleFunc(EndpointHealthz, login.handleHealthz).Methods(http.MethodGet)
|
router.HandleFunc(EndpointHealthz, login.handleHealthz).Methods(http.MethodGet)
|
||||||
router.HandleFunc(EndpointReadiness, login.handleReadiness).Methods(http.MethodGet)
|
router.HandleFunc(EndpointReadiness, login.handleReadiness).Methods(http.MethodGet)
|
||||||
router.HandleFunc(EndpointLogin, login.handleLogin).Methods(http.MethodGet, http.MethodPost)
|
router.HandleFunc(EndpointLogin, login.handleLogin).Methods(http.MethodGet, http.MethodPost)
|
||||||
router.HandleFunc(EndpointUsername, login.handleUsername).Methods(http.MethodGet)
|
router.HandleFunc(EndpointLoginName, login.handleLoginName).Methods(http.MethodGet)
|
||||||
router.HandleFunc(EndpointUsername, login.handleUsernameCheck).Methods(http.MethodPost)
|
router.HandleFunc(EndpointLoginName, login.handleLoginNameCheck).Methods(http.MethodPost)
|
||||||
router.HandleFunc(EndpointUserSelection, login.handleSelectUser).Methods(http.MethodPost)
|
router.HandleFunc(EndpointUserSelection, login.handleSelectUser).Methods(http.MethodPost)
|
||||||
router.HandleFunc(EndpointPassword, login.handlePasswordCheck).Methods(http.MethodPost)
|
router.HandleFunc(EndpointPassword, login.handlePasswordCheck).Methods(http.MethodPost)
|
||||||
router.HandleFunc(EndpointInitPassword, login.handleInitPassword).Methods(http.MethodGet)
|
router.HandleFunc(EndpointInitPassword, login.handleInitPassword).Methods(http.MethodGet)
|
||||||
|
@ -6,7 +6,6 @@ Password:
|
|||||||
Login:
|
Login:
|
||||||
Title: Anmeldung
|
Title: Anmeldung
|
||||||
Description: Gib deine Benutzerdaten ein.
|
Description: Gib deine Benutzerdaten ein.
|
||||||
Username: Benutzername
|
|
||||||
Loginname: Loginname
|
Loginname: Loginname
|
||||||
LoginnamePlaceHolder: username@domain
|
LoginnamePlaceHolder: username@domain
|
||||||
|
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
Login:
|
Login:
|
||||||
Title: Login
|
Title: Login
|
||||||
Description: Enter your logindata.
|
Description: Enter your logindata.
|
||||||
Username: Username
|
|
||||||
Loginname: Loginname
|
Loginname: Loginname
|
||||||
LoginnamePlaceHolder: username@domain
|
LoginnamePlaceHolder: username@domain
|
||||||
|
|
||||||
@ -91,7 +90,7 @@ EmailVerificationDone:
|
|||||||
|
|
||||||
Registration:
|
Registration:
|
||||||
Title: 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
|
Email: E-Mail
|
||||||
Firstname: Firstname
|
Firstname: Firstname
|
||||||
Lastname: Lastname
|
Lastname: Lastname
|
||||||
|
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 2.4 KiB |
BIN
internal/login/static/resources/images/icon-newuser-dark.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
internal/login/static/resources/images/icon-newuser-dark@2x.png
Normal file
After Width: | Height: | Size: 2.4 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 2.4 KiB |
BIN
internal/login/static/resources/images/icon-newuser-light.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
internal/login/static/resources/images/icon-newuser-light@2x.png
Normal file
After Width: | Height: | Size: 2.4 KiB |
BIN
internal/login/static/resources/images/icon-user-dark-hover.png
Normal file
After Width: | Height: | Size: 4.8 KiB |
After Width: | Height: | Size: 9.0 KiB |
BIN
internal/login/static/resources/images/icon-user-dark.png
Normal file
After Width: | Height: | Size: 4.8 KiB |
BIN
internal/login/static/resources/images/icon-user-dark@2x.png
Normal file
After Width: | Height: | Size: 9.0 KiB |
BIN
internal/login/static/resources/images/icon-user-light-hover.png
Normal file
After Width: | Height: | Size: 4.2 KiB |
After Width: | Height: | Size: 7.6 KiB |
BIN
internal/login/static/resources/images/icon-user-light.png
Normal file
After Width: | Height: | Size: 4.6 KiB |
BIN
internal/login/static/resources/images/icon-user-light@2x.png
Normal file
After Width: | Height: | Size: 8.4 KiB |
@ -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));
|
@ -95,7 +95,7 @@ h1 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
p {
|
p {
|
||||||
font-width: 300;
|
font-weight: 300;
|
||||||
}
|
}
|
||||||
|
|
||||||
header {
|
header {
|
||||||
@ -151,9 +151,6 @@ button.primary {
|
|||||||
button.primary:hover {
|
button.primary:hover {
|
||||||
background-color: #f60075;
|
background-color: #f60075;
|
||||||
}
|
}
|
||||||
button > .sessionstate {
|
|
||||||
text-transform: lowercase;
|
|
||||||
}
|
|
||||||
|
|
||||||
input:not([type=radio]), select {
|
input:not([type=radio]), select {
|
||||||
background-color: #252525;
|
background-color: #252525;
|
||||||
@ -200,6 +197,102 @@ form .actions .right {
|
|||||||
form .actions button, form .actions a {
|
form .actions button, form .actions a {
|
||||||
margin: 10px 0;
|
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 {
|
#copy-secret {
|
||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
@ -209,11 +302,11 @@ form .actions button, form .actions a {
|
|||||||
#qrcode {
|
#qrcode {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
#qrcode svg rect[style*="fill:white"] {
|
#qrcode svg rect.color {
|
||||||
fill: #282828 !important;
|
fill: white;
|
||||||
}
|
}
|
||||||
#qrcode svg rect[style*="fill:black"] {
|
#qrcode svg rect.bg-color {
|
||||||
fill: white !important;
|
fill: #282828;
|
||||||
}
|
}
|
||||||
|
|
||||||
#secret .copy {
|
#secret .copy {
|
||||||
|
@ -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"}
|
@ -95,7 +95,7 @@ h1 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
p {
|
p {
|
||||||
font-width: 300;
|
font-weight: 300;
|
||||||
}
|
}
|
||||||
|
|
||||||
header {
|
header {
|
||||||
@ -151,9 +151,6 @@ button.primary {
|
|||||||
button.primary:hover {
|
button.primary:hover {
|
||||||
background-color: #f60075;
|
background-color: #f60075;
|
||||||
}
|
}
|
||||||
button > .sessionstate {
|
|
||||||
text-transform: lowercase;
|
|
||||||
}
|
|
||||||
|
|
||||||
input:not([type=radio]), select {
|
input:not([type=radio]), select {
|
||||||
background-color: #252525;
|
background-color: #252525;
|
||||||
@ -200,6 +197,102 @@ form .actions .right {
|
|||||||
form .actions button, form .actions a {
|
form .actions button, form .actions a {
|
||||||
margin: 10px 0;
|
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 {
|
#copy-secret {
|
||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
@ -209,11 +302,11 @@ form .actions button, form .actions a {
|
|||||||
#qrcode {
|
#qrcode {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
#qrcode svg rect[style*="fill:white"] {
|
#qrcode svg rect.color {
|
||||||
fill: #282828 !important;
|
fill: white;
|
||||||
}
|
}
|
||||||
#qrcode svg rect[style*="fill:black"] {
|
#qrcode svg rect.bg-color {
|
||||||
fill: white !important;
|
fill: #282828;
|
||||||
}
|
}
|
||||||
|
|
||||||
#secret .copy {
|
#secret .copy {
|
||||||
@ -282,6 +375,48 @@ html button.primary {
|
|||||||
html button.primary:hover {
|
html button.primary:hover {
|
||||||
background-color: #f60075;
|
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 {
|
html input {
|
||||||
background-color: white;
|
background-color: white;
|
||||||
color: #282828;
|
color: #282828;
|
||||||
|
@ -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"}
|
@ -30,6 +30,36 @@ html {
|
|||||||
background-color: $primaryColorHover;
|
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 {
|
input {
|
||||||
|
@ -25,7 +25,7 @@ h1 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
p {
|
p {
|
||||||
font-width: 300;
|
font-weight: 300;
|
||||||
}
|
}
|
||||||
|
|
||||||
header {
|
header {
|
||||||
@ -83,10 +83,6 @@ button {
|
|||||||
background-color: $primaryColorHover;
|
background-color: $primaryColorHover;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
& > .sessionstate {
|
|
||||||
text-transform: lowercase;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
input:not([type='radio']), select {
|
input:not([type='radio']), select {
|
||||||
@ -143,6 +139,102 @@ form {
|
|||||||
margin: 10px 0;
|
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 {
|
#copy-secret {
|
||||||
@ -153,12 +245,12 @@ form {
|
|||||||
#qrcode {
|
#qrcode {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
|
||||||
svg rect[style*="fill:white"] {
|
svg rect.color {
|
||||||
fill: $backgroundColor !important;
|
fill: $fontColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
svg rect[style*="fill:black"] {
|
svg rect.bg-color {
|
||||||
fill: $fontColor !important;
|
fill: $backgroundColor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,7 +4,20 @@ $headerFont: Aileron;
|
|||||||
|
|
||||||
// ----- LAYOUT ------------
|
// ----- LAYOUT ------------
|
||||||
$inputHeight: 50px;
|
$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 --------
|
// ----- DARK-THEME --------
|
||||||
$backgroundColor: #282828;
|
$backgroundColor: #282828;
|
||||||
@ -14,10 +27,16 @@ $primaryColorHover: lighten($primaryColor, 10%);
|
|||||||
$labelColor: #898989;
|
$labelColor: #898989;
|
||||||
$inputBorderColor: #595959;
|
$inputBorderColor: #595959;
|
||||||
$inputBackgroundColor: #252525;
|
$inputBackgroundColor: #252525;
|
||||||
|
$buttonBackgroundColorHover: $inputBackgroundColor;
|
||||||
|
$profileImgDark: "/resources/images/icon-user-dark";
|
||||||
|
$otherUserImgDark: "/resources/images/icon-newuser-dark";
|
||||||
|
|
||||||
|
|
||||||
// ----- LIGHT-THEME --------
|
// ----- LIGHT-THEME --------
|
||||||
$backgroundColorLight: $fontColor;
|
$backgroundColorLight: $fontColor;
|
||||||
$fontColorLight: $backgroundColor;
|
$fontColorLight: $backgroundColor;
|
||||||
$primaryColorLight: $primaryColor;
|
$primaryColorLight: $primaryColor;
|
||||||
$primaryColorHoverLight: lighten($primaryColorLight, 10%);
|
$primaryColorHoverLight: lighten($primaryColorLight, 10%);
|
||||||
|
$buttonBackgroundColorHoverLight: #EFEFEF;
|
||||||
|
$profileImgLight: "/resources/images/icon-user-light";
|
||||||
|
$otherUserImgLight: "/resources/images/icon-newuser-light";
|
@ -95,7 +95,7 @@ h1 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
p {
|
p {
|
||||||
font-width: 300;
|
font-weight: 300;
|
||||||
}
|
}
|
||||||
|
|
||||||
header {
|
header {
|
||||||
@ -151,9 +151,6 @@ button.primary {
|
|||||||
button.primary:hover {
|
button.primary:hover {
|
||||||
background-color: #6778f8;
|
background-color: #6778f8;
|
||||||
}
|
}
|
||||||
button > .sessionstate {
|
|
||||||
text-transform: lowercase;
|
|
||||||
}
|
|
||||||
|
|
||||||
input:not([type=radio]), select {
|
input:not([type=radio]), select {
|
||||||
background-color: #252525;
|
background-color: #252525;
|
||||||
@ -200,6 +197,102 @@ form .actions .right {
|
|||||||
form .actions button, form .actions a {
|
form .actions button, form .actions a {
|
||||||
margin: 10px 0;
|
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 {
|
#copy-secret {
|
||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
@ -209,11 +302,11 @@ form .actions button, form .actions a {
|
|||||||
#qrcode {
|
#qrcode {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
#qrcode svg rect[style*="fill:white"] {
|
#qrcode svg rect.color {
|
||||||
fill: #282828 !important;
|
fill: #FFFFFF;
|
||||||
}
|
}
|
||||||
#qrcode svg rect[style*="fill:black"] {
|
#qrcode svg rect.bg-color {
|
||||||
fill: #FFFFFF !important;
|
fill: #282828;
|
||||||
}
|
}
|
||||||
|
|
||||||
#secret .copy {
|
#secret .copy {
|
||||||
|
@ -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"}
|
@ -95,7 +95,7 @@ h1 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
p {
|
p {
|
||||||
font-width: 300;
|
font-weight: 300;
|
||||||
}
|
}
|
||||||
|
|
||||||
header {
|
header {
|
||||||
@ -151,9 +151,6 @@ button.primary {
|
|||||||
button.primary:hover {
|
button.primary:hover {
|
||||||
background-color: #6778f8;
|
background-color: #6778f8;
|
||||||
}
|
}
|
||||||
button > .sessionstate {
|
|
||||||
text-transform: lowercase;
|
|
||||||
}
|
|
||||||
|
|
||||||
input:not([type=radio]), select {
|
input:not([type=radio]), select {
|
||||||
background-color: #252525;
|
background-color: #252525;
|
||||||
@ -200,6 +197,102 @@ form .actions .right {
|
|||||||
form .actions button, form .actions a {
|
form .actions button, form .actions a {
|
||||||
margin: 10px 0;
|
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 {
|
#copy-secret {
|
||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
@ -209,11 +302,11 @@ form .actions button, form .actions a {
|
|||||||
#qrcode {
|
#qrcode {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
#qrcode svg rect[style*="fill:white"] {
|
#qrcode svg rect.color {
|
||||||
fill: #282828 !important;
|
fill: #FFFFFF;
|
||||||
}
|
}
|
||||||
#qrcode svg rect[style*="fill:black"] {
|
#qrcode svg rect.bg-color {
|
||||||
fill: #FFFFFF !important;
|
fill: #282828;
|
||||||
}
|
}
|
||||||
|
|
||||||
#secret .copy {
|
#secret .copy {
|
||||||
@ -282,6 +375,48 @@ html button.primary {
|
|||||||
html button.primary:hover {
|
html button.primary:hover {
|
||||||
background-color: #6778f8;
|
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 {
|
html input {
|
||||||
background-color: #FFFFFF;
|
background-color: #FFFFFF;
|
||||||
color: #282828;
|
color: #282828;
|
||||||
|
@ -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"}
|
@ -6,6 +6,8 @@
|
|||||||
|
|
||||||
<form action="{{ changePasswordUrl }}" method="POST">
|
<form action="{{ changePasswordUrl }}" method="POST">
|
||||||
|
|
||||||
|
{{ .CSRF }}
|
||||||
|
|
||||||
<input type="hidden" name="authRequestID" value="{{ .AuthReqID }}" />
|
<input type="hidden" name="authRequestID" value="{{ .AuthReqID }}" />
|
||||||
|
|
||||||
<div class="fields">
|
<div class="fields">
|
||||||
|
@ -6,6 +6,8 @@
|
|||||||
|
|
||||||
<form action="{{ loginUrl }}" method="POST">
|
<form action="{{ loginUrl }}" method="POST">
|
||||||
|
|
||||||
|
{{ .CSRF }}
|
||||||
|
|
||||||
<input type="hidden" name="authRequestID" value="{{ .AuthReqID }}" />
|
<input type="hidden" name="authRequestID" value="{{ .AuthReqID }}" />
|
||||||
|
|
||||||
|
|
||||||
|
@ -6,6 +6,8 @@
|
|||||||
|
|
||||||
<form action="{{ initPasswordUrl }}" method="POST">
|
<form action="{{ initPasswordUrl }}" method="POST">
|
||||||
|
|
||||||
|
{{ .CSRF }}
|
||||||
|
|
||||||
<input type="hidden" name="authRequestID" value="{{ .AuthReqID }}" />
|
<input type="hidden" name="authRequestID" value="{{ .AuthReqID }}" />
|
||||||
<input type="hidden" name="userID" value="{{ .UserID }}" />
|
<input type="hidden" name="userID" value="{{ .UserID }}" />
|
||||||
|
|
||||||
|
@ -5,6 +5,8 @@
|
|||||||
<p>{{t "PasswordSetDone.Description"}}</p>
|
<p>{{t "PasswordSetDone.Description"}}</p>
|
||||||
<form action="{{ loginUrl }}" method="POST">
|
<form action="{{ loginUrl }}" method="POST">
|
||||||
|
|
||||||
|
{{ .CSRF }}
|
||||||
|
|
||||||
<input type="hidden" name="authRequestID" value="{{ .AuthReqID }}" />
|
<input type="hidden" name="authRequestID" value="{{ .AuthReqID }}" />
|
||||||
|
|
||||||
<div class="actions">
|
<div class="actions">
|
||||||
|
@ -6,6 +6,8 @@
|
|||||||
|
|
||||||
<form action="{{ initUserUrl }}" method="POST">
|
<form action="{{ initUserUrl }}" method="POST">
|
||||||
|
|
||||||
|
{{ .CSRF }}
|
||||||
|
|
||||||
<input type="hidden" name="authRequestID" value="{{ .AuthReqID }}" />
|
<input type="hidden" name="authRequestID" value="{{ .AuthReqID }}" />
|
||||||
<input type="hidden" name="userID" value="{{ .UserID }}" />
|
<input type="hidden" name="userID" value="{{ .UserID }}" />
|
||||||
|
|
||||||
|
@ -5,6 +5,8 @@
|
|||||||
<p>{{t "InitUserDone.Description"}}</p>
|
<p>{{t "InitUserDone.Description"}}</p>
|
||||||
<form action="{{ loginUrl }}" method="POST">
|
<form action="{{ loginUrl }}" method="POST">
|
||||||
|
|
||||||
|
{{ .CSRF }}
|
||||||
|
|
||||||
<input type="hidden" name="authRequestID" value="{{ .AuthReqID }}" />
|
<input type="hidden" name="authRequestID" value="{{ .AuthReqID }}" />
|
||||||
|
|
||||||
<div class="actions">
|
<div class="actions">
|
||||||
|
@ -4,14 +4,16 @@
|
|||||||
<h1>{{t "Login.Title"}}</h1>
|
<h1>{{t "Login.Title"}}</h1>
|
||||||
<p>{{t "Login.Description"}}</p>
|
<p>{{t "Login.Description"}}</p>
|
||||||
|
|
||||||
<form action="{{ usernameUrl }}" method="POST">
|
<form action="{{ loginNameUrl }}" method="POST">
|
||||||
|
|
||||||
|
{{ .CSRF }}
|
||||||
|
|
||||||
<input type="hidden" name="authRequestID" value="{{ .AuthReqID }}" />
|
<input type="hidden" name="authRequestID" value="{{ .AuthReqID }}" />
|
||||||
|
|
||||||
<div class="fields">
|
<div class="fields">
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label class="label" for="username">{{t "Login.Loginname"}}</label>
|
<label class="label" for="loginName">{{t "Login.Loginname"}}</label>
|
||||||
<input class="input" type="text" id="username" name="username" placeholder="{{t "Login.LoginnamePlaceHolder"}}" value="{{ .UserName }}" autocomplete="username" autofocus required>
|
<input class="input" type="text" id="loginName" name="loginName" placeholder="{{t "Login.LoginnamePlaceHolder"}}" value="{{ .LoginName }}" autocomplete="username" autofocus required>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -5,6 +5,8 @@
|
|||||||
<p>{{t "LogoutDone.Description"}}</p>
|
<p>{{t "LogoutDone.Description"}}</p>
|
||||||
<form action="{{ loginUrl }}" method="POST">
|
<form action="{{ loginUrl }}" method="POST">
|
||||||
|
|
||||||
|
{{ .CSRF }}
|
||||||
|
|
||||||
<div class="actions">
|
<div class="actions">
|
||||||
<button class="primary right" type="submit">{{t "Actions.Login"}}</button>
|
<button class="primary right" type="submit">{{t "Actions.Login"}}</button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -6,6 +6,8 @@
|
|||||||
|
|
||||||
<form action="{{ mailVerificationUrl }}" method="POST">
|
<form action="{{ mailVerificationUrl }}" method="POST">
|
||||||
|
|
||||||
|
{{ .CSRF }}
|
||||||
|
|
||||||
<input type="hidden" name="authRequestID" value="{{ .AuthReqID }}" />
|
<input type="hidden" name="authRequestID" value="{{ .AuthReqID }}" />
|
||||||
<input type="hidden" name="userID" value="{{ .UserID }}" />
|
<input type="hidden" name="userID" value="{{ .UserID }}" />
|
||||||
|
|
||||||
|
@ -6,6 +6,8 @@
|
|||||||
|
|
||||||
<form action="{{ loginUrl }}" method="POST">
|
<form action="{{ loginUrl }}" method="POST">
|
||||||
|
|
||||||
|
{{ .CSRF }}
|
||||||
|
|
||||||
<input type="hidden" name="authRequestID" value="{{ .AuthReqID }}" />
|
<input type="hidden" name="authRequestID" value="{{ .AuthReqID }}" />
|
||||||
|
|
||||||
|
|
||||||
|
@ -6,6 +6,8 @@
|
|||||||
|
|
||||||
<form action="{{ loginUrl }}" method="POST">
|
<form action="{{ loginUrl }}" method="POST">
|
||||||
|
|
||||||
|
{{ .CSRF }}
|
||||||
|
|
||||||
<input type="hidden" name="authRequestID" value="{{ .AuthReqID }}" />
|
<input type="hidden" name="authRequestID" value="{{ .AuthReqID }}" />
|
||||||
<input type="hidden" name="mfaType" value="{{ .MfaType }}" />
|
<input type="hidden" name="mfaType" value="{{ .MfaType }}" />
|
||||||
|
|
||||||
|
@ -6,6 +6,8 @@
|
|||||||
|
|
||||||
<form action="{{ mfaInitVerifyUrl }}" method="POST">
|
<form action="{{ mfaInitVerifyUrl }}" method="POST">
|
||||||
|
|
||||||
|
{{ .CSRF }}
|
||||||
|
|
||||||
<input type="hidden" name="authRequestID" value="{{ .AuthReqID }}" />
|
<input type="hidden" name="authRequestID" value="{{ .AuthReqID }}" />
|
||||||
<input type="hidden" name="mfaType" value="{{ .MfaType }}" />
|
<input type="hidden" name="mfaType" value="{{ .MfaType }}" />
|
||||||
<input type="hidden" name="url" value="{{ .Url }}" />
|
<input type="hidden" name="url" value="{{ .Url }}" />
|
||||||
@ -21,7 +23,7 @@
|
|||||||
<span class="label" for="secret">{{t "MfaInitVerify.Secret"}}</span>
|
<span class="label" for="secret">{{t "MfaInitVerify.Secret"}}</span>
|
||||||
<span class="input" id="secret">
|
<span class="input" id="secret">
|
||||||
{{.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>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="field">
|
<div class="field">
|
||||||
@ -36,12 +38,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<script>
|
<script src="{{ resourceUrl "scripts/copy_to_clipboard.js" }}"></script>
|
||||||
const copyToClipboard = str => {
|
|
||||||
navigator.clipboard.writeText(str);
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
|
|
||||||
{{template "main-bottom" .}}
|
{{template "main-bottom" .}}
|
||||||
|
|
@ -5,6 +5,8 @@
|
|||||||
|
|
||||||
<form action="{{ mfaPromptUrl }}" method="POST">
|
<form action="{{ mfaPromptUrl }}" method="POST">
|
||||||
|
|
||||||
|
{{ .CSRF }}
|
||||||
|
|
||||||
<input type="hidden" name="authRequestID" value="{{ .AuthReqID }}" />
|
<input type="hidden" name="authRequestID" value="{{ .AuthReqID }}" />
|
||||||
|
|
||||||
<div class="fields">
|
<div class="fields">
|
||||||
|
@ -6,6 +6,8 @@
|
|||||||
|
|
||||||
<form action="{{ mfaVerifyUrl }}" method="POST">
|
<form action="{{ mfaVerifyUrl }}" method="POST">
|
||||||
|
|
||||||
|
{{ .CSRF }}
|
||||||
|
|
||||||
<input type="hidden" name="authRequestID" value="{{ .AuthReqID }}" />
|
<input type="hidden" name="authRequestID" value="{{ .AuthReqID }}" />
|
||||||
<input type="hidden" name="mfaType" value="{{ .SelectedMfaProvider }}" />
|
<input type="hidden" name="mfaType" value="{{ .SelectedMfaProvider }}" />
|
||||||
|
|
||||||
|
@ -5,8 +5,10 @@
|
|||||||
|
|
||||||
<form action="{{ passwordUrl }}" method="POST">
|
<form action="{{ passwordUrl }}" method="POST">
|
||||||
|
|
||||||
|
{{ .CSRF }}
|
||||||
|
|
||||||
<input type="hidden" name="authRequestID" value="{{ .AuthReqID }}" />
|
<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="fields">
|
||||||
<div class="field">
|
<div class="field">
|
||||||
@ -19,7 +21,7 @@
|
|||||||
|
|
||||||
<div class="actions">
|
<div class="actions">
|
||||||
<button class="primary right" type="submit">{{t "Actions.Next"}}</button>
|
<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>
|
<button class="secondary" type="button">{{t "Actions.Back"}}</button>
|
||||||
</a>
|
</a>
|
||||||
<a href="{{ passwordResetUrl .AuthReqID }}">
|
<a href="{{ passwordResetUrl .AuthReqID }}">
|
||||||
|
@ -5,6 +5,8 @@
|
|||||||
<p>{{t "PasswordResetDone.Description"}}</p>
|
<p>{{t "PasswordResetDone.Description"}}</p>
|
||||||
<form action="{{ loginUrl }}" method="POST">
|
<form action="{{ loginUrl }}" method="POST">
|
||||||
|
|
||||||
|
{{ .CSRF }}
|
||||||
|
|
||||||
<input type="hidden" name="authRequestID" value="{{ .AuthReqID }}" />
|
<input type="hidden" name="authRequestID" value="{{ .AuthReqID }}" />
|
||||||
|
|
||||||
<div class="actions">
|
<div class="actions">
|
||||||
|
@ -5,6 +5,8 @@
|
|||||||
|
|
||||||
<form action="{{ registrationUrl }}" method="POST">
|
<form action="{{ registrationUrl }}" method="POST">
|
||||||
|
|
||||||
|
{{ .CSRF }}
|
||||||
|
|
||||||
<input type="hidden" name="authRequestID" value="{{ .AuthReqID }}" />
|
<input type="hidden" name="authRequestID" value="{{ .AuthReqID }}" />
|
||||||
|
|
||||||
<div class="fields">
|
<div class="fields">
|
||||||
|
@ -6,17 +6,32 @@
|
|||||||
|
|
||||||
<form action="{{ userSelectionUrl }}" method="POST">
|
<form action="{{ userSelectionUrl }}" method="POST">
|
||||||
|
|
||||||
|
{{ .CSRF }}
|
||||||
|
|
||||||
<input type="hidden" name="authRequestID" value="{{ .AuthReqID }}" />
|
<input type="hidden" name="authRequestID" value="{{ .AuthReqID }}" />
|
||||||
|
|
||||||
<div class="actions">
|
<div class="actions">
|
||||||
{{ range $user := .Users }}
|
{{ if .Users }}
|
||||||
{{ $sessionState := (t (printf "UserSelection.SessionState%v" $user.UserSessionState)) }}
|
<div class="user-selection-list">
|
||||||
<button type="submit" name="userID" value="{{$user.UserID}}" class="primary">
|
{{ range $user := .Users }}
|
||||||
<span class="username">{{$user.UserName}}</span>
|
{{ $sessionState := (printf "sessionstate-%v" $user.UserSessionState) }}
|
||||||
<span class="sessionstate">({{$sessionState}})</span>
|
<button type="submit" name="userID" value="{{$user.UserID}}" class="clean user-selection">
|
||||||
</button>
|
<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 }}
|
{{ 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>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
73
internal/qrcode/qr_svg.go
Normal 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)
|
||||||
|
}
|
493
internal/qrcode/qr_svg_test.go
Normal 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
@ -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).
|
@ -81,6 +81,12 @@ func (u *User) CheckOrgIamPolicy(policy *org_model.OrgIamPolicy) error {
|
|||||||
return nil
|
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 {
|
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())
|
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())
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,8 @@ type UserSessionView struct {
|
|||||||
UserAgentID string
|
UserAgentID string
|
||||||
UserID string
|
UserID string
|
||||||
UserName string
|
UserName string
|
||||||
|
LoginName string
|
||||||
|
DisplayName string
|
||||||
PasswordVerification time.Time
|
PasswordVerification time.Time
|
||||||
MfaSoftwareVerification time.Time
|
MfaSoftwareVerification time.Time
|
||||||
MfaSoftwareVerificationType req_model.MfaType
|
MfaSoftwareVerificationType req_model.MfaType
|
||||||
|
@ -109,6 +109,7 @@ func (es *UserEventstore) PrepareCreateUser(ctx context.Context, user *usr_model
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
user.SetNamesAsDisplayname()
|
||||||
if !user.IsValid() {
|
if !user.IsValid() {
|
||||||
return nil, nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-9dk45", "User is invalid")
|
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 {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
user.SetNamesAsDisplayname()
|
||||||
if !user.IsValid() || user.Password == nil || user.SecretString == "" {
|
if !user.IsValid() || user.Password == nil || user.SecretString == "" {
|
||||||
return nil, nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-9dk45", "Errors.User.InvalidData")
|
return nil, nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-9dk45", "Errors.User.InvalidData")
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,9 @@ type UserSessionView struct {
|
|||||||
State int32 `json:"-" gorm:"column:state"`
|
State int32 `json:"-" gorm:"column:state"`
|
||||||
UserAgentID string `json:"userAgentID" gorm:"column:user_agent_id;primary_key"`
|
UserAgentID string `json:"userAgentID" gorm:"column:user_agent_id;primary_key"`
|
||||||
UserID string `json:"userID" gorm:"column:user_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"`
|
PasswordVerification time.Time `json:"-" gorm:"column:password_verification"`
|
||||||
MfaSoftwareVerification time.Time `json:"-" gorm:"column:mfa_software_verification"`
|
MfaSoftwareVerification time.Time `json:"-" gorm:"column:mfa_software_verification"`
|
||||||
MfaSoftwareVerificationType int32 `json:"-" gorm:"column:mfa_software_verification_type"`
|
MfaSoftwareVerificationType int32 `json:"-" gorm:"column:mfa_software_verification_type"`
|
||||||
@ -54,6 +56,8 @@ func UserSessionToModel(userSession *UserSessionView) *model.UserSessionView {
|
|||||||
UserAgentID: userSession.UserAgentID,
|
UserAgentID: userSession.UserAgentID,
|
||||||
UserID: userSession.UserID,
|
UserID: userSession.UserID,
|
||||||
UserName: userSession.UserName,
|
UserName: userSession.UserName,
|
||||||
|
LoginName: userSession.LoginName,
|
||||||
|
DisplayName: userSession.DisplayName,
|
||||||
PasswordVerification: userSession.PasswordVerification,
|
PasswordVerification: userSession.PasswordVerification,
|
||||||
MfaSoftwareVerification: userSession.MfaSoftwareVerification,
|
MfaSoftwareVerification: userSession.MfaSoftwareVerification,
|
||||||
MfaSoftwareVerificationType: req_model.MfaType(userSession.MfaSoftwareVerificationType),
|
MfaSoftwareVerificationType: req_model.MfaType(userSession.MfaSoftwareVerificationType),
|
||||||
|
6
migrations/cockroach/V1.19__usersession_names.sql
Normal 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;
|
@ -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) {
|
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 protoReq empty.Empty
|
||||||
var metadata runtime.ServerMetadata
|
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) {
|
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 protoReq empty.Empty
|
||||||
var metadata runtime.ServerMetadata
|
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 (
|
var (
|
||||||
filter_AdminService_IsOrgUnique_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)}
|
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 protoReq UniqueOrgRequest
|
||||||
var metadata runtime.ServerMetadata
|
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)
|
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) {
|
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 protoReq OrgID
|
||||||
var metadata runtime.ServerMetadata
|
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) {
|
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 protoReq OrgSearchRequest
|
||||||
var metadata runtime.ServerMetadata
|
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) {
|
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 protoReq OrgSetUpRequest
|
||||||
var metadata runtime.ServerMetadata
|
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) {
|
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 protoReq OrgIamPolicyID
|
||||||
var metadata runtime.ServerMetadata
|
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) {
|
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 protoReq OrgIamPolicyRequest
|
||||||
var metadata runtime.ServerMetadata
|
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) {
|
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 protoReq OrgIamPolicyRequest
|
||||||
var metadata runtime.ServerMetadata
|
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) {
|
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 protoReq OrgIamPolicyID
|
||||||
var metadata runtime.ServerMetadata
|
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
|
// RegisterAdminServiceHandlerFromEndpoint is same as RegisterAdminServiceHandler but
|
||||||
// automatically dials to "endpoint" and closes the connection when "ctx" gets done.
|
// 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) {
|
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 (
|
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 (
|
var (
|
||||||
|
@ -274,7 +274,7 @@
|
|||||||
"200": {
|
"200": {
|
||||||
"description": "A successful response.",
|
"description": "A successful response.",
|
||||||
"schema": {
|
"schema": {
|
||||||
"$ref": "#/definitions/protobufStruct"
|
"type": "object"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -285,19 +285,6 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"definitions": {
|
"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": {
|
"protobufNullValue": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"enum": [
|
||||||
@ -306,51 +293,6 @@
|
|||||||
"default": "NULL_VALUE",
|
"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."
|
"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": {
|
"v1CreateOrgRequest": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
@ -377,9 +319,6 @@
|
|||||||
"nick_name": {
|
"nick_name": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"display_name": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"preferred_language": {
|
"preferred_language": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
@ -32,7 +32,6 @@ func userCreateRequestToModel(user *CreateUserRequest) *usr_model.User {
|
|||||||
return &usr_model.User{
|
return &usr_model.User{
|
||||||
Profile: &usr_model.Profile{
|
Profile: &usr_model.Profile{
|
||||||
UserName: user.UserName,
|
UserName: user.UserName,
|
||||||
DisplayName: user.DisplayName,
|
|
||||||
FirstName: user.FirstName,
|
FirstName: user.FirstName,
|
||||||
LastName: user.LastName,
|
LastName: user.LastName,
|
||||||
NickName: user.NickName,
|
NickName: user.NickName,
|
||||||
|
@ -220,19 +220,18 @@ message CreateUserRequest {
|
|||||||
string first_name = 2 [(validate.rules).string = {min_len: 1, max_len: 200}];
|
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 last_name = 3 [(validate.rules).string = {min_len: 1, max_len: 200}];
|
||||||
string nick_name = 4 [(validate.rules).string = {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 = 5 [(validate.rules).string = {max_len: 200}];
|
||||||
string preferred_language = 6 [(validate.rules).string = {max_len: 200}];
|
Gender gender = 6;
|
||||||
Gender gender = 7;
|
string email = 7 [(validate.rules).string = {min_len: 1, max_len: 200, email: true}];
|
||||||
string email = 8 [(validate.rules).string = {min_len: 1, max_len: 200, email: true}];
|
bool is_email_verified = 8;
|
||||||
bool is_email_verified = 9;
|
string phone = 9 [(validate.rules).string = {max_len: 20}];
|
||||||
string phone = 11 [(validate.rules).string = {max_len: 20}];
|
bool is_phone_verified = 10;
|
||||||
bool is_phone_verified = 12;
|
string country = 11 [(validate.rules).string = {max_len: 200}];
|
||||||
string country = 13 [(validate.rules).string = {max_len: 200}];
|
string locality = 12 [(validate.rules).string = {max_len: 200}];
|
||||||
string locality = 14 [(validate.rules).string = {max_len: 200}];
|
string postal_code = 13 [(validate.rules).string = {max_len: 200}];
|
||||||
string postal_code = 15 [(validate.rules).string = {max_len: 200}];
|
string region = 14 [(validate.rules).string = {max_len: 200}];
|
||||||
string region = 16 [(validate.rules).string = {max_len: 200}];
|
string street_address = 15 [(validate.rules).string = {max_len: 200}];
|
||||||
string street_address = 17 [(validate.rules).string = {max_len: 200}];
|
string password = 16 [(validate.rules).string = {max_len: 72}];
|
||||||
string password = 18 [(validate.rules).string = {max_len: 72}];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
message User {
|
message User {
|
||||||
|
@ -520,7 +520,7 @@
|
|||||||
"200": {
|
"200": {
|
||||||
"description": "A successful response.",
|
"description": "A successful response.",
|
||||||
"schema": {
|
"schema": {
|
||||||
"$ref": "#/definitions/protobufStruct"
|
"type": "object"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -531,19 +531,6 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"definitions": {
|
"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": {
|
"protobufNullValue": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"enum": [
|
||||||
@ -552,51 +539,6 @@
|
|||||||
"default": "NULL_VALUE",
|
"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."
|
"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": {
|
"v1Gender": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"enum": [
|
||||||
@ -826,9 +768,6 @@
|
|||||||
"nick_name": {
|
"nick_name": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"display_name": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"preferred_language": {
|
"preferred_language": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
@ -138,14 +138,14 @@ func (mr *MockAuthServiceClientMockRecorder) GetMyMfas(arg0, arg1 interface{}, a
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetMyUserAddress mocks base method
|
// 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()
|
m.ctrl.T.Helper()
|
||||||
varargs := []interface{}{arg0, arg1}
|
varargs := []interface{}{arg0, arg1}
|
||||||
for _, a := range arg2 {
|
for _, a := range arg2 {
|
||||||
varargs = append(varargs, a)
|
varargs = append(varargs, a)
|
||||||
}
|
}
|
||||||
ret := m.ctrl.Call(m, "GetMyUserAddress", varargs...)
|
ret := m.ctrl.Call(m, "GetMyUserAddress", varargs...)
|
||||||
ret0, _ := ret[0].(*grpc.UserAddress)
|
ret0, _ := ret[0].(*grpc.UserAddressView)
|
||||||
ret1, _ := ret[1].(error)
|
ret1, _ := ret[1].(error)
|
||||||
return ret0, ret1
|
return ret0, ret1
|
||||||
}
|
}
|
||||||
@ -158,14 +158,14 @@ func (mr *MockAuthServiceClientMockRecorder) GetMyUserAddress(arg0, arg1 interfa
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetMyUserEmail mocks base method
|
// 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()
|
m.ctrl.T.Helper()
|
||||||
varargs := []interface{}{arg0, arg1}
|
varargs := []interface{}{arg0, arg1}
|
||||||
for _, a := range arg2 {
|
for _, a := range arg2 {
|
||||||
varargs = append(varargs, a)
|
varargs = append(varargs, a)
|
||||||
}
|
}
|
||||||
ret := m.ctrl.Call(m, "GetMyUserEmail", varargs...)
|
ret := m.ctrl.Call(m, "GetMyUserEmail", varargs...)
|
||||||
ret0, _ := ret[0].(*grpc.UserEmail)
|
ret0, _ := ret[0].(*grpc.UserEmailView)
|
||||||
ret1, _ := ret[1].(error)
|
ret1, _ := ret[1].(error)
|
||||||
return ret0, ret1
|
return ret0, ret1
|
||||||
}
|
}
|
||||||
@ -178,14 +178,14 @@ func (mr *MockAuthServiceClientMockRecorder) GetMyUserEmail(arg0, arg1 interface
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetMyUserPhone mocks base method
|
// 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()
|
m.ctrl.T.Helper()
|
||||||
varargs := []interface{}{arg0, arg1}
|
varargs := []interface{}{arg0, arg1}
|
||||||
for _, a := range arg2 {
|
for _, a := range arg2 {
|
||||||
varargs = append(varargs, a)
|
varargs = append(varargs, a)
|
||||||
}
|
}
|
||||||
ret := m.ctrl.Call(m, "GetMyUserPhone", varargs...)
|
ret := m.ctrl.Call(m, "GetMyUserPhone", varargs...)
|
||||||
ret0, _ := ret[0].(*grpc.UserPhone)
|
ret0, _ := ret[0].(*grpc.UserPhoneView)
|
||||||
ret1, _ := ret[1].(error)
|
ret1, _ := ret[1].(error)
|
||||||
return ret0, ret1
|
return ret0, ret1
|
||||||
}
|
}
|
||||||
@ -198,14 +198,14 @@ func (mr *MockAuthServiceClientMockRecorder) GetMyUserPhone(arg0, arg1 interface
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetMyUserProfile mocks base method
|
// 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()
|
m.ctrl.T.Helper()
|
||||||
varargs := []interface{}{arg0, arg1}
|
varargs := []interface{}{arg0, arg1}
|
||||||
for _, a := range arg2 {
|
for _, a := range arg2 {
|
||||||
varargs = append(varargs, a)
|
varargs = append(varargs, a)
|
||||||
}
|
}
|
||||||
ret := m.ctrl.Call(m, "GetMyUserProfile", varargs...)
|
ret := m.ctrl.Call(m, "GetMyUserProfile", varargs...)
|
||||||
ret0, _ := ret[0].(*grpc.UserProfile)
|
ret0, _ := ret[0].(*grpc.UserProfileView)
|
||||||
ret1, _ := ret[1].(error)
|
ret1, _ := ret[1].(error)
|
||||||
return ret0, ret1
|
return ret0, ret1
|
||||||
}
|
}
|
||||||
|
@ -66,7 +66,6 @@ func updateProfileToModel(ctx context.Context, u *UpdateUserProfileRequest) *usr
|
|||||||
FirstName: u.FirstName,
|
FirstName: u.FirstName,
|
||||||
LastName: u.LastName,
|
LastName: u.LastName,
|
||||||
NickName: u.NickName,
|
NickName: u.NickName,
|
||||||
DisplayName: u.DisplayName,
|
|
||||||
PreferredLanguage: preferredLanguage,
|
PreferredLanguage: preferredLanguage,
|
||||||
Gender: genderToModel(u.Gender),
|
Gender: genderToModel(u.Gender),
|
||||||
}
|
}
|
||||||
|
@ -55,7 +55,7 @@ func (o *OPStorage) GetUserinfoFromScopes(ctx context.Context, userID string, sc
|
|||||||
userInfo.FamilyName = user.LastName
|
userInfo.FamilyName = user.LastName
|
||||||
userInfo.GivenName = user.FirstName
|
userInfo.GivenName = user.FirstName
|
||||||
userInfo.Nickname = user.NickName
|
userInfo.Nickname = user.NickName
|
||||||
userInfo.PreferredUsername = user.UserName
|
userInfo.PreferredUsername = user.PreferredLoginName
|
||||||
userInfo.UpdatedAt = user.ChangeDate
|
userInfo.UpdatedAt = user.ChangeDate
|
||||||
userInfo.Gender = oidc.Gender(getGender(user.Gender))
|
userInfo.Gender = oidc.Gender(getGender(user.Gender))
|
||||||
case scopePhone:
|
case scopePhone:
|
||||||
|