fix webcomponent
This commit is contained in:
parent
bf7e3d7785
commit
eee573eb47
@ -41,15 +41,15 @@ func UserFromContext(req *http.Request) *User {
|
|||||||
|
|
||||||
type User struct {
|
type User struct {
|
||||||
ID int `db:"id" json:"-"`
|
ID int `db:"id" json:"-"`
|
||||||
Handle string `db:"user" json:"user"`
|
Handle string `db:"handle" json:"handle"`
|
||||||
Name string `db:"name" json:"name"`
|
Name string `db:"name" json:"name"`
|
||||||
Password string `db:"password" json:"password"`
|
Password string `db:"password" json:"-"`
|
||||||
Schedule *UserSchedule `db:"schedule,omitempty" json:"schedule"`
|
Schedule *UserSchedule `db:"schedule,omitempty" json:"schedule"`
|
||||||
Expires *time.Time `db:"expires,omitempty" json:"expires"`
|
Expires *time.Time `db:"expires,omitempty" json:"expires"`
|
||||||
Greeting string `db:"greeting" json:"greeting"`
|
Greeting string `db:"greeting" json:"greeting"`
|
||||||
TTL *TTL `db:"max_ttl,omitempty" json:"max_ttl"`
|
TTL *TTL `db:"max_ttl,omitempty" json:"max_ttl"`
|
||||||
Require2FA bool `db:"second_factor" json:"second_factor"`
|
Require2FA bool `db:"second_factor" json:"second_factor"`
|
||||||
IsAdmin bool `db:"is_admin" json:"admin"`
|
IsAdmin bool `db:"is_admin" json:"is_admin"`
|
||||||
credentials []*Credential
|
credentials []*Credential
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -140,4 +140,6 @@ func (user *User) Login(password string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// implement interfaces
|
||||||
var _ = db.Record(&User{})
|
var _ = db.Record(&User{})
|
||||||
|
var _ = webauthn.User(&User{})
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
<main class="container">
|
<main class="container">
|
||||||
<section id="create-user">
|
<section id="create-user" style="display:none">
|
||||||
<h2>Crear usuario</h2>
|
<h2>Crear usuario</h2>
|
||||||
<form id="create-user" method="post" action="/api/user">
|
<form id="create-user" method="post" action="/api/user">
|
||||||
<label for="user">Handle</label>
|
<label for="user">Handle</label>
|
||||||
@ -61,14 +61,13 @@
|
|||||||
</main>
|
</main>
|
||||||
<script type="module" src="/static/admin.js"></script>
|
<script type="module" src="/static/admin.js"></script>
|
||||||
|
|
||||||
<template id="user-info-panel">
|
<template id="user-info-panel"><li class="user-info-panel">
|
||||||
<li class="user-info-panel {{ if .IsAdmin }}user-info-panel-admin{{ end }}">
|
|
||||||
<header>
|
<header>
|
||||||
<h3><slot name="name">{{ .Name }}</h3>
|
<h3><slot name="name">Alguien</h3>
|
||||||
<code><pre>{{ .Handle }}</pre></code>
|
<code><pre>alguien</pre></code>
|
||||||
<button class="user-edit">Modificar</button>
|
<button class="user-edit">Modificar</button>
|
||||||
</header>
|
</header>
|
||||||
<div class="user-info-panel-details">
|
<form action="/api/user/:id" class="user-info-panel-details">
|
||||||
<label for="name">Nombre</label>
|
<label for="name">Nombre</label>
|
||||||
<input name="name" value="" placeholder="João Gilberto" />
|
<input name="name" value="" placeholder="João Gilberto" />
|
||||||
|
|
||||||
@ -95,8 +94,7 @@
|
|||||||
|
|
||||||
<button class="user-delete">Eliminar</button>
|
<button class="user-delete">Eliminar</button>
|
||||||
<button class="user-save">Guardar cambios</button>
|
<button class="user-save">Guardar cambios</button>
|
||||||
</div>
|
</form>
|
||||||
</li>
|
</li></template>
|
||||||
</template>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -180,8 +180,7 @@ func Initialize(config *Config) (http.Handler, error) {
|
|||||||
router.POST("/api/rex", am.Enforce2FA(rex))
|
router.POST("/api/rex", am.Enforce2FA(rex))
|
||||||
router.GET("/admin", am.RequireAdmin(renderTemplate(adminTemplate)))
|
router.GET("/admin", am.RequireAdmin(renderTemplate(adminTemplate)))
|
||||||
router.GET("/api/user", am.RequireAdmin(listUsers))
|
router.GET("/api/user", am.RequireAdmin(listUsers))
|
||||||
// router.GET("/api/user/:id", am.RequireAdmin(getUser))
|
router.GET("/api/user/:id", am.RequireAdmin(getUser))
|
||||||
router.GET("/api/user/:id", getUser)
|
|
||||||
router.PUT("/api/user", am.RequireAdmin(am.Enforce2FA(createUser)))
|
router.PUT("/api/user", am.RequireAdmin(am.Enforce2FA(createUser)))
|
||||||
router.POST("/api/user/:id", am.RequireAdmin(am.Enforce2FA(updateUser)))
|
router.POST("/api/user/:id", am.RequireAdmin(am.Enforce2FA(updateUser)))
|
||||||
router.DELETE("/api/user/:id", am.RequireAdmin(am.Enforce2FA(deleteUser)))
|
router.DELETE("/api/user/:id", am.RequireAdmin(am.Enforce2FA(deleteUser)))
|
||||||
|
@ -1,32 +1,35 @@
|
|||||||
const button = document.querySelector("#open button")
|
const button = document.querySelector("#open button")
|
||||||
const form = document.querySelector("#open")
|
const form = document.querySelector("#open")
|
||||||
const { create: createCredentials, get: getCredentials } = hankoWebAuthn;
|
|
||||||
|
|
||||||
const userList = document.querySelector("#user-list > ul")
|
const userList = document.querySelector("#user-list > ul")
|
||||||
|
|
||||||
|
class UserInfoPanel extends HTMLElement {
|
||||||
|
constructor(user) {
|
||||||
|
super()
|
||||||
|
let template = document.getElementById("user-info-panel")
|
||||||
|
const shadowRoot = this.attachShadow({ mode: "open" })
|
||||||
|
const panel = template.content.cloneNode(true)
|
||||||
|
|
||||||
|
let handle = user.handle
|
||||||
|
panel.querySelector('h3').innerHTML = user.name
|
||||||
|
panel.querySelector('input[name=name]').value = user.name
|
||||||
|
|
||||||
|
panel.querySelector('form').action = panel.querySelector('form').action.replace(":id", handle)
|
||||||
|
panel.querySelector('pre').textContent = handle
|
||||||
|
|
||||||
|
panel.querySelector('input[name=greeting]').value = user.greeting
|
||||||
|
panel.querySelector('input[name=schedule]').value = user.schedule
|
||||||
|
panel.querySelector('input[name=expires]').value = user.expires
|
||||||
|
panel.querySelector('input[name=max_ttl]').value = user.max_ttl
|
||||||
|
panel.querySelector('input[name=is_admin]').checked = user.is_admin
|
||||||
|
panel.querySelector('input[name=second_factor]').checked = user.second_factor
|
||||||
|
shadowRoot.appendChild(panel)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
customElements.define(
|
customElements.define(
|
||||||
"user-info-panel",
|
"user-info-panel",
|
||||||
class extends HTMLElement {
|
UserInfoPanel
|
||||||
constructor() {
|
|
||||||
super()
|
|
||||||
let template = document.getElementById("user-info-panel")
|
|
||||||
const shadowRoot = this.attachShadow({ mode: "open" })
|
|
||||||
const panel = template.content.cloneNode(true)
|
|
||||||
|
|
||||||
panel.querySelector('h3').textContent = this.getAttribute('name')
|
|
||||||
panel.querySelector('name').value = this.getAttribute('name')
|
|
||||||
panel.querySelector('pre').textContent = this.getAttribute('handle')
|
|
||||||
|
|
||||||
panel.querySelector('greeting').value = this.getAttribute('greeting')
|
|
||||||
panel.querySelector('schedule').value = this.getAttribute('schedule')
|
|
||||||
panel.querySelector('expires').value = this.getAttribute('expires')
|
|
||||||
panel.querySelector('max_ttl').value = this.getAttribute('ttl')
|
|
||||||
panel.querySelector('is_admin').checked = this.hasAttribute('admin')
|
|
||||||
panel.querySelector('second_factor').checked = this.hasAttribute('second_factor')
|
|
||||||
shadowRoot.appendChild(panel)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
|
|
||||||
async function fetchUsers() {
|
async function fetchUsers() {
|
||||||
@ -46,25 +49,26 @@ async function fetchUsers() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
userList.replaceChildren(json.map(u => {
|
json.forEach(u => {
|
||||||
const ip = document.createElement("user-info-panel")
|
const ip = new UserInfoPanel(u)
|
||||||
ip.setAttribute("name", u.name)
|
ip.setAttribute("data-name", u.name)
|
||||||
ip.setAttribute("handle", u.handle)
|
ip.setAttribute("data-handle", u.handle)
|
||||||
|
|
||||||
ip.setAttribute('greeting', u.greeting)
|
ip.setAttribute('data-greeting', u.greeting)
|
||||||
ip.setAttribute('schedule', u.schedule)
|
ip.setAttribute('data-schedule', u.schedule)
|
||||||
ip.setAttribute('expires', u.expires)
|
ip.setAttribute('data-expires', u.expires)
|
||||||
ip.setAttribute('max_ttl', u.ttl)
|
ip.setAttribute('data-max_ttl', u.max_ttl)
|
||||||
if (u.admin) {
|
if (u.admin) {
|
||||||
ip.setAttribute('is_admin', "")
|
ip.setAttribute('data-is_admin', "")
|
||||||
}
|
}
|
||||||
if (u.second_factor) {
|
if (u.second_factor) {
|
||||||
ip.setAttribute('second_factor', "")
|
ip.setAttribute('data-second_factor', "")
|
||||||
}
|
}
|
||||||
|
|
||||||
return ip
|
return userList.append(ip)
|
||||||
}))
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
window.addEventListener("load", async function() {
|
||||||
|
await fetchUsers()
|
||||||
|
})
|
||||||
|
Loading…
Reference in New Issue
Block a user