summaryrefslogtreecommitdiff
path: root/templates/login.tpl
diff options
context:
space:
mode:
Diffstat (limited to 'templates/login.tpl')
-rw-r--r--templates/login.tpl137
1 files changed, 137 insertions, 0 deletions
diff --git a/templates/login.tpl b/templates/login.tpl
new file mode 100644
index 0000000..0323409
--- /dev/null
+++ b/templates/login.tpl
@@ -0,0 +1,137 @@
1<!doctype html>
2<html lang="en">
3 <head>
4 <meta charset="utf-8" />
5 <meta name="viewport" content="width=device-width, initial-scale=1">
6 <meta name="render-time" content="{{ .RenderTime }}">
7 {{ if .Context.HasKey "title" }}<title>{{ .Context.Get "title" }}</title>{{ else }}<title>SSH Proxy</title>{{ end }}
8
9 <script type="text/javascript">
10 /*
11 * Base64URL-ArrayBuffer
12 * https://github.com/herrjemand/Base64URL-ArrayBuffer
13 *
14 * Copyright (c) 2017 Yuriy Ackermann <ackermann.yuriy@gmail.com>
15 * Copyright (c) 2012 Niklas von Hertzen
16 * Licensed under the MIT license.
17 *
18 */
19 (function(){
20 'use strict';
21
22 let chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_';
23
24 // Use a lookup table to find the index.
25 let lookup = new Uint8Array(256);
26 for (let i = 0; i < chars.length; i++) {
27 lookup[chars.charCodeAt(i)] = i;
28 }
29
30 let encode = function(arraybuffer) {
31 let bytes = new Uint8Array(arraybuffer),
32 i, len = bytes.length, base64url = '';
33
34 for (i = 0; i < len; i+=3) {
35 base64url += chars[bytes[i] >> 2];
36 base64url += chars[((bytes[i] & 3) << 4) | (bytes[i + 1] >> 4)];
37 base64url += chars[((bytes[i + 1] & 15) << 2) | (bytes[i + 2] >> 6)];
38 base64url += chars[bytes[i + 2] & 63];
39 }
40
41 if ((len % 3) === 2) {
42 base64url = base64url.substring(0, base64url.length - 1);
43 } else if (len % 3 === 1) {
44 base64url = base64url.substring(0, base64url.length - 2);
45 }
46
47 return base64url;
48 };
49
50 let decode = function(base64string) {
51 let bufferLength = base64string.length * 0.75,
52 len = base64string.length, i, p = 0,
53 encoded1, encoded2, encoded3, encoded4;
54
55 let bytes = new Uint8Array(bufferLength);
56
57 for (i = 0; i < len; i+=4) {
58 encoded1 = lookup[base64string.charCodeAt(i)];
59 encoded2 = lookup[base64string.charCodeAt(i+1)];
60 encoded3 = lookup[base64string.charCodeAt(i+2)];
61 encoded4 = lookup[base64string.charCodeAt(i+3)];
62
63 bytes[p++] = (encoded1 << 2) | (encoded2 >> 4);
64 bytes[p++] = ((encoded2 & 15) << 4) | (encoded3 >> 2);
65 bytes[p++] = ((encoded3 & 3) << 6) | (encoded4 & 63);
66 }
67
68 return bytes.buffer
69 };
70
71 window.base64url = {
72 'decode': decode,
73 'encode': encode
74 };
75 })();
76 </script>
77
78 <script type="text/javascript">
79 window.addEventListener("load", _ => {
80 const urlParams = new URLSearchParams(window.location.search);
81 const code = urlParams.get("code");
82 if (code !== "") {
83 document.getElementById("code").value = code;
84 }
85
86 document.getElementById("login").addEventListener("click", evt => {
87 evt.preventDefault();
88
89 var username = document.getElementById("username");
90 fetch("/auth/login/" + username.value)
91 .then((result) => result.json())
92 .then((data) => {
93 data.publicKey.challenge = base64url.decode(data.publicKey.challenge);
94 data.publicKey.allowCredentials.forEach(e => e.id = base64url.decode(e.id));
95
96 navigator.credentials.get(data)
97 .then((credential) => {
98 fetch("/auth/login/" + username.value, {
99 method: "POST",
100 mode: "same-origin",
101 headers: {
102 "Content-Type": "application/json",
103 "X-CSRF-Token": "{{ .CSRFToken }}"
104 },
105 body: JSON.stringify({
106 code: document.getElementById("code").value,
107 type: credential.type,
108 id: credential.id,
109 rawId: base64url.encode(credential.rawId),
110 response: {
111 authenticatorData: base64url.encode(credential.response.authenticatorData),
112 clientDataJSON: base64url.encode(credential.response.clientDataJSON),
113 signature: base64url.encode(credential.response.signature),
114 userHandle: base64url.encode(credential.response.userHandle)
115 }
116 })
117 })
118 .then((response) => {
119 if (response.ok) { document.body.innerHTML = "<h1>Success</h1>"; }
120 else { document.body.innerHTML = "<h1>Failure</h1>"; }
121 });
122 });
123 });
124 });
125 });
126 </script>
127 </head>
128
129 <body>
130 <form>
131 <label for="code">Code: <input type="text" name="code" id="code" /></label><br/>
132 <label for="username">Username: <input type="text" name="username" id="username" autocorrect="off" autocapitalize="none" autocomplete="username" /></label><br/>
133 <input type="hidden" value="{{ .CSRFToken }}" name="csrf-token" />
134 <input type="submit" id="login" value="Login" />
135 </form>
136 </body>
137</html>