Major lavender template rewrite and minor build tweaks

This commit is contained in:
Melon 2024-05-16 22:28:11 +01:00
parent 1014ffeb8b
commit 099e877065
Signed by: melon
GPG Key ID: 6C9D970C50D26A25
14 changed files with 517 additions and 280 deletions

View File

@ -1,7 +1,11 @@
{
"ServiceName": "Test Service",
"DisplayName": "Test User",
"Subject": "uuid",
"Auth": {
"Subject": "user uuid",
"UserInfo": {
"name": "Test User"
}
},
"IsAdmin": true,
"LoginName": "jane@example.com",
"WantsList": [
@ -9,5 +13,44 @@
"Another perm"
],
"AppName": "Marshmallow Sample App",
"AppDomain": "https://marshmallow.example.com"
"AppDomain": "https://marshmallow.example.com",
"NewAppSecret": "$$AppSecret$$",
"NewAppName": "Marshmallow Sample App",
"EditApp": {
"Subject": "msa-uuid",
"Name": "Marshmallow Sample App",
"Domain": "http://marshmallow.example.com",
"Perms": "lavender:subject",
"Public": true,
"Sso": false,
"Active": true
},
"Apps": [
{
"Subject": "msa-uuid",
"Name": "Marshmallow Sample App",
"Domain": "http://marshmallow.example.com",
"Perms": "lavender:subject",
"Public": true,
"Sso": false,
"Active": true,
"Owner": true
}
],
"EditUser": {
"Subject": "msu-uuid",
"Roles": "msu:role",
"Active": true
},
"Users": [
{
"Subject": "msu-uuid",
"Email": "jane@example.com",
"EmailVerified": true,
"Roles": "msu:role",
"LastUpdated": "2024-01-01",
"Active": true
}
],
"Offset": 0
}

View File

@ -1,8 +1,8 @@
<div class="sticky top-0 z-40 w-full backdrop-blur flex-none lg:z-50 lg:border-b lg:border-slate-900/10 dark:border-slate-50/[0.06] bg-white/95 supports-backdrop-blur:bg-white/60 dark:bg-transparent">
<header>
<div class="max-w-8xl mx-auto">
<div class="py-4 border-b border-slate-900/10 lg:px-8 lg:border-0 dark:border-slate-300/10 mx-4 lg:mx-0">
<div class="relative flex items-center">
<a class="mr-3 flex-none flex w-[2.0625rem] overflow-hidden md:w-auto" href="/">
<a class="mr-3 flex-none flex w-[2.0625rem] overflow-hidden md:w-auto items-center font-bold" href="/">
<span class="sr-only">{{.ServiceName}}</span>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-key-round text-slate-900 dark:text-white w-auto h-5">
<path d="M2 18v3c0 .6.4 1 1 1h4v-3h3v-3h2l1.4-1.4a6.5 6.5 0 1 0-4-4Z"/>
@ -11,13 +11,13 @@
<span class="hidden md:block">{{.ServiceName}}</span>
</a>
<div class="relative hidden lg:flex items-center ml-auto">
<nav class="text-sm leading-6 font-semibold text-slate-700 dark:text-slate-200">
<nav class="text-sm leading-6 font-semibold">
<ul class="flex space-x-8">
<li><a class="hover:text-sky-500 dark:hover:text-sky-400" href="https://example.com">Example Button</a></li>
<li><a class="" href="https://example.com">Example Button</a></li>
</ul>
</nav>
</div>
</div>
</div>
</div>
</div>
</header>

View File

@ -1,21 +1,19 @@
<!DOCTYPE html>
<html lang="en" class="bg-gray-900">
<html lang="en">
<head>
<title>{{.ServiceName}}</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<link rel="stylesheet" href="/assets/style.css">
</head>
<body class="min-h-screen">
<body>
{{template "header.go.html" .}}
<main class="flex flex-col items-center mx-auto">
<div class="block rounded-lg shadow bg-gray-800 border border-gray-700 m-8 sm:max-w-md w-full">
<div class="p-6 sm:p-8 space-y-4 md:space-y-6">
<h1 class="text-xl font-bold leading-tight tracking-tight text-gray-900 md:text-2xl dark:text-white text-center">{{.ServiceName}}</h1>
<form method="GET" action="/login" class="space-y-4 md:space-y-6">
<div>Not logged in</div>
<button type="submit" class="w-full text-white bg-emerald-600 hover:bg-emerald-700 focus:ring-4 focus:outline-none focus:ring-emerald-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center dark:bg-emerald-600 dark:hover:bg-emerald-700 dark:focus:ring-emerald-800">Login</button>
</form>
</div>
<main>
<div class="center-box sm:max-w-md">
<h1 class="box-title">{{.ServiceName}}</h1>
<form method="GET" action="/login" class="space-y-4 md:space-y-6">
<div>Not logged in</div>
<button type="submit" class="btn-green">Login</button>
</form>
</div>
</main>
</body>

