style all the sign-in pages
This commit is contained in:
parent
1170275816
commit
09fcd573b4
|
@ -1,24 +1,30 @@
|
|||
// get the challenge from out of the HTML
|
||||
const sc = document.querySelector("#challenge").dataset.sc
|
||||
const ssbUriLink = document.querySelector('#start-auth-uri');
|
||||
const waitingElem = document.querySelector('#waiting');
|
||||
const errorElem = document.querySelector('#failed');
|
||||
const challengeElem = document.querySelector('#challenge');
|
||||
|
||||
const sc = challengeElem.dataset.sc;
|
||||
const evtSource = new EventSource(`/withssb/events?sc=${sc}`);
|
||||
|
||||
const ping = document.querySelector('#ping');
|
||||
const failed = document.querySelector('#failed');
|
||||
ssbUriLink.addEventListener('click', (e) => {
|
||||
errorElem.classList.add('hidden');
|
||||
waitingElem.classList.remove('hidden');
|
||||
});
|
||||
|
||||
evtSource.onerror = (e) => {
|
||||
failed.textContent = "Warning: The connection to the server was interupted."
|
||||
}
|
||||
waitingElem.classList.add('hidden');
|
||||
errorElem.classList.remove('hidden');
|
||||
console.error(e.data);
|
||||
};
|
||||
|
||||
// TODO: change to some css-style progress indicator
|
||||
evtSource.addEventListener("ping", (e) => {
|
||||
ping.textContent = e.data;
|
||||
})
|
||||
evtSource.addEventListener('failed', (e) => {
|
||||
waitingElem.classList.add('hidden');
|
||||
errorElem.classList.remove('hidden');
|
||||
console.error(e.data);
|
||||
});
|
||||
|
||||
evtSource.addEventListener("failed", (e) => {
|
||||
failed.textContent = e.data;
|
||||
})
|
||||
|
||||
evtSource.addEventListener("success", (e) => {
|
||||
evtSource.close()
|
||||
window.location = `/withssb/finalize?token=${e.data}`
|
||||
})
|
||||
evtSource.addEventListener('success', (e) => {
|
||||
waitingElem.classList.add('hidden');
|
||||
evtSource.close();
|
||||
window.location = `/withssb/finalize?token=${e.data}`;
|
||||
});
|
||||
|
|
|
@ -17,7 +17,6 @@ import (
|
|||
|
||||
kitlog "github.com/go-kit/kit/log"
|
||||
"github.com/go-kit/kit/log/level"
|
||||
"github.com/gorilla/csrf"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/gorilla/sessions"
|
||||
"github.com/skip2/go-qrcode"
|
||||
|
@ -34,7 +33,7 @@ import (
|
|||
)
|
||||
|
||||
var HTMLTemplates = []string{
|
||||
"auth/start_login_form.tmpl",
|
||||
"auth/decide_method.tmpl",
|
||||
"auth/withssb_server_start.tmpl",
|
||||
}
|
||||
|
||||
|
@ -96,7 +95,7 @@ func NewWithSSBHandler(
|
|||
ssb.cookieStore = cookies
|
||||
ssb.bridge = bridge
|
||||
|
||||
m.Get(router.AuthLogin).HandlerFunc(ssb.decideMethod)
|
||||
m.Get(router.AuthWithSSBLogin).HandlerFunc(ssb.decideMethod)
|
||||
m.Get(router.AuthWithSSBServerEvents).HandlerFunc(ssb.eventSource)
|
||||
m.Get(router.AuthWithSSBFinalize).HandlerFunc(ssb.finalizeCookie)
|
||||
|
||||
|
@ -265,15 +264,6 @@ func (h WithSSBHandler) decideMethod(w http.ResponseWriter, req *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
// without any query params: shows a form field so you can input alias or SSB ID
|
||||
if alias == "" && cid == nil {
|
||||
data := map[string]interface{}{
|
||||
csrf.TemplateTag: csrf.TemplateField(req),
|
||||
}
|
||||
h.render.Render(w, req, "auth/start_login_form.tmpl", http.StatusOK, data)
|
||||
return
|
||||
}
|
||||
|
||||
// assume server-init sse dance
|
||||
data, err := h.serverInitiated()
|
||||
if err != nil {
|
||||
|
|
|
@ -108,7 +108,7 @@ func TestFallbackAuth(t *testing.T) {
|
|||
}
|
||||
ts.AuthFallbackDB.CheckReturns(int64(23), nil)
|
||||
|
||||
signInURL, err := ts.Router.Get(router.AuthFallbackSignIn).URL()
|
||||
signInURL, err := ts.Router.Get(router.AuthFallbackLogin).URL()
|
||||
r.Nil(err)
|
||||
|
||||
signInURL.Host = "localhost"
|
||||
|
|
|
@ -39,6 +39,7 @@ var HTMLTemplates = []string{
|
|||
"aliases-resolved.html",
|
||||
"invite/accept.tmpl",
|
||||
"invite/consumed.tmpl",
|
||||
"auth/fallback_sign_in.tmpl",
|
||||
"notice/list.tmpl",
|
||||
"notice/show.tmpl",
|
||||
"error.tmpl",
|
||||
|
@ -243,7 +244,15 @@ func New(
|
|||
bridge,
|
||||
)
|
||||
|
||||
m.Get(router.AuthFallbackSignIn).HandlerFunc(authWithPassword.Authorize)
|
||||
m.Get(router.AuthLogin).Handler(r.StaticHTML("auth/decide_method.tmpl"))
|
||||
|
||||
m.Get(router.AuthFallbackFinalize).HandlerFunc(authWithPassword.Authorize)
|
||||
|
||||
m.Get(router.AuthFallbackLogin).Handler(r.HTML("auth/fallback_sign_in.tmpl", func(w http.ResponseWriter, req *http.Request) (interface{}, error) {
|
||||
return map[string]interface{}{
|
||||
csrf.TemplateTag: csrf.TemplateField(req),
|
||||
}, nil
|
||||
}))
|
||||
|
||||
m.Get(router.AuthLogout).HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
||||
err = authWithSSB.Logout(w, req)
|
||||
|
|
|
@ -128,7 +128,7 @@ func TestNoticesEditButtonVisible(t *testing.T) {
|
|||
ts.AuthFallbackDB.CheckReturns(testUser.ID, nil)
|
||||
ts.MembersDB.GetByIDReturns(testUser, nil)
|
||||
|
||||
postEndpoint, err := ts.Router.Get(router.AuthFallbackSignIn).URL()
|
||||
postEndpoint, err := ts.Router.Get(router.AuthFallbackLogin).URL()
|
||||
r.Nil(err)
|
||||
postEndpoint.Host = "localhost"
|
||||
postEndpoint.Scheme = "https"
|
||||
|
|
|
@ -19,17 +19,17 @@ AuthSignIn = "Sign in"
|
|||
AuthSignOut = "Sign out"
|
||||
|
||||
AuthTitle = "Member Authentication"
|
||||
AuthWelcome = "TODO: Some text about the different login methods"
|
||||
|
||||
AuthWithSSBTitle = "Sign-in with SSB"
|
||||
AuthWithSSBStart = "To begin, enter your alias on this room or your public key"
|
||||
AuthWithSSBServerStart = "If you have a compatible device/application, you can sign-in here without a password. Open the QR-Code on your mobile device to complete the process or click the link below."
|
||||
|
||||
AuthFallbackWelcome = "Here you can log in with username and password."
|
||||
AuthFallbackTitle = "Password Login"
|
||||
AuthWelcome = "If you are a member of this room, you can access the internal dashboard. Click on your preferred sign-in method below:"
|
||||
|
||||
AuthWithSSBTitle = "Sign in with SSB"
|
||||
AuthWithSSBInstruct = "Easy and secure method, if your SSB app supports it."
|
||||
AuthWithSSBWelcome = "To sign-in with your SSB identity stored on this device, press the button below which will open a compatible SSB app, if it's installed."
|
||||
AuthWithSSBInstructQR = "If your SSB app is on another device, you can scan the following QR code to sign-in with that device's SSB identity."
|
||||
AuthWithSSBError = "Sign-in failed. Please make sure you use an SSB app that supports this method of login, and click the button above within a minute after this page was opened."
|
||||
|
||||
AuthFallbackTitle = "Password sign-in"
|
||||
AuthFallbackWelcome = "Signing in with username and password is only possible if the administrator has given you one, because we do not support user registration."
|
||||
AuthFallbackInstruct = "This method is an acceptable fallback, if you have a username and password."
|
||||
|
||||
AdminDashboardWelcome = "Welcome to your dashboard"
|
||||
AdminDashboardTitle = "Room Admin Dashboard"
|
||||
|
|
|
@ -6,11 +6,13 @@ import "github.com/gorilla/mux"
|
|||
|
||||
// constant names for the named routes
|
||||
const (
|
||||
AuthFallbackSignIn = "auth:fallback:signin"
|
||||
|
||||
AuthLogin = "auth:login"
|
||||
AuthLogout = "auth:logout"
|
||||
|
||||
AuthFallbackLogin = "auth:fallback:login"
|
||||
AuthFallbackFinalize = "auth:fallback:finalize"
|
||||
|
||||
AuthWithSSBLogin = "auth:withssb:login"
|
||||
AuthWithSSBServerEvents = "auth:withssb:sse"
|
||||
AuthWithSSBFinalize = "auth:withssb:finalize"
|
||||
)
|
||||
|
@ -24,9 +26,10 @@ func Auth(m *mux.Router) *mux.Router {
|
|||
m.Path("/login").Methods("GET").Name(AuthLogin)
|
||||
m.Path("/logout").Methods("GET").Name(AuthLogout)
|
||||
|
||||
// register password fallback
|
||||
m.Path("/password/signin").Methods("POST").Name(AuthFallbackSignIn)
|
||||
m.Path("/fallback/login").Methods("GET").Name(AuthFallbackLogin)
|
||||
m.Path("/fallback/finalize").Methods("POST").Name(AuthFallbackFinalize)
|
||||
|
||||
m.Path("/withssb/login").Methods("GET").Name(AuthWithSSBLogin)
|
||||
m.Path("/withssb/events").Methods("GET").Name(AuthWithSSBServerEvents)
|
||||
m.Path("/withssb/finalize").Methods("GET").Name(AuthWithSSBFinalize)
|
||||
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
{{ define "title" }}{{i18n "AuthTitle"}}{{ end }}
|
||||
{{ define "content" }}
|
||||
<div class="flex flex-col justify-center items-center self-center max-w-lg">
|
||||
<span class="text-center mt-8">{{i18n "AuthWelcome"}}</span>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col sm:flex-row justify-center items-center sm:items-stretch">
|
||||
<a
|
||||
href="{{urlTo "auth:withssb:login"}}"
|
||||
class="w-64 sm:mr-4 my-6 py-10 border-green-200 border-2 rounded-3xl flex flex-col justify-start items-center hover:border-green-400 hover:shadow-xl transition"
|
||||
>
|
||||
<svg class="w-12 h-12 text-green-500 mb-4" viewBox="0 0 24 24">
|
||||
<path fill="currentColor" d="M12.66 13.67C12.32 14 11.93 14.29 11.5 14.5V21L9.5 23L7.5 21L9.5 19.29L8 18L9.5 16.71L7.5 15V14.5C6 13.77 5 12.26 5 10.5C5 8 7 6 9.5 6C9.54 6 9.58 6 9.61 6C9.59 6.07 9.54 6.12 9.5 6.18C9.23 6.79 9.08 7.43 9.03 8.08C8.43 8.28 8 8.84 8 9.5C8 10.33 8.67 11 9.5 11C9.53 11 9.57 11 9.6 11C10.24 12.25 11.34 13.2 12.66 13.67M16 6C16 5.37 15.9 4.75 15.72 4.18C17.06 4.56 18.21 5.55 18.73 6.96C19.33 8.62 18.89 10.39 17.75 11.59L20 17.68L18.78 20.25L16.22 19.05L17.5 16.76L15.66 16.06L16.63 14.34L14.16 13.41L14 12.95C12.36 12.77 10.88 11.7 10.27 10.04C9.42 7.71 10.63 5.12 12.96 4.27C13.14 4.21 13.33 4.17 13.5 4.13C12.84 2.87 11.53 2 10 2C7.79 2 6 3.79 6 6C6 6.09 6 6.17 6.03 6.26C5.7 6.53 5.4 6.82 5.15 7.15C5.06 6.78 5 6.4 5 6C5 3.24 7.24 1 10 1S15 3.24 15 6C15 7.16 14.6 8.21 13.94 9.06C16.08 8.88 16 6 16 6M12.81 8.1C12.87 8.27 12.96 8.41 13.06 8.54C13.62 7.88 13.97 7.04 14 6.11C13.89 6.13 13.8 6.15 13.7 6.18C12.92 6.47 12.5 7.33 12.81 8.1Z" />
|
||||
</svg>
|
||||
<h1 class="text-xl font-bold text-green-500">{{i18n "AuthWithSSBTitle"}}</h1>
|
||||
<span class="mx-3 mt-2 text-center text-sm">{{i18n "AuthWithSSBInstruct"}}</span>
|
||||
</a>
|
||||
|
||||
<a
|
||||
href="{{urlTo "auth:fallback:login"}}"
|
||||
class="w-64 sm:ml-4 my-6 py-10 border-gray-200 border-2 rounded-3xl flex flex-col justify-start items-center hover:border-gray-400 hover:shadow-xl transition"
|
||||
>
|
||||
<svg class="w-12 h-12 text-gray-500 mb-4" viewBox="0 0 24 24">
|
||||
<path fill="currentColor" d="M17,7H22V17H17V19A1,1 0 0,0 18,20H20V22H17.5C16.95,22 16,21.55 16,21C16,21.55 15.05,22 14.5,22H12V20H14A1,1 0 0,0 15,19V5A1,1 0 0,0 14,4H12V2H14.5C15.05,2 16,2.45 16,3C16,2.45 16.95,2 17.5,2H20V4H18A1,1 0 0,0 17,5V7M2,7H13V9H4V15H13V17H2V7M20,15V9H17V15H20M8.5,12A1.5,1.5 0 0,0 7,10.5A1.5,1.5 0 0,0 5.5,12A1.5,1.5 0 0,0 7,13.5A1.5,1.5 0 0,0 8.5,12M13,10.89C12.39,10.33 11.44,10.38 10.88,11C10.32,11.6 10.37,12.55 11,13.11C11.55,13.63 12.43,13.63 13,13.11V10.89Z" />
|
||||
</svg>
|
||||
<h1 class="text-xl font-bold text-gray-500">{{i18n "AuthFallbackTitle"}}</h1>
|
||||
<span class="mx-3 mt-2 text-center text-sm">{{i18n "AuthFallbackInstruct"}}</span>
|
||||
</a>
|
||||
</div>
|
||||
{{end}}
|
|
@ -0,0 +1,25 @@
|
|||
{{ define "title" }}{{i18n "AuthTitle"}}{{ end }}
|
||||
{{ define "content" }}
|
||||
<div class="flex flex-col justify-center items-center self-center max-w-lg">
|
||||
<span class="text-center mt-8">{{i18n "AuthFallbackWelcome"}}</span>
|
||||
|
||||
<form
|
||||
id="password-fallback"
|
||||
method="POST"
|
||||
action="{{urlTo "auth:fallback:finalize"}}"
|
||||
class="flex flex-row items-end"
|
||||
>
|
||||
{{ .csrfField }}
|
||||
<div class="flex flex-col w-48">
|
||||
<label class="mt-8 text-sm text-gray-600">Username</label>
|
||||
<input type="text" name="user"
|
||||
class="shadow rounded border border-transparent h-8 p-1 focus:outline-none focus:ring-2 focus:ring-green-400 focus:border-transparent">
|
||||
<label class="mt-8 text-sm text-gray-600">Password</label>
|
||||
<input type="password" name="pass"
|
||||
class="shadow rounded border border-transparent h-8 p-1 focus:outline-none focus:ring-2 focus:ring-green-400 focus:border-transparent">
|
||||
<button type="submit"
|
||||
class="my-8 shadow rounded px-4 h-8 text-gray-100 bg-green-500 hover:bg-green-600 focus:outline-none focus:ring-2 focus:ring-green-600 focus:ring-opacity-50">Enter</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
{{end}}
|
|
@ -1,71 +0,0 @@
|
|||
{{ define "title" }}{{i18n "AuthTitle"}}{{ end }}
|
||||
{{ define "content" }}
|
||||
<div id="page-header">
|
||||
<h1 class="text-lg">{{i18n "AuthTitle"}}</h1>
|
||||
<p id="welcome">{{i18n "AuthWelcome"}}</p>
|
||||
</div>
|
||||
<hr class="mt-5 pt-5">
|
||||
|
||||
<div>
|
||||
<div id="page-header">
|
||||
<h1 class="text-lg">{{i18n "AuthWithSSBTitle"}}</h1>
|
||||
<p id="describe-withssb">{{i18n "AuthWithSSBStart"}}</p>
|
||||
</div>
|
||||
<div>
|
||||
<form
|
||||
id="start-siwssb"
|
||||
method="GET"
|
||||
action="{{urlTo "auth:login:check" }}"
|
||||
class="flex flex-row items-end"
|
||||
>
|
||||
<label>Alias or SSB ID</label>
|
||||
<input
|
||||
type="text"
|
||||
name="input"
|
||||
class="shadow rounded border border-transparent h-8 p-1 focus:outline-none focus:ring-2 focus:ring-pink-400 focus:border-transparent"
|
||||
>
|
||||
<button
|
||||
type="submit"
|
||||
class="shadow rounded px-4 h-8 text-gray-100 bg-pink-600 hover:bg-pink-700 focus:outline-none focus:ring-2 focus:ring-pink-600 focus:ring-opacity-50"
|
||||
>Enter</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr class="mt-5 pt-5">
|
||||
|
||||
<div>
|
||||
<div id="page-header">
|
||||
<h1 class="text-lg">{{i18n "AuthFallbackTitle"}}</h1>
|
||||
<p id="describe-password">{{i18n "AuthFallbackWelcome"}}</p>
|
||||
</div>
|
||||
<div>
|
||||
<form
|
||||
id="password-fallback"
|
||||
method="POST"
|
||||
action={{urlTo "auth:fallback:signin" }}
|
||||
class="flex flex-row items-end"
|
||||
>
|
||||
{{ .csrfField }}
|
||||
<div class="w-96 grid grid-cols-2 gap-x-4 gap-y-1 mr-4">
|
||||
<label>Username</label>
|
||||
<label>Password</label>
|
||||
<input
|
||||
type="text"
|
||||
name="user"
|
||||
class="shadow rounded border border-transparent h-8 p-1 focus:outline-none focus:ring-2 focus:ring-pink-400 focus:border-transparent"
|
||||
>
|
||||
<input
|
||||
type="password"
|
||||
name="pass"
|
||||
class="shadow rounded border border-transparent h-8 p-1 focus:outline-none focus:ring-2 focus:ring-pink-400 focus:border-transparent"
|
||||
>
|
||||
</div>
|
||||
<button
|
||||
type="submit"
|
||||
class="shadow rounded px-4 h-8 text-gray-100 bg-pink-600 hover:bg-pink-700 focus:outline-none focus:ring-2 focus:ring-pink-600 focus:ring-opacity-50"
|
||||
>Enter</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
|
@ -1,9 +1,5 @@
|
|||
{{ define "title" }}{{i18n "AuthWithSSBTitle"}}{{ end }}
|
||||
{{ define "content" }}
|
||||
<div id="page-header">
|
||||
<h1 id="welcome" class="text-lg">{{i18n "AuthWithSSBServerStart"}}</h1>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col justify-center items-center self-center max-w-lg">
|
||||
<span class="text-center mt-8">{{i18n "AuthWithSSBWelcome"}}</span>
|
||||
|
||||
|
@ -11,10 +7,14 @@
|
|||
id="start-auth-uri"
|
||||
href="{{.SSBURI}}"
|
||||
target="_blank"
|
||||
class="shadow rounded flex flex-row justify-center items-center mt-8 px-4 h-8 text-gray-100 bg-pink-600 hover:bg-pink-700 focus:outline-none focus:ring-2 focus:ring-pink-600 focus:ring-opacity-50"
|
||||
class="shadow rounded flex flex-row justify-center items-center mt-8 px-4 h-8 text-gray-100 bg-green-500 hover:bg-green-600 focus:outline-none focus:ring-2 focus:ring-green-600 focus:ring-opacity-50"
|
||||
>{{i18n "AuthWithSSBTitle"}}</a>
|
||||
|
||||
<div class="mt-8 w-64 h-px bg-gray-200"></div>
|
||||
<p id="waiting" class="hidden mt-8 animate-pulse text-green-500">Waiting for confirmation</p>
|
||||
|
||||
<p id="failed" class="hidden mt-8 text-red-700 text-center">{{i18n "AuthWithSSBError"}}</p>
|
||||
|
||||
<hr class="mt-8 w-64 h-px bg-gray-200"></hr>
|
||||
|
||||
<span class="text-center mt-8">{{i18n "AuthWithSSBInstructQR"}}</span>
|
||||
|
||||
|
@ -28,11 +28,6 @@
|
|||
/>
|
||||
</div>
|
||||
|
||||
<div class="text-xs">
|
||||
<h3>Server events</h3>
|
||||
<p id="ping"></p>
|
||||
<p id="failed" class="text-red-500"></p>
|
||||
</div>
|
||||
<div id="challenge" class="hidden" data-sc="{{.ServerChallenge}}"></div>
|
||||
<script src="/assets/login-events.js"></script>
|
||||
{{end}}
|
|
@ -41,7 +41,7 @@
|
|||
{{else}}
|
||||
<a
|
||||
href="{{urlTo "auth:login"}}"
|
||||
class="pl-3 pr-4 py-2 sm:py-1 font-semibold text-sm text-gray-500 hover:text-green-600"
|
||||
class="pl-3 pr-4 py-2 sm:py-1 font-semibold text-sm text-gray-500 hover:text-green-500"
|
||||
>{{i18n "AuthSignIn"}}</a>
|
||||
{{end}}
|
||||
</div>
|
||||
|
|
Loading…
Reference in New Issue