wrap async calls into promises
safari complains about bare async calls not being triggered by user action after a click allow admins to have multiple open sessions general webapp tweaks to background colors and button widths
This commit is contained in:
parent
81fbcba5a0
commit
a8d18d8812
|
@ -55,10 +55,10 @@ func LoginHandler(w http.ResponseWriter, req *http.Request, ps httprouter.Params
|
|||
if err := user.Login(password); err != nil {
|
||||
code := http.StatusBadRequest
|
||||
status := http.StatusText(code)
|
||||
if err, ok := err.(*errors.InvalidCredentials); ok {
|
||||
code = err.Code()
|
||||
status = err.Error()
|
||||
err.Log()
|
||||
if invalidCreds, ok := err.(*errors.InvalidCredentials); ok {
|
||||
code = invalidCreds.Code()
|
||||
status = invalidCreds.Error()
|
||||
invalidCreds.Log()
|
||||
} else {
|
||||
logrus.Errorf("could not login %s: %s", username, err.Error())
|
||||
}
|
||||
|
|
|
@ -71,8 +71,10 @@ func NewSession(user *user.User, table db.Collection) (*Session, error) {
|
|||
Expires: user.TTL.FromNow(),
|
||||
}
|
||||
|
||||
// delete previous sessions
|
||||
table.Find(db.Cond{"user": user.ID}).Delete()
|
||||
if !user.IsAdmin {
|
||||
// delete previous sessions
|
||||
table.Find(db.Cond{"user": user.ID}).Delete()
|
||||
}
|
||||
// insert new one
|
||||
_, err := table.Insert(sess)
|
||||
return sess, err
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<meta charset="utf-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
|
||||
<title>puerta@nidi.to</title>
|
||||
<link rel="stylesheet" href="https://cdn.rob.mx/css/fonts.css" />
|
||||
<link rel="stylesheet" href="https://cdn.rob.mx/nidito/index.css" />
|
||||
|
@ -16,6 +16,7 @@
|
|||
<link rel="apple-touch-icon" sizes="152x152" href="/static/icon/152.png">
|
||||
<link rel="apple-touch-icon" sizes="384x384" href="/static/icon/384.png">
|
||||
<link rel="apple-touch-icon" sizes="192x192" href="/static/icon/192.png">
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
|
||||
<style>
|
||||
#user-list {
|
||||
display: grid;
|
||||
|
@ -250,7 +251,7 @@
|
|||
</section>
|
||||
</main>
|
||||
|
||||
<script type="module" src="https://unpkg.com/@github/webauthn-json@2.0.2/dist/esm/webauthn-json.browser-ponyfill.js"></script>
|
||||
<script type="module" src="https://unpkg.com/@github/webauthn-json@2.1.1/dist/esm/webauthn-json.browser-ponyfill.js"></script>
|
||||
<script>window._PushKey = "$PUSH_KEY$"</script>
|
||||
<script type="module" src="/static/admin.js"></script>
|
||||
</body>
|
||||
|
|
|
@ -4,7 +4,8 @@
|
|||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<meta charset="utf-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
|
||||
|
||||
<title>puerta@nidi.to</title>
|
||||
<link rel="stylesheet" href="https://cdn.rob.mx/css/fonts.css" />
|
||||
<link rel="stylesheet" href="https://cdn.rob.mx/nidito/index.css" />
|
||||
|
@ -16,6 +17,7 @@
|
|||
<link rel="apple-touch-icon" sizes="152x152" href="/static/icon/152.png">
|
||||
<link rel="apple-touch-icon" sizes="384x384" href="/static/icon/384.png">
|
||||
<link rel="apple-touch-icon" sizes="192x192" href="/static/icon/192.png">
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
|
||||
</head>
|
||||
<body>
|
||||
<header id="main-header">
|
||||
|
@ -29,7 +31,7 @@
|
|||
<button id="rex">Abrir</button>
|
||||
</form>
|
||||
</main>
|
||||
<script type="module" src="https://unpkg.com/@github/webauthn-json@2.0.2/dist/esm/webauthn-json.browser-ponyfill.js"></script>
|
||||
<script type="module" src="https://unpkg.com/@github/webauthn-json@2.1.1/dist/esm/webauthn-json.browser-ponyfill.js"></script>
|
||||
<script type="module" src="/static/index.js" async="async"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -4,11 +4,12 @@
|
|||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<meta charset="utf-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
|
||||
<title>puerta@nidi.to</title>
|
||||
<link rel="stylesheet" href="https://cdn.rob.mx/css/fonts.css" />
|
||||
<link rel="stylesheet" href="https://cdn.rob.mx/nidito/index.css" />
|
||||
<link rel="stylesheet" href="/static/index.css" />
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
|
||||
<!--link rel="manifest" href="/static/manifest.webmanifest" /-->
|
||||
</head>
|
||||
<body>
|
||||
|
|
|
@ -12,6 +12,7 @@ import (
|
|||
"mime"
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"git.rob.mx/nidito/puerta/internal/auth"
|
||||
|
@ -223,7 +224,7 @@ func Initialize(config *Config) (http.Handler, error) {
|
|||
|
||||
wan, err := webauthn.New(&webauthn.Config{
|
||||
RPDisplayName: config.Name,
|
||||
RPID: config.HTTP.Origin,
|
||||
RPID: strings.Split(config.HTTP.Origin, ":")[0],
|
||||
RPOrigins: origins,
|
||||
})
|
||||
if err != nil {
|
||||
|
|
|
@ -299,6 +299,7 @@ window.addEventListener("load", async function() {
|
|||
type: "module",
|
||||
scope: "/"
|
||||
})
|
||||
console.info(`Registered service worker`, reg)
|
||||
} catch(err) {
|
||||
console.log(`Could not register serviceworker: ${err}`)
|
||||
pnb.style.display = "none"
|
||||
|
@ -317,6 +318,7 @@ window.addEventListener("load", async function() {
|
|||
}
|
||||
} catch(err) {
|
||||
console.error("Could not get pushmanager subscription", err)
|
||||
pnb.style.display = "none"
|
||||
}
|
||||
|
||||
|
||||
|
@ -328,14 +330,6 @@ window.addEventListener("load", async function() {
|
|||
console.error("Could not get pushmanager subscription", err)
|
||||
}
|
||||
|
||||
if (sub) {
|
||||
pnb.classList.add("subscribed")
|
||||
pnb.innerHTML = "🔕"
|
||||
} else {
|
||||
pnb.classList.remove("subscribed")
|
||||
pnb.innerHTML = "🔔"
|
||||
}
|
||||
|
||||
if (!pnb.classList.contains("subscribed")) {
|
||||
if (await createPushSubscription()) {
|
||||
pnb.classList.add("subscribed")
|
||||
|
@ -347,6 +341,14 @@ window.addEventListener("load", async function() {
|
|||
pnb.innerHTML = "🔔"
|
||||
}
|
||||
}
|
||||
|
||||
if (sub) {
|
||||
pnb.classList.add("subscribed")
|
||||
pnb.innerHTML = "🔕"
|
||||
} else {
|
||||
pnb.classList.remove("subscribed")
|
||||
pnb.innerHTML = "🔔"
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
|
|
|
@ -1,16 +1,25 @@
|
|||
/* SPDX-License-Identifier: Apache-2.0
|
||||
Copyright © 2022 Roberto Hidalgo <nidito@un.rob.mx> */
|
||||
|
||||
button {
|
||||
background: rgba(255,255,255,.6);
|
||||
font-family: "Aestetico", sans-serif;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
display: block;
|
||||
color: #c11145;
|
||||
border: 5px solid #c11145;
|
||||
transition: all ease-in-out .5s;
|
||||
}
|
||||
|
||||
main.container button {
|
||||
display: block;
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
font-size: 1.5em;
|
||||
border-radius: .4em;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.container {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
@ -85,11 +94,38 @@ input[type=checkbox] {
|
|||
}
|
||||
|
||||
@media screen and (max-width: 768px) {
|
||||
html { height: -webkit-fill-available; }
|
||||
body {
|
||||
background-color: #c11145;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 100vh;
|
||||
min-height: -webkit-fill-available;
|
||||
}
|
||||
main {
|
||||
background-color: rgb(255, 198, 215);
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
#main-header {
|
||||
position: sticky;
|
||||
padding-top: env(safe-area-inset-top);
|
||||
top: 0;
|
||||
}
|
||||
|
||||
input {
|
||||
max-width: 100%;
|
||||
}
|
||||
button {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
#auth {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.container {
|
||||
padding-bottom: env(safe-area-inset-bottom);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -38,7 +38,9 @@ export async function withAuth(target, config) {
|
|||
if (step == "register") {
|
||||
// server told us to register new credentials
|
||||
// we try to do that
|
||||
await register(challenge, target)
|
||||
await new Promise((res,rej) => {
|
||||
register(challenge, target).then(res).catch(rej)
|
||||
})
|
||||
// and retry the original request if successful
|
||||
return await new Promise((res, rej) => {
|
||||
setTimeout(async () => {
|
||||
|
@ -51,7 +53,9 @@ export async function withAuth(target, config) {
|
|||
})
|
||||
} else if (step == "login") {
|
||||
// server told us to use existing credential for request
|
||||
return await login(challenge, target, config)
|
||||
return await new Promise((res,rej) => {
|
||||
return login(challenge, target, config).then(res).catch(rej)
|
||||
})
|
||||
}
|
||||
|
||||
throw `Unknown webauthn step: <${step}>`
|
||||
|
|
Loading…
Reference in New Issue