View File

@ -1,30 +1,28 @@
<!DOCTYPE html>
<html lang="en" class="bg-gray-900">
<html lang="en">
<head>
<title>{{.ServiceName}}</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<link rel="stylesheet" href="/assets/style.css">
</head>
<body class="min-h-screen">
<body>
{{template "header.go.html" .}}
<main class="flex flex-col items-center mx-auto">
<div class="block rounded-lg shadow bg-gray-800 border border-gray-700 m-8 sm:max-w-md w-full">
<div class="p-6 sm:p-8 space-y-4 md:space-y-6">
<h1 class="text-xl font-bold leading-tight tracking-tight text-gray-900 md:text-2xl dark:text-white text-center">{{.ServiceName}}</h1>
<div>Logged in as: {{.Auth.UserInfo.name}} ({{.Auth.Subject}})</div>
<form method="GET" action="/manage/apps" class="space-y-4 md:space-y-6">
<button type="submit" class="w-full text-white bg-emerald-600 hover:bg-emerald-700 focus:ring-4 focus:outline-none focus:ring-emerald-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center dark:bg-emerald-600 dark:hover:bg-emerald-700 dark:focus:ring-emerald-800">Manage Applications</button>
<main>
<div class="center-box sm:max-w-md">
<h1 class="box-title">{{.ServiceName}}</h1>
<div>Logged in as: {{.Auth.UserInfo.name}} ({{.Auth.Subject}})</div>
<form method="GET" action="/manage/apps" class="space-y-4 md:space-y-6">
<button type="submit" class="btn-green">Manage Applications</button>
</form>
{{if .IsAdmin}}
<form method="GET" action="/manage/users" class="space-y-4 md:space-y-6">
<button type="submit" class="btn-green">Manage Users</button>
</form>
{{if .IsAdmin}}
<form method="GET" action="/manage/users" class="space-y-4 md:space-y-6">
<button type="submit" class="w-full text-white bg-emerald-600 hover:bg-emerald-700 focus:ring-4 focus:outline-none focus:ring-emerald-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center dark:bg-emerald-600 dark:hover:bg-emerald-700 dark:focus:ring-emerald-800">Manage Users</button>
</form>
{{end}}
<form method="POST" action="/logout">
<input type="hidden" name="nonce" value="{{.Nonce}}">
<button type="submit" class="w-full text-white bg-rose-600 hover:bg-rose-700 focus:ring-4 focus:outline-none focus:ring-rose-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center dark:bg-rose-600 dark:hover:bg-rose-700 dark:focus:ring-rose-800">Log out</button>
</form>
</div>
{{end}}
<form method="POST" action="/logout">
<input type="hidden" name="nonce" value="{{.Nonce}}">
<button type="submit" class="btn-red">Log out</button>
</form>
</div>
</main>
</body>

View File

@ -1,30 +1,28 @@
<!DOCTYPE html>
<html lang="en" class="bg-gray-900">
<html lang="en">
<head>
<title>{{.ServiceName}}</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="/assets/style.css">
</head>
<body class="min-h-screen">
<body>
{{template "header.go.html" .}}
<main class="flex flex-col items-center mx-auto">
<div class="block rounded-lg shadow bg-gray-800 border border-gray-700 m-8 sm:max-w-md w-full">
<div class="p-6 sm:p-8 space-y-4 md:space-y-6">
<h1 class="text-xl font-bold leading-tight tracking-tight text-gray-900 md:text-2xl dark:text-white text-center">Login</h1>
<main>
<div class="center-box sm:max-w-md">
<h1 class="box-title">Login</h1>
<div>
<label for="field_loginname" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Log in as</label>
<input disabled value="{{.LoginName}}" type="email" name="loginname" id="field_loginname" class="bg-gray-50 border border-gray-300 text-gray-900 sm:text-sm rounded-lg focus:ring-primary-600 focus:border-primary-600 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-gray-400 dark:focus:ring-blue-500 dark:focus:border-blue-500" placeholder="name@company.com" required>
<label for="field_loginname">Log in as</label>
<input disabled value="{{.LoginName}}" type="email" name="loginname" id="field_loginname" placeholder="name@company.com" required>
</div>
<form method="POST" action="/login">
<button type="submit" name="not-you" value="1" class="w-full text-white bg-rose-600 hover:bg-rose-700 focus:ring-4 focus:outline-none focus:ring-rose-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center dark:bg-rose-600 dark:hover:bg-rose-700 dark:focus:ring-rose-800">Not You?</button>
<button type="submit" name="not-you" value="1" class="btn-red">Not You?</button>
</form>
<form method="POST" action="/login">
<input type="hidden" name="redirect" value="{{.Redirect}}"/>
<input type="hidden" name="loginname" value="{{.LoginName}}"/>
<button type="submit" class="w-full text-white bg-emerald-600 hover:bg-emerald-700 focus:ring-4 focus:outline-none focus:ring-emerald-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center dark:bg-emerald-600 dark:hover:bg-emerald-700 dark:focus:ring-emerald-800">Continue</button>
<button type="submit" class="btn-green">Continue</button>
</form>
</div>
</div>
</main>
</body>
</html>

