Merge branch 'main' into remove_vendor_doc

This commit is contained in:
zeripath 2022-01-15 23:28:07 +00:00 committed by GitHub
commit c91dcb94ba
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 137 additions and 76 deletions

View file

@ -292,7 +292,7 @@ fmt-check:
checks: checks-frontend checks-backend checks: checks-frontend checks-backend
.PHONY: checks-frontend .PHONY: checks-frontend
checks-frontend: svg-check checks-frontend: lockfile-check svg-check
.PHONY: checks-backend .PHONY: checks-backend
checks-backend: test-vendor swagger-check swagger-validate checks-backend: test-vendor swagger-check swagger-validate
@ -700,6 +700,17 @@ svg-check: svg
exit 1; \ exit 1; \
fi fi
.PHONY: lockfile-check
lockfile-check:
npm install --package-lock-only
@diff=$$(git diff package-lock.json); \
if [ -n "$$diff" ]; then \
echo "package-lock.json is inconsistent with package.json"; \
echo "Please run 'npm install --package-lock-only' and commit the result:"; \
echo "$${diff}"; \
exit 1; \
fi
.PHONY: update-translations .PHONY: update-translations
update-translations: update-translations:
mkdir -p ./translations mkdir -p ./translations

View file

@ -128,6 +128,7 @@ This error indicates nginx is configured to restrict the file upload size.
In your nginx config file containing your Gitea proxy directive, find the `location { ... }` block for Gitea and add the line In your nginx config file containing your Gitea proxy directive, find the `location { ... }` block for Gitea and add the line
`client_max_body_size 16M;` to set this limit to 16 megabytes or any other number of choice. `client_max_body_size 16M;` to set this limit to 16 megabytes or any other number of choice.
If you use Git LFS, this will also limit the size of the largest file you will be able to push.
## Apache HTTPD ## Apache HTTPD

View file

@ -6,7 +6,7 @@ package auth
import ( import (
"context" "context"
"encoding/base64" "encoding/base32"
"fmt" "fmt"
"strings" "strings"
@ -94,7 +94,7 @@ type WebAuthnCredentialList []*WebAuthnCredential
func (list WebAuthnCredentialList) ToCredentials() []webauthn.Credential { func (list WebAuthnCredentialList) ToCredentials() []webauthn.Credential {
creds := make([]webauthn.Credential, 0, len(list)) creds := make([]webauthn.Credential, 0, len(list))
for _, cred := range list { for _, cred := range list {
credID, _ := base64.RawStdEncoding.DecodeString(cred.CredentialID) credID, _ := base32.HexEncoding.DecodeString(cred.CredentialID)
creds = append(creds, webauthn.Credential{ creds = append(creds, webauthn.Credential{
ID: credID, ID: credID,
PublicKey: cred.PublicKey, PublicKey: cred.PublicKey,
@ -164,13 +164,13 @@ func HasWebAuthnRegistrationsByUID(uid int64) (bool, error) {
} }
// GetWebAuthnCredentialByCredID returns WebAuthn credential by credential ID // GetWebAuthnCredentialByCredID returns WebAuthn credential by credential ID
func GetWebAuthnCredentialByCredID(credID string) (*WebAuthnCredential, error) { func GetWebAuthnCredentialByCredID(userID int64, credID string) (*WebAuthnCredential, error) {
return getWebAuthnCredentialByCredID(db.DefaultContext, credID) return getWebAuthnCredentialByCredID(db.DefaultContext, userID, credID)
} }
func getWebAuthnCredentialByCredID(ctx context.Context, credID string) (*WebAuthnCredential, error) { func getWebAuthnCredentialByCredID(ctx context.Context, userID int64, credID string) (*WebAuthnCredential, error) {
cred := new(WebAuthnCredential) cred := new(WebAuthnCredential)
if found, err := db.GetEngine(ctx).Where("credential_id = ?", credID).Get(cred); err != nil { if found, err := db.GetEngine(ctx).Where("user_id = ? AND credential_id = ?", userID, credID).Get(cred); err != nil {
return nil, err return nil, err
} else if !found { } else if !found {
return nil, ErrWebAuthnCredentialNotExist{CredentialID: credID} return nil, ErrWebAuthnCredentialNotExist{CredentialID: credID}
@ -187,7 +187,7 @@ func createCredential(ctx context.Context, userID int64, name string, cred *weba
c := &WebAuthnCredential{ c := &WebAuthnCredential{
UserID: userID, UserID: userID,
Name: name, Name: name,
CredentialID: base64.RawStdEncoding.EncodeToString(cred.ID), CredentialID: base32.HexEncoding.EncodeToString(cred.ID),
PublicKey: cred.PublicKey, PublicKey: cred.PublicKey,
AttestationType: cred.AttestationType, AttestationType: cred.AttestationType,
AAGUID: cred.Authenticator.AAGUID, AAGUID: cred.Authenticator.AAGUID,

View file

@ -5,7 +5,7 @@
package auth package auth
import ( import (
"encoding/base64" "encoding/base32"
"testing" "testing"
"code.gitea.io/gitea/models/unittest" "code.gitea.io/gitea/models/unittest"
@ -61,7 +61,7 @@ func TestCreateCredential(t *testing.T) {
res, err := CreateCredential(1, "WebAuthn Created Credential", &webauthn.Credential{ID: []byte("Test")}) res, err := CreateCredential(1, "WebAuthn Created Credential", &webauthn.Credential{ID: []byte("Test")})
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, "WebAuthn Created Credential", res.Name) assert.Equal(t, "WebAuthn Created Credential", res.Name)
bs, err := base64.RawStdEncoding.DecodeString(res.CredentialID) bs, err := base32.HexEncoding.DecodeString(res.CredentialID)
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, []byte("Test"), bs) assert.Equal(t, []byte("Test"), bs)

View file

@ -368,6 +368,8 @@ var migrations = []Migration{
NewMigration("Add authorize column to team_unit table", addAuthorizeColForTeamUnit), NewMigration("Add authorize column to team_unit table", addAuthorizeColForTeamUnit),
// v207 -> v208 // v207 -> v208
NewMigration("Add webauthn table and migrate u2f data to webauthn", addWebAuthnCred), NewMigration("Add webauthn table and migrate u2f data to webauthn", addWebAuthnCred),
// v208 -> v209
NewMigration("Use base32.HexEncoding instead of base64 encoding for cred ID as it is case insensitive", useBase32HexForCredIDInWebAuthnCredential),
} }
// GetCurrentDBVersion returns the current db version // GetCurrentDBVersion returns the current db version

51
models/migrations/v208.go Normal file
View file

@ -0,0 +1,51 @@
// Copyright 2021 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package migrations
import (
"encoding/base32"
"encoding/base64"
"xorm.io/xorm"
)
func useBase32HexForCredIDInWebAuthnCredential(x *xorm.Engine) error {
// Create webauthnCredential table
type webauthnCredential struct {
ID int64 `xorm:"pk autoincr"`
CredentialID string `xorm:"INDEX"`
}
if err := x.Sync2(&webauthnCredential{}); err != nil {
return err
}
var start int
regs := make([]*webauthnCredential, 0, 50)
for {
err := x.OrderBy("id").Limit(50, start).Find(&regs)
if err != nil {
return err
}
for _, reg := range regs {
credID, _ := base64.RawStdEncoding.DecodeString(reg.CredentialID)
reg.CredentialID = base32.HexEncoding.EncodeToString(credID)
_, err := x.Update(reg)
if err != nil {
return err
}
}
if len(regs) < 50 {
break
}
start += 50
regs = regs[:0]
}
return nil
}

View file

@ -748,10 +748,9 @@ passcode_invalid = The passcode is incorrect. Try again.
twofa_enrolled = Your account has been enrolled into two-factor authentication. Store your scratch token (%s) in a safe place as it is only shown once! twofa_enrolled = Your account has been enrolled into two-factor authentication. Store your scratch token (%s) in a safe place as it is only shown once!
twofa_failed_get_secret = Failed to get secret. twofa_failed_get_secret = Failed to get secret.
webauthn_desc = Security keys are hardware devices containing cryptographic keys. They can be used for two-factor authentication. Security keys must support the <a rel="noreferrer" href="https://w3c.github.io/webauthn/#webauthn-authenticator">WebAuthn Authenticator</a> standard. webauthn_desc = Security keys are hardware devices containing cryptographic keys. They can be used for two-factor authentication. Security keys must support the <a rel="noreferrer" target="_blank" href="https://w3c.github.io/webauthn/#webauthn-authenticator">WebAuthn Authenticator</a> standard.
webauthn_register_key = Add Security Key webauthn_register_key = Add Security Key
webauthn_nickname = Nickname webauthn_nickname = Nickname
webauthn_press_button = Press the button on your security key to register it.
webauthn_delete_key = Remove Security Key webauthn_delete_key = Remove Security Key
webauthn_delete_key_desc = If you remove a security key you can no longer sign in with it. Continue? webauthn_delete_key_desc = If you remove a security key you can no longer sign in with it. Continue?

71
package-lock.json generated
View file

@ -4,6 +4,7 @@
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "gitea",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@claviska/jquery-minicolors": "2.3.6", "@claviska/jquery-minicolors": "2.3.6",
@ -12,7 +13,7 @@
"codemirror": "5.64.0", "codemirror": "5.64.0",
"css-loader": "6.5.1", "css-loader": "6.5.1",
"dropzone": "6.0.0-beta.2", "dropzone": "6.0.0-beta.2",
"easymde": "2.15.0", "easymde": "2.16.1",
"esbuild-loader": "2.16.0", "esbuild-loader": "2.16.0",
"escape-goat": "4.0.0", "escape-goat": "4.0.0",
"fast-glob": "3.2.7", "fast-glob": "3.2.7",
@ -1305,9 +1306,9 @@
} }
}, },
"node_modules/@types/codemirror": { "node_modules/@types/codemirror": {
"version": "0.0.109", "version": "5.60.5",
"resolved": "https://registry.npmjs.org/@types/codemirror/-/codemirror-0.0.109.tgz", "resolved": "https://registry.npmjs.org/@types/codemirror/-/codemirror-5.60.5.tgz",
"integrity": "sha512-cSdiHeeLjvGn649lRTNeYrVCDOgDrtP+bDDSFDd1TF+i0jKGPDRozno2NOJ9lTniso+taiv4kiVS8dgM8Jm5lg==", "integrity": "sha512-TiECZmm8St5YxjFUp64LK0c8WU5bxMDt9YaAek1UqUb9swrSCoJhh92fWu1p3mTEqlHjhB5sY7OFBhWroJXZVg==",
"dependencies": { "dependencies": {
"@types/tern": "*" "@types/tern": "*"
} }
@ -1380,9 +1381,9 @@
"dev": true "dev": true
}, },
"node_modules/@types/marked": { "node_modules/@types/marked": {
"version": "2.0.5", "version": "4.0.1",
"resolved": "https://registry.npmjs.org/@types/marked/-/marked-2.0.5.tgz", "resolved": "https://registry.npmjs.org/@types/marked/-/marked-4.0.1.tgz",
"integrity": "sha512-shRZ7XnYFD/8n8zSjKvFdto1QNSf4tONZIlNEZGrJe8GsOE8DL/hG1Hbl8gZlfLnjS7+f5tZGIaTgfpyW38h4w==" "integrity": "sha512-ZigEmCWdNUU7IjZEuQ/iaimYdDHWHfTe3kg8ORfKjyGYd9RWumPoOJRQXB0bO+XLkNwzCthW3wUIQtANaEZ1ag=="
}, },
"node_modules/@types/minimist": { "node_modules/@types/minimist": {
"version": "1.2.2", "version": "1.2.2",
@ -3780,15 +3781,15 @@
} }
}, },
"node_modules/easymde": { "node_modules/easymde": {
"version": "2.15.0", "version": "2.16.1",
"resolved": "https://registry.npmjs.org/easymde/-/easymde-2.15.0.tgz", "resolved": "https://registry.npmjs.org/easymde/-/easymde-2.16.1.tgz",
"integrity": "sha512-9jMRIVvKt1d0UjRN45yotUYECAM4xvw0TTAQw8sYDONP++keWJVnd8Xrn+V+vQEN/v9/X0SWEoo1rFSgCooGpw==", "integrity": "sha512-FihYgjRsKfhGNk89SHSqxKLC4aJ1kfybPWW6iAmtb5GnXu+tnFPSzSaGBmk1RRlCuhFSjhF0SnIMGVPjEzkr6g==",
"dependencies": { "dependencies": {
"@types/codemirror": "0.0.109", "@types/codemirror": "^5.60.4",
"@types/marked": "^2.0.2", "@types/marked": "^4.0.1",
"codemirror": "^5.61.0", "codemirror": "^5.63.1",
"codemirror-spell-checker": "1.1.2", "codemirror-spell-checker": "1.1.2",
"marked": "^2.0.3" "marked": "^4.0.10"
} }
}, },
"node_modules/editorconfig-checker": { "node_modules/editorconfig-checker": {
@ -7356,14 +7357,14 @@
} }
}, },
"node_modules/marked": { "node_modules/marked": {
"version": "2.1.3", "version": "4.0.10",
"resolved": "https://registry.npmjs.org/marked/-/marked-2.1.3.tgz", "resolved": "https://registry.npmjs.org/marked/-/marked-4.0.10.tgz",
"integrity": "sha512-/Q+7MGzaETqifOMWYEA7HVMaZb4XbcRfaOzcSsHZEith83KGlvaSG33u0SKu89Mj5h+T8V2hM+8O45Qc5XTgwA==", "integrity": "sha512-+QvuFj0nGgO970fySghXGmuw+Fd0gD2x3+MqCWLIPf5oxdv1Ka6b2q+z9RP01P/IaKPMEramy+7cNy/Lw8c3hw==",
"bin": { "bin": {
"marked": "bin/marked" "marked": "bin/marked.js"
}, },
"engines": { "engines": {
"node": ">= 10" "node": ">= 12"
} }
}, },
"node_modules/mathml-tag-names": { "node_modules/mathml-tag-names": {
@ -11526,9 +11527,9 @@
} }
}, },
"@types/codemirror": { "@types/codemirror": {
"version": "0.0.109", "version": "5.60.5",
"resolved": "https://registry.npmjs.org/@types/codemirror/-/codemirror-0.0.109.tgz", "resolved": "https://registry.npmjs.org/@types/codemirror/-/codemirror-5.60.5.tgz",
"integrity": "sha512-cSdiHeeLjvGn649lRTNeYrVCDOgDrtP+bDDSFDd1TF+i0jKGPDRozno2NOJ9lTniso+taiv4kiVS8dgM8Jm5lg==", "integrity": "sha512-TiECZmm8St5YxjFUp64LK0c8WU5bxMDt9YaAek1UqUb9swrSCoJhh92fWu1p3mTEqlHjhB5sY7OFBhWroJXZVg==",
"requires": { "requires": {
"@types/tern": "*" "@types/tern": "*"
} }
@ -11601,9 +11602,9 @@
"dev": true "dev": true
}, },
"@types/marked": { "@types/marked": {
"version": "2.0.5", "version": "4.0.1",
"resolved": "https://registry.npmjs.org/@types/marked/-/marked-2.0.5.tgz", "resolved": "https://registry.npmjs.org/@types/marked/-/marked-4.0.1.tgz",
"integrity": "sha512-shRZ7XnYFD/8n8zSjKvFdto1QNSf4tONZIlNEZGrJe8GsOE8DL/hG1Hbl8gZlfLnjS7+f5tZGIaTgfpyW38h4w==" "integrity": "sha512-ZigEmCWdNUU7IjZEuQ/iaimYdDHWHfTe3kg8ORfKjyGYd9RWumPoOJRQXB0bO+XLkNwzCthW3wUIQtANaEZ1ag=="
}, },
"@types/minimist": { "@types/minimist": {
"version": "1.2.2", "version": "1.2.2",
@ -13474,15 +13475,15 @@
} }
}, },
"easymde": { "easymde": {
"version": "2.15.0", "version": "2.16.1",
"resolved": "https://registry.npmjs.org/easymde/-/easymde-2.15.0.tgz", "resolved": "https://registry.npmjs.org/easymde/-/easymde-2.16.1.tgz",
"integrity": "sha512-9jMRIVvKt1d0UjRN45yotUYECAM4xvw0TTAQw8sYDONP++keWJVnd8Xrn+V+vQEN/v9/X0SWEoo1rFSgCooGpw==", "integrity": "sha512-FihYgjRsKfhGNk89SHSqxKLC4aJ1kfybPWW6iAmtb5GnXu+tnFPSzSaGBmk1RRlCuhFSjhF0SnIMGVPjEzkr6g==",
"requires": { "requires": {
"@types/codemirror": "0.0.109", "@types/codemirror": "^5.60.4",
"@types/marked": "^2.0.2", "@types/marked": "^4.0.1",
"codemirror": "^5.61.0", "codemirror": "^5.63.1",
"codemirror-spell-checker": "1.1.2", "codemirror-spell-checker": "1.1.2",
"marked": "^2.0.3" "marked": "^4.0.10"
} }
}, },
"editorconfig-checker": { "editorconfig-checker": {
@ -16117,9 +16118,9 @@
"dev": true "dev": true
}, },
"marked": { "marked": {
"version": "2.1.3", "version": "4.0.10",
"resolved": "https://registry.npmjs.org/marked/-/marked-2.1.3.tgz", "resolved": "https://registry.npmjs.org/marked/-/marked-4.0.10.tgz",
"integrity": "sha512-/Q+7MGzaETqifOMWYEA7HVMaZb4XbcRfaOzcSsHZEith83KGlvaSG33u0SKu89Mj5h+T8V2hM+8O45Qc5XTgwA==" "integrity": "sha512-+QvuFj0nGgO970fySghXGmuw+Fd0gD2x3+MqCWLIPf5oxdv1Ka6b2q+z9RP01P/IaKPMEramy+7cNy/Lw8c3hw=="
}, },
"mathml-tag-names": { "mathml-tag-names": {
"version": "2.1.3", "version": "2.1.3",

View file

@ -1,4 +1,5 @@
{ {
"name": "gitea",
"license": "MIT", "license": "MIT",
"private": true, "private": true,
"type": "module", "type": "module",

View file

@ -5,7 +5,7 @@
package auth package auth
import ( import (
"encoding/base64" "encoding/base32"
"errors" "errors"
"net/http" "net/http"
@ -131,7 +131,7 @@ func WebAuthnLoginAssertionPost(ctx *context.Context) {
} }
// Success! Get the credential and update the sign count with the new value we received. // Success! Get the credential and update the sign count with the new value we received.
dbCred, err := auth.GetWebAuthnCredentialByCredID(base64.RawStdEncoding.EncodeToString(cred.ID)) dbCred, err := auth.GetWebAuthnCredentialByCredID(user.ID, base32.HexEncoding.EncodeToString(cred.ID))
if err != nil { if err != nil {
ctx.ServerError("GetWebAuthnCredentialByCredID", err) ctx.ServerError("GetWebAuthnCredentialByCredID", err)
return return

View file

@ -38,9 +38,9 @@ func WebAuthnRegister(ctx *context.Context) {
return return
} }
_ = ctx.Session.Delete("registration") _ = ctx.Session.Delete("webauthnRegistration")
if err := ctx.Session.Set("WebauthnName", form.Name); err != nil { if err := ctx.Session.Set("webauthnName", form.Name); err != nil {
ctx.ServerError("Unable to set session key for WebauthnName", err) ctx.ServerError("Unable to set session key for webauthnName", err)
return return
} }
@ -51,7 +51,7 @@ func WebAuthnRegister(ctx *context.Context) {
} }
// Save the session data as marshaled JSON // Save the session data as marshaled JSON
if err = ctx.Session.Set("registration", sessionData); err != nil { if err = ctx.Session.Set("webauthnRegistration", sessionData); err != nil {
ctx.ServerError("Unable to set session", err) ctx.ServerError("Unable to set session", err)
return return
} }
@ -61,20 +61,20 @@ func WebAuthnRegister(ctx *context.Context) {
// WebauthnRegisterPost receives the response of the security key // WebauthnRegisterPost receives the response of the security key
func WebauthnRegisterPost(ctx *context.Context) { func WebauthnRegisterPost(ctx *context.Context) {
name, ok := ctx.Session.Get("WebauthnName").(string) name, ok := ctx.Session.Get("webauthnName").(string)
if !ok || name == "" { if !ok || name == "" {
ctx.ServerError("Get WebauthnName", errors.New("no WebauthnName")) ctx.ServerError("Get webauthnName", errors.New("no webauthnName"))
return return
} }
// Load the session data // Load the session data
sessionData, ok := ctx.Session.Get("registration").(*webauthn.SessionData) sessionData, ok := ctx.Session.Get("webauthnRegistration").(*webauthn.SessionData)
if !ok || sessionData == nil { if !ok || sessionData == nil {
ctx.ServerError("Get registration", errors.New("no registration")) ctx.ServerError("Get registration", errors.New("no registration"))
return return
} }
defer func() { defer func() {
_ = ctx.Session.Delete("registration") _ = ctx.Session.Delete("webauthnRegistration")
}() }()
// Verify that the challenge succeeded // Verify that the challenge succeeded
@ -103,6 +103,8 @@ func WebauthnRegisterPost(ctx *context.Context) {
ctx.ServerError("CreateCredential", err) ctx.ServerError("CreateCredential", err)
return return
} }
_ = ctx.Session.Delete("webauthnName")
ctx.JSON(http.StatusCreated, cred) ctx.JSON(http.StatusCreated, cred)
} }

View file

@ -12,7 +12,7 @@
<div class="hide" data-webauthn-error-msg="duplicated"><p>{{.i18n.Tr "webauthn_error_duplicated"}}</div> <div class="hide" data-webauthn-error-msg="duplicated"><p>{{.i18n.Tr "webauthn_error_duplicated"}}</div>
<div class="hide" data-webauthn-error-msg="empty"><p>{{.i18n.Tr "webauthn_error_empty"}}</div> <div class="hide" data-webauthn-error-msg="empty"><p>{{.i18n.Tr "webauthn_error_empty"}}</div>
<div class="hide" data-webauthn-error-msg="timeout"><p>{{.i18n.Tr "webauthn_error_timeout"}}</div> <div class="hide" data-webauthn-error-msg="timeout"><p>{{.i18n.Tr "webauthn_error_timeout"}}</div>
<div class="hide" data-webauthn-error-msg="0"></div> <div class="hide" data-webauthn-error-msg="general"></div>
</div> </div>
</div> </div>
<div class="actions"> <div class="actions">

View file

@ -28,16 +28,6 @@
</div> </div>
</div> </div>
<div class="ui small modal" id="register-device">
<div class="header">{{.i18n.Tr "settings.webauthn_register_key"}}</div>
<div class="content">
<i class="notched spinner loading icon"></i> {{.i18n.Tr "settings.webauthn_press_button"}}
</div>
<div class="actions">
<div class="ui cancel button">{{.i18n.Tr "cancel"}}</div>
</div>
</div>
{{template "user/auth/webauthn_error" .}} {{template "user/auth/webauthn_error" .}}
<div class="ui small basic delete modal" id="delete-registration"> <div class="ui small basic delete modal" id="delete-registration">

View file

@ -24,7 +24,7 @@ export function initUserAuthWebAuthn() {
.then((credential) => { .then((credential) => {
verifyAssertion(credential); verifyAssertion(credential);
}).catch((err) => { }).catch((err) => {
webAuthnError(0, err.message); webAuthnError('general', err.message);
}); });
}).fail(() => { }).fail(() => {
webAuthnError('unknown'); webAuthnError('unknown');
@ -113,11 +113,16 @@ function webauthnRegistered(newCredential) {
function webAuthnError(errorType, message) { function webAuthnError(errorType, message) {
$('#webauthn-error [data-webauthn-error-msg]').hide(); $('#webauthn-error [data-webauthn-error-msg]').hide();
if (errorType === 0 && message && message.length > 1) { const $errorGeneral = $(`#webauthn-error [data-webauthn-error-msg=general]`);
$(`#webauthn-error [data-webauthn-error-msg=0]`).text(message); if (errorType === 'general') {
$(`#webauthn-error [data-webauthn-error-msg=0]`).show(); $errorGeneral.show().text(message || 'unknown error');
} else { } else {
$(`#webauthn-error [data-webauthn-error-msg=${errorType}]`).show(); const $errorTyped = $(`#webauthn-error [data-webauthn-error-msg=${errorType}]`);
if ($errorTyped.length) {
$errorTyped.show();
} else {
$errorGeneral.show().text(`unknown error type: ${errorType}`);
}
} }
$('#webauthn-error').modal('show'); $('#webauthn-error').modal('show');
} }
@ -149,7 +154,6 @@ export function initUserAuthWebAuthnRegister() {
return; return;
} }
$('#register-device').modal({allowMultiple: false});
$('#webauthn-error').modal({allowMultiple: false}); $('#webauthn-error').modal({allowMultiple: false});
$('#register-webauthn').on('click', (e) => { $('#register-webauthn').on('click', (e) => {
e.preventDefault(); e.preventDefault();
@ -167,7 +171,6 @@ function webAuthnRegisterRequest() {
name: $('#nickname').val(), name: $('#nickname').val(),
}).done((makeCredentialOptions) => { }).done((makeCredentialOptions) => {
$('#nickname').closest('div.field').removeClass('error'); $('#nickname').closest('div.field').removeClass('error');
$('#register-device').modal('show');
makeCredentialOptions.publicKey.challenge = decode(makeCredentialOptions.publicKey.challenge); makeCredentialOptions.publicKey.challenge = decode(makeCredentialOptions.publicKey.challenge);
makeCredentialOptions.publicKey.user.id = decode(makeCredentialOptions.publicKey.user.id); makeCredentialOptions.publicKey.user.id = decode(makeCredentialOptions.publicKey.user.id);
@ -185,7 +188,7 @@ function webAuthnRegisterRequest() {
webAuthnError('unknown'); webAuthnError('unknown');
return; return;
} }
webAuthnError(0, err); webAuthnError('general', err.message);
}); });
}).fail((xhr) => { }).fail((xhr) => {
if (xhr.status === 409) { if (xhr.status === 409) {