View File

@ -1,25 +1,23 @@
<!DOCTYPE html>
<html lang="en" class="bg-gray-900">
<html lang="en">
<head>
<title>{{.ServiceName}}</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<link rel="stylesheet" href="/assets/style.css">
</head>
<body class="min-h-screen">
<body>
{{template "header.go.html" .}}
<main class="flex flex-col items-center mx-auto">
<div class="block rounded-lg shadow bg-gray-800 border border-gray-700 m-8 sm:max-w-md w-full">
<div class="p-6 sm:p-8 space-y-4 md:space-y-6">
<h1 class="text-xl font-bold leading-tight tracking-tight text-gray-900 md:text-2xl dark:text-white text-center">Login</h1>
<form method="POST" action="/login" class="space-y-4 md:space-y-6">
<input type="hidden" name="redirect" value="{{.Redirect}}"/>
<div>
<label for="field_loginname" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Your email</label>
<input type="email" name="loginname" id="field_loginname" class="bg-gray-50 border border-gray-300 text-gray-900 sm:text-sm rounded-lg focus:ring-primary-600 focus:border-primary-600 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500" placeholder="name@company.com" required>
</div>
<button type="submit" class="w-full text-white bg-emerald-600 hover:bg-emerald-700 focus:ring-4 focus:outline-none focus:ring-emerald-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center dark:bg-emerald-600 dark:hover:bg-emerald-700 dark:focus:ring-emerald-800">Login</button>
</form>
</div>
<main>
<div class="center-box sm:max-w-md">
<h1 class="box-title">Login</h1>
<form method="POST" action="/login" class="space-y-4 md:space-y-6">
<input type="hidden" name="redirect" value="{{.Redirect}}"/>
<div>
<label for="field_loginname">Your email</label>
<input type="email" name="loginname" id="field_loginname" placeholder="name@company.com" required>
</div>
<button type="submit" class="btn-green">Login</button>
</form>
</div>
</main>
</body>

View File

@ -3,5 +3,83 @@
@tailwind utilities;
html {
@apply bg-zinc-900 text-zinc-300 scroll-smooth selection:bg-fuchsia-400/30 text-pretty;
@apply bg-white dark:bg-gray-900 text-black dark:text-gray-200 scroll-smooth selection:bg-blue-500 text-pretty;
}
body {
@apply min-h-screen;
}
@layer components {
header {
@apply sticky top-0 z-40 w-full backdrop-blur flex-none lg:z-50 lg:border-b lg:border-slate-900/10 dark:border-slate-50/[0.06] bg-emerald-500/95 dark:bg-transparent text-black dark:text-gray-200;
}
main {
@apply flex flex-col items-center mx-auto p-8;
}
.center-box {
@apply block rounded-lg shadow bg-gray-200 dark:bg-gray-800 border border-gray-700 w-full p-6 sm:p-8 space-y-4 md:space-y-6;
}
.center-box h1.box-title {
@apply text-xl font-bold leading-tight tracking-tight md:text-2xl text-center;
}
button {
@apply w-full text-white focus:ring-4 focus:outline-none font-medium rounded-lg text-sm px-5 py-2.5 text-center;
}
button.btn-green {
@apply bg-emerald-600 hover:bg-emerald-700 focus:ring-emerald-300 dark:bg-emerald-600 dark:hover:bg-emerald-700 dark:focus:ring-emerald-800;
}
button.btn-red {
@apply bg-rose-600 hover:bg-rose-700 focus:ring-rose-300 dark:bg-rose-600 dark:hover:bg-rose-700 dark:focus:ring-rose-800;
}
button.btn-amber {
@apply bg-amber-600 hover:bg-amber-700 focus:ring-amber-300 dark:bg-amber-600 dark:hover:bg-amber-700 dark:focus:ring-amber-800;
}
label[for] {
@apply block mb-2 text-sm font-medium text-gray-900 dark:text-white;
}
input[type=text], input[type=email] {
@apply bg-gray-50 border border-gray-300 text-gray-900 sm:text-sm rounded-lg focus:ring-emerald-600 focus:border-emerald-600 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500;
}
input[type=checkbox] {
@apply focus:outline-none appearance-none relative w-6 h-6 border border-gray-300 rounded bg-gray-50 focus:ring-2 focus:ring-emerald-300 dark:bg-gray-700 dark:border-gray-600 dark:focus:ring-emerald-600 dark:ring-offset-gray-800 checked:bg-emerald-700;
}
input[type=checkbox] + svg.check {
@apply absolute w-6 h-6 mt-1 hidden pointer-events-none text-gray-200;
}
input[type=checkbox]:checked + svg.check {
@apply block;
}
table.table-default {
@apply w-full text-sm text-left rtl:text-right text-gray-500 dark:text-gray-200;
}
table.table-default thead {
@apply text-xs text-gray-700 bg-gray-200 dark:bg-gray-700 dark:text-gray-200;
}
table.table-default thead tr th {
@apply px-6 py-3 text-center;
}
table.table-default tbody {
@apply bg-white dark:bg-gray-800;
}
table.table-default tbody tr td {
@apply px-6 py-4 text-center;
}
}

View File

@ -0,0 +1,77 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>{{.ServiceName}}</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<link rel="stylesheet" href="/assets/style.css">
</head>
<body>
{{template "header.go.html" .}}
<main>
<div class="center-box sm:max-w-2xl">
<h1 class="box-title">Create Client Application</h1>
<form method="POST" action="/manage/apps" class="space-y-4 md:space-y-6">
<input type="hidden" name="action" value="create"/>
<input type="hidden" name="offset" value="{{.Offset}}"/>
<div>
<label for="field_name">Name:</label>
<input type="text" name="name" id="field_name" required/>
</div>
<div>
<label for="field_domain">Domain:</label>
<input type="text" name="domain" id="field_domain" placeholder="https://example.com" required/>
</div>
{{if .IsAdmin}}
<div>
<label for="field_perms">Perms:</label>
<input type="text" name="perms" id="field_perms" size="100"/>
</div>
{{end}}
<div class="flex flex-row justify-center">
<div class="space-y-4 md:space-y-6">
<div class="flex">
<div class="flex items-center h-5">
<input id="field_public" name="public" type="checkbox"/>
<svg class="check" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="4" stroke-linecap="round" stroke-linejoin="round">
<polyline points="20 6 9 17 4 12"></polyline>
</svg>
</div>
<div class="ml-3 text-sm">
<label for="field_public">Make this a client-only application</label>
</div>
</div>
{{if .IsAdmin}}
<div class="flex">
<div class="flex items-center h-5">
<input id="field_sso" name="sso" type="checkbox"/>
<svg class="check" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="4" stroke-linecap="round" stroke-linejoin="round">
<polyline points="20 6 9 17 4 12"></polyline>
</svg>
</div>
<div class="ml-3 text-sm">
<label for="field_sso">Enable automatic SSO flow</label>
</div>
</div>
{{end}}
<div class="flex">
<div class="flex items-center h-5">
<input id="field_active" name="active" type="checkbox" checked/>
<svg class="check" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="4" stroke-linecap="round" stroke-linejoin="round">
<polyline points="20 6 9 17 4 12"></polyline>
</svg>
</div>
<div class="ml-3 text-sm">
<label for="field_active">Enable the application</label>
</div>
</div>
</div>
</div>
<div class="grid grid-cols-2 gap-4">
<button name="create_action" value="create" class="btn-green">Create</button>
<button name="create_action" value="cancel" class="btn-red">Cancel</button>
</div>
</form>
</div>
</main>
</body>
</html>

View File

@ -0,0 +1,81 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>{{.ServiceName}}</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<link rel="stylesheet" href="/assets/style.css">
</head>
<body>
{{template "header.go.html" .}}
<main>
<div class="center-box sm:max-w-2xl">
<h1 class="box-title">Edit Client Application</h1>
<form method="POST" action="/manage/apps" class="space-y-4 md:space-y-6">
<input type="hidden" name="action" value="create"/>
<input type="hidden" name="offset" value="{{.Offset}}"/>
<input type="hidden" name="subject" value="{{.EditApp.Subject}}"/>
<div>
<label for="field_subject">Subject: {{.EditApp.Subject}}</label>
</div>
<div>
<label for="field_name">Name:</label>
<input type="text" name="name" id="field_name" value="{{.EditApp.Name}}" required/>
</div>
<div>
<label for="field_domain">Domain:</label>
<input type="text" name="domain" id="field_domain" value="{{.EditApp.Domain}}" placeholder="https://example.com" required/>
</div>
{{if .IsAdmin}}
<div>
<label for="field_perms">Perms:</label>
<input type="text" name="perms" id="field_perms" value="{{.EditApp.Perms}}" size="100"/>
</div>
{{end}}
<div class="flex flex-row justify-center">
<div class="space-y-4 md:space-y-6">
<div class="flex">
<div class="flex items-center h-5">
<input id="field_public" name="public" type="checkbox" {{if .EditApp.Public}}checked{{end}}/>
<svg class="check" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="4" stroke-linecap="round" stroke-linejoin="round">
<polyline points="20 6 9 17 4 12"></polyline>
</svg>
</div>
<div class="ml-3 text-sm">
<label for="field_public">Make this a client-only application</label>
</div>
</div>
{{if .IsAdmin}}
<div class="flex">
<div class="flex items-center h-5">
<input id="field_sso" name="sso" type="checkbox" {{if .EditApp.Sso}}checked{{end}}/>
<svg class="check" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="4" stroke-linecap="round" stroke-linejoin="round">
<polyline points="20 6 9 17 4 12"></polyline>
</svg>
</div>
<div class="ml-3 text-sm">
<label for="field_sso">Enable automatic SSO flow</label>
</div>
</div>
{{end}}
<div class="flex">
<div class="flex items-center h-5">
<input id="field_active" name="active" type="checkbox" {{if .EditApp.Active}}checked{{end}}/>
<svg class="check" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="4" stroke-linecap="round" stroke-linejoin="round">
<polyline points="20 6 9 17 4 12"></polyline>
</svg>
</div>
<div class="ml-3 text-sm">
<label for="field_active">Enable the application</label>
</div>
</div>
</div>
</div>
<div class="grid grid-cols-2 gap-4">
<button name="edit_action" value="edit" class="btn-green">Save</button>
<button name="edit_action" value="cancel" class="btn-red">Cancel</button>
</div>
</form>
</div>
</main>
</body>
</html>

View File

@ -1,5 +1,5 @@
<!DOCTYPE html>
<html lang="en" class="bg-gray-900">
<html lang="en">
<head>
<title>{{.ServiceName}}</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
@ -31,130 +31,62 @@
</head>
<body>
{{template "header.go.html" .}}
<main>
<main class="space-y-4 sm:space-y-6">
{{if .NewAppSecret}}
<div>New application secret: <span id="app-secret">{{.NewAppSecret}}</span> for {{.NewAppName}}</div>
<div class="block text-black text-center rounded-lg shadow bg-rose-400 border border-gray-700 mb-0 sm:max-w-2xl w-full p-6 sm:p-8">New application secret: <span id="app-secret">{{.NewAppSecret}}</span> for {{.NewAppName}}</div>
{{end}}
{{if .Edit}}
<h2>Edit Client Application</h2>
<form method="POST" action="/manage/apps">
<input type="hidden" name="action" value="edit"/>
<input type="hidden" name="offset" value="{{.Offset}}"/>
<input type="hidden" name="subject" value="{{.Edit.Sub}}"/>
<div>
<label>ID: {{.Edit.Sub}}</label>
</div>
<div>
<label for="field_name">Name:</label>
<input type="text" name="name" id="field_name" value="{{.Edit.Name}}" required/>
</div>
<div>
<label for="field_domain">Domain:</label>
<input type="text" name="domain" id="field_domain" value="{{.Edit.Domain}}" required/>
</div>
{{if .IsAdmin}}
<div>
<label for="field_perms">Perms:</label>
<input type="text" name="perms" id="field_perms" value="{{.Edit.Perms}}" size="100"/>
</div>
{{end}}
<div>
<label for="field_public">Public: <input type="checkbox" name="public" id="field_public" {{if .Edit.Public}}checked{{end}}/></label>
</div>
{{if .IsAdmin}}
<div>
<label for="field_sso">SSO: <input type="checkbox" name="sso" id="field_sso" {{if .Edit.SSO}}checked{{end}}/></label>
</div>
{{end}}
<div>
<label for="field_active">Active: <input type="checkbox" name="active" id="field_active" {{if .Edit.Active}}checked{{end}}/></label>
</div>
<button type="submit">Edit</button>
</form>
<form method="GET" action="/manage/apps">
<input type="hidden" name="offset" value="{{.Offset}}"/>
<button type="submit">Cancel</button>
</form>
{{else}}
<h2>Manage Client Applications</h2>
{{if eq (len .Apps) 0}}
<div>No client applications found</div>
{{else}}
<table>
<thead>
<h1 class="box-title">Manage Client Applications</h1>
<div class="relative overflow-x-auto shadow-md sm:rounded-lg">
<table class="table-default">
<thead>
<tr>
<th>Name</th>
<th>Domain</th>
<th>Active</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{{if eq (len .Apps) 0}}
<tr>
<th>ID</th>
<th>Name</th>
<th>Domain</th>
<th>Perms</th>
<th>SSO</th>
<th>Active</th>
<th>Owner</th>
<th>Actions</th>
<td colspan="9">No client applications found</td>
</tr>
</thead>
<tbody>
{{range .Apps}}
<tr>
<td>{{.Sub}}</td>
<td>{{.Name}}</td>
<td>{{.Domain}}</td>
<td>{{.Perms}}</td>
<td>{{.SSO}}</td>
<td>{{.Active}}</td>
<td>{{.Owner}}</td>
<td>
{{end}}
{{range .Apps}}
<tr>
<td>{{.Name}}</td>
<td>{{.Domain}}</td>
<td>
<label class="flex items-center">
<input type="checkbox" disabled class="focus:outline-none appearance-none relative peer w-6 h-6 border border-gray-300 rounded bg-gray-50 focus:ring focus:ring-3 focus:ring-emerald-300 dark:bg-gray-700 dark:border-gray-600 dark:focus:ring-emerald-600 dark:ring-offset-gray-800 checked:bg-emerald-700" {{if .Active}}checked{{end}}/>
<svg class="absolute w-6 h-6 mt-1 hidden peer-checked:block pointer-events-none text-gray-200" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="4" stroke-linecap="round" stroke-linejoin="round">
<polyline points="20 6 9 17 4 12"></polyline>
</svg>
<span class="hidden">Active</span>
</label>
</td>
<td>
<div class="grid grid-cols-1 gap-4">
<form method="GET" action="/manage/apps">
<input type="hidden" name="offset" value="{{$.Offset}}"/>
<input type="hidden" name="edit" value="{{.Sub}}"/>
<button type="submit">Edit</button>
<input type="hidden" name="edit" value="{{.Subject}}"/>
<button type="submit" class="btn-green">Edit</button>
</form>
<form method="POST" action="/manage/apps?offset={{$.Offset}}">
<input type="hidden" name="action" value="secret"/>
<input type="hidden" name="offset" value="{{$.Offset}}"/>
<input type="hidden" name="subject" value="{{.Sub}}"/>
<button type="submit">Reset Secret</button>
<input type="hidden" name="subject" value="{{.Subject}}"/>
<button type="submit" class="btn-red">Reset Secret</button>
</form>
</td>
</tr>
{{end}}
</tbody>
</table>
{{end}}
<h2>Create Client Application</h2>
<form method="POST" action="/manage/apps">
<input type="hidden" name="action" value="create"/>
<input type="hidden" name="offset" value="{{.Offset}}"/>
<div>
<label for="field_name">Name:</label>
<input type="text" name="name" id="field_name" required/>
</div>
<div>
<label for="field_domain">Domain:</label>
<input type="text" name="domain" id="field_domain" required/>
</div>
{{if .IsAdmin}}
<div>
<label for="field_perms">Perms:</label>
<input type="text" name="perms" id="field_perms"/>
</div>
</div>
</td>
</tr>
{{end}}
<div>
<label for="field_public">Public: <input type="checkbox" name="public" id="field_public"/></label>
</div>
{{if .IsAdmin}}
<div>
<label for="field_sso">SSO: <input type="checkbox" name="sso" id="field_sso"/></label>
</div>
{{end}}
<div>
<label for="field_active">Active: <input type="checkbox" name="active" id="field_active" checked/></label>
</div>
<button type="submit">Create</button>
</form>
{{end}}
</tbody>
</table>
</div>
</main>
</body>
</html>

View File

@ -0,0 +1,47 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>{{.ServiceName}}</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<link rel="stylesheet" href="/assets/style.css">
</head>
<body>
{{template "header.go.html" .}}
<main>
<div class="center-box sm:max-w-2xl">
<h1 class="box-title">Edit User</h1>
<form method="POST" action="/manage/users" class="space-y-4 md:space-y-6">
<input type="hidden" name="action" value="create"/>
<input type="hidden" name="offset" value="{{.Offset}}"/>
<input type="hidden" name="subject" value="{{.EditUser.Subject}}"/>
<div>
<label for="field_subject">Subject: {{.EditUser.Subject}}</label>
</div>
<div>
<label for="field_roles">Roles:</label>
<input type="text" name="roles" id="field_roles" value="{{.EditUser.Roles}}" size="100"/>
</div>
<div class="flex flex-row justify-center">
<div class="space-y-4 md:space-y-6">
<div class="flex">
<div class="flex items-center h-5">
<input id="field_active" name="active" type="checkbox" {{if .EditUser.Active}}checked{{end}}/>
<svg class="check" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="4" stroke-linecap="round" stroke-linejoin="round">
<polyline points="20 6 9 17 4 12"></polyline>
</svg>
</div>
<div class="ml-3 text-sm">
<label for="field_active">Enable the user</label>
</div>
</div>
</div>
</div>
<div class="grid grid-cols-2 gap-4">
<button name="edit_action" value="edit" class="btn-green">Save</button>
<button name="edit_action" value="cancel" class="btn-red">Cancel</button>
</div>
</form>
</div>
</main>
</body>
</html>

View File

@ -1,5 +1,5 @@
<!DOCTYPE html>
<html lang="en" class="bg-gray-900">
<html lang="en">
<head>
<title>{{.ServiceName}}</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
@ -7,85 +7,74 @@
</head>
<body>
{{template "header.go.html" .}}
<main>
{{if .Edit}}
<h2>Edit User</h2>
<form method="POST" action="/manage/users">
<input type="hidden" name="action" value="edit"/>
<input type="hidden" name="offset" value="{{.Offset}}"/>
<div>
<label for="field_subject">Subject:</label>
<input type="text" name="subject" id="field_subject" value="{{.Edit.Sub}}" required/>
</div>
<div>
<label for="field_roles">Roles:</label>
<input type="text" name="roles" id="field_roles" value="{{.Edit.Roles}}" size="100"/>
</div>
<div>
<label for="field_active">Active: <input type="checkbox" name="active" id="field_active" checked/></label>
</div>
<button type="submit">Edit</button>
</form>
<form method="GET" action="/manage/users">
<input type="hidden" name="offset" value="{{.Offset}}"/>
<button type="submit">Cancel</button>
</form>
{{else}}
<h2>Manage Users</h2>
{{if eq (len .Users) 0}}
<div>No users found, this is definitely a bug.</div>
{{else}}
<table>
<thead>
<main class="space-y-4 sm:space-y-6">
<h1 class="box-title">Manage Users</h1>
<div class="relative overflow-x-auto shadow-md sm:rounded-lg">
<table class="table-default">
<thead>
<tr>
<th>Subject</th>
<th>Email</th>
<th>Email Verified</th>
<th>Last Updated</th>
<th>Active</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{{if eq (len .Users) 0}}
<tr>
<th>Subject</th>
<th>Email</th>
<th>Email Verified</th>
<th>Roles</th>
<th>Last Updated</th>
<th>Active</th>
<th>Actions</th>
<td colspan="9">No users found, this is definitely a bug.</td>
</tr>
</thead>
<tbody>
{{range .Users}}
<tr>
<td>{{.Sub}}</td>
<th>
{{if $.EmailShow}}
<span>{{.Email}}</span>
{{else}}
<span>{{emailHide .Email}}</span>
{{end}}
</th>
<th>{{.EmailVerified}}</th>
<th>{{.Roles}}</th>
<th>{{.UpdatedAt}}</th>
<td>{{.Active}}</td>
<td>
{{end}}
{{range .Users}}
<tr>
<td>{{.Subject}}</td>
<td>
{{if $.EmailShow}}
<span>{{.Email}}</span>
{{else}}
<span>{{emailHide .Email}}</span>
{{end}}
</td>
<td>{{.EmailVerified}}</td>
<td>{{.UpdatedAt}}</td>
<td>
<label class="flex items-center">
<input type="checkbox" disabled class="focus:outline-none appearance-none relative peer w-6 h-6 border border-gray-300 rounded bg-gray-50 focus:ring focus:ring-3 focus:ring-emerald-300 dark:bg-gray-700 dark:border-gray-600 dark:focus:ring-emerald-600 dark:ring-offset-gray-800 checked:bg-emerald-700" {{if .Active}}checked{{end}}/>
<svg class="absolute w-6 h-6 mt-1 hidden peer-checked:block pointer-events-none text-gray-200" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="4" stroke-linecap="round" stroke-linejoin="round">
<polyline points="20 6 9 17 4 12"></polyline>
</svg>
<span class="hidden">Active</span>
</label>
</td>
<td>
<div class="grid grid-cols-1 gap-4">
<form method="GET" action="/manage/users">
<input type="hidden" name="offset" value="{{$.Offset}}"/>
<input type="hidden" name="edit" value="{{.Sub}}"/>
<button type="submit">Edit</button>
<button type="submit" class="btn-green">Edit</button>
</form>
<form method="POST" action="/reset-password">
<input type="hidden" name="email" value="{{.Email}}"/>
<button type="submit">Send Reset Password Email</button>
<button type="submit" class="btn-red">Send Reset Password Email</button>
</form>
</td>
</tr>
{{end}}
</tbody>
</table>
<form method="GET" action="/manage/users">
<input type="hidden" name="offset" value="{{.Offset}}"/>
{{if not .EmailShow}}
<input type="hidden" name="show-email"/>
{{end}}
<button type="submit">{{if .EmailShow}}Hide Email Addresses{{else}}Show email addresses{{end}}</button>
</form>
</div>
</td>
</tr>
{{end}}
</tbody>
</table>
</div>
<form method="GET" action="/manage/users">
<input type="hidden" name="offset" value="{{.Offset}}"/>
{{if not .EmailShow}}
<input type="hidden" name="show-email"/>
{{end}}
{{end}}
<button type="submit" class="btn-amber">{{if .EmailShow}}Hide Email Addresses{{else}}Show email addresses{{end}}</button>
</form>
</main>
</body>
</html>

View File

@ -1,40 +1,38 @@
<!DOCTYPE html>
<html lang="en" class="bg-gray-900">
<html lang="en">
<head>
<title>{{.ServiceName}}</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<link rel="stylesheet" href="/assets/style.css">
</head>
<body class="min-h-screen">
<body>
{{template "header.go.html" .}}
<main class="flex flex-col items-center mx-auto">
<div class="block rounded-lg shadow bg-gray-800 border border-gray-700 m-8 sm:max-w-md w-full">
<div class="p-6 sm:p-8 space-y-4">
<h1 class="text-xl font-bold leading-tight tracking-tight text-gray-900 md:text-2xl dark:text-white text-center">{{.AppName}}</h1>
<h2 class="text-l font-bold leading-tight tracking-tight text-gray-900 md:text-xl dark:text-white text-center">Would like access to your 1f349 account:</h2>
<h3 class="text-l leading-tight tracking-tight text-gray-900 md:text-xl dark:text-white text-center">Logged in as: <span class="font-bold">{{.Auth.UserInfo.name}}</span></h3>
<div>
<ul class="space-y-1 text-gray-500 list-disc list-inside dark:text-gray-400">
{{range .WantsList}}
<li>{{.}}</li>
{{end}}
</ul>
</div>
<form method="POST" action="/login" class="space-y-4 md:space-y-6">
<input type="hidden" name="response_type" value="{{.ResponseType}}"/>
<input type="hidden" name="response_mode" value="{{.ResponseMode}}">
<input type="hidden" name="client_id" value="{{.ClientID}}"/>
<input type="hidden" name="redirect_uri" value="{{.RedirectUri}}"/>
<input type="hidden" name="state" value="{{.State}}"/>
<input type="hidden" name="scope" value="{{.Scope}}"/>
<input type="hidden" name="nonce" value="{{.Nonce}}"/>
<div class="grid grid-cols-2 gap-4">
<button name="oauth_action" value="authorize" class="w-full text-white bg-emerald-600 hover:bg-emerald-700 focus:ring-4 focus:outline-none focus:ring-emerald-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center dark:bg-emerald-600 dark:hover:bg-emerald-700 dark:focus:ring-emerald-800">Authorize</button>
<button name="oauth_action" value="cancel" class="w-full text-white bg-rose-600 hover:bg-rose-700 focus:ring-4 focus:outline-none focus:ring-rose-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center dark:bg-rose-600 dark:hover:bg-rose-700 dark:focus:ring-rose-800">Cancel</button>
</div>
</form>
<div>Authorizing this action will redirect you to <a href="" class="font-bold">{{.AppDomain}}</a> with access to the permissions requested above.</div>
<main>
<div class="center-box sm:max-w-md">
<h1 class="box-title">{{.AppName}}</h1>
<h2 class="text-l font-bold leading-tight tracking-tight text-gray-900 md:text-xl dark:text-white text-center">Would like access to your 1f349 account:</h2>
<h3 class="text-l leading-tight tracking-tight text-gray-900 md:text-xl dark:text-white text-center">Logged in as: <span class="font-bold">{{.Auth.UserInfo.name}}</span></h3>
<div>
<ul class="space-y-1 text-gray-800 list-disc list-inside dark:text-gray-400">
{{range .WantsList}}
<li>{{.}}</li>
{{end}}
</ul>
</div>
<form method="POST" action="/login" class="space-y-4 md:space-y-6">
<input type="hidden" name="response_type" value="{{.ResponseType}}"/>
<input type="hidden" name="response_mode" value="{{.ResponseMode}}">
<input type="hidden" name="client_id" value="{{.ClientID}}"/>
<input type="hidden" name="redirect_uri" value="{{.RedirectUri}}"/>
<input type="hidden" name="state" value="{{.State}}"/>
<input type="hidden" name="scope" value="{{.Scope}}"/>
<input type="hidden" name="nonce" value="{{.Nonce}}"/>
<div class="grid grid-cols-2 gap-4">
<button type="submit" name="oauth_action" value="authorize" class="btn-green">Authorize</button>
<button type="submit" name="oauth_action" value="cancel" class="btn-red">Cancel</button>
</div>
</form>
<div>Authorizing this action will redirect you to <a href="" class="font-bold">{{.AppDomain}}</a> with access to the permissions requested above.</div>
</div>
</main>
</body>

View File

@ -84,7 +84,7 @@ func main() {
go UpdateOnChange(w.Event)
go func() {
err := w.Start(5 * time.Second)
err := w.Start(time.Second)
Logger.Warn("Watcher stopped", "err", err)
}()
@ -202,11 +202,11 @@ func UpdateTemplate(p string) {
cmd := exec.Command("tailwindcss", args...)
cmd.Dir = p
tailwindOutput, err := cmd.CombinedOutput()
Logger.Debug(string(tailwindOutput))
if err != nil {
Logger.Warn("Failed to run tailwind", "err", err)
return
}
Logger.Debug(string(tailwindOutput))
// make new template
fs, err := template.New("theme-template-root").Funcs(DefaultFuncMap).ParseFS(os.DirFS(p), "*.go.html")