Skip to content

Commit

Permalink
Reimplement passkey settings with htmx instead of solid
Browse files Browse the repository at this point in the history
  • Loading branch information
foodelevator committed Aug 6, 2024
1 parent 46ac0b4 commit 8ac7a88
Show file tree
Hide file tree
Showing 16 changed files with 436 additions and 200 deletions.
5 changes: 4 additions & 1 deletion cmd/dev/dev.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,10 @@ func main() {
ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt)
defer cancel()

for _, cmd := range [][]string{{"pnpm", "build", "--watch", "--no-watch.clearScreen"}, {"pnpm", "tailwind", "--watch"}} {
for _, cmd := range [][]string{
{"pnpm", "build", "--watch", "--no-watch.clearScreen"},
{"pnpm", "tailwind", "--watch"},
} {
go run(ctx, cmd)
}
watcher, err := fsnotify.NewWatcher()
Expand Down
8 changes: 4 additions & 4 deletions cmd/web/web.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,17 @@ func main() {
panic(err)
}

ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
serviceCreationContext, cancel := context.WithTimeout(context.Background(), time.Minute)
user := must(user.NewService(db))
passkey := must(passkey.NewService(db))
oidcrp := must(oidcrp.NewService(ctx))
legacyapi := must(legacyapi.NewService(ctx, db))
oidcrp := must(oidcrp.NewService(serviceCreationContext))
legacyapi := must(legacyapi.NewService(serviceCreationContext, db))
dev := must(dev.NewService(db))
oidcprovider := must(oidcprovider.NewService(db))
admin := must(admin.NewService(db))
cancel()

user.Assign(dev)
user.Assign(dev, passkey)
passkey.Assign(user)
oidcrp.Assign(user)
legacyapi.Assign(user)
Expand Down
156 changes: 0 additions & 156 deletions islands/passkeySettings.island.tsx

This file was deleted.

80 changes: 80 additions & 0 deletions pkg/templates/layout.templ
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ templ Page() {
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>Logout</title>
<link rel="stylesheet" href="/dist/style.css"/>
<script src="https://unpkg.com/[email protected]" integrity="sha384-QWGpdj554B4ETpJJC9z+ZHJcA/i59TyjxEPXiiUgN2WmTyV5OEZWCD6gQhgkdpB/" crossorigin="anonymous"></script>
@base64Helpers()
</head>
<body class="bg-gray-900 text-neutral-100">
{ children... }
Expand All @@ -24,3 +26,81 @@ templ Modal() {
</div>
}
}

templ base64Helpers() {
<script>
/**
* @param {string} data
* @returns Uint8Array
*/
let decodebase64url = (data) =>
Uint8Array.from(window.atob(data.replace(/-/g, "+").replace(/_/g, "/")), v => v.charCodeAt(0));
/**
* @param {Uint8Array} data
* @returns string
*/
let encodebase64url = (data) =>
base64ArrayBuffer(data).replace(/\+/g, "-").replace(/\//g, "_");

// Taken from https://gist.github.com/jonleighton/958841 and slightly modified.
/*
MIT LICENSE
Copyright 2011 Jon Leighton
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

/**
* @param {ArrayBuffer} arrayBuffer
*/
function base64ArrayBuffer(arrayBuffer) {
let base64 = "";
let encodings = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

let bytes = new Uint8Array(arrayBuffer);
let byteLength = bytes.byteLength;
let byteRemainder = byteLength % 3;
let mainLength = byteLength - byteRemainder;

// Main loop deals with bytes in chunks of 3
for (let i = 0; i < mainLength; i = i + 3) {
// Combine the three bytes into a single integer
let chunk = (bytes[i] << 16) | (bytes[i + 1] << 8) | bytes[i + 2];

// Use bitmasks to extract 6-bit segments from the triplet
let a = (chunk & 16515072) >> 18; // 16515072 = (2^6 - 1) << 18
let b = (chunk & 258048) >> 12; // 258048 = (2^6 - 1) << 12
let c = (chunk & 4032) >> 6; // 4032 = (2^6 - 1) << 6
let d = chunk & 63; // 63 = 2^6 - 1

// Convert the raw binary segments to the appropriate ASCII encoding
base64 += encodings[a] + encodings[b] + encodings[c] + encodings[d];
}

// Deal with the remaining bytes and padding
if (byteRemainder == 1) {
let chunk = bytes[mainLength];

let a = (chunk & 252) >> 2; // 252 = (2^6 - 1) << 2

// Set the 4 least significant bits to zero
let b = (chunk & 3) << 4; // 3 = 2^2 - 1

base64 += encodings[a] + encodings[b] + '==';
} else if (byteRemainder == 2) {
let chunk = (bytes[mainLength] << 8) | bytes[mainLength + 1];

let a = (chunk & 64512) >> 10; // 64512 = (2^6 - 1) << 10
let b = (chunk & 1008) >> 4; // 1008 = (2^6 - 1) << 4

// Set the 2 least significant bits to zero
let c = (chunk & 15) << 2; // 15 = 2^4 - 1

base64 += encodings[a] + encodings[b] + encodings[c] + '=';
}

return base64;
}
</script>
}
36 changes: 35 additions & 1 deletion pkg/templates/layout_templ.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion services/admin/admin.templ
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,5 @@ templ page() {
{ children... }
</main>
</div>
<script src="https://unpkg.com/[email protected]" integrity="sha384-QWGpdj554B4ETpJJC9z+ZHJcA/i59TyjxEPXiiUgN2WmTyV5OEZWCD6gQhgkdpB/" crossorigin="anonymous"></script>
}
}
2 changes: 1 addition & 1 deletion services/admin/admin_templ.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions services/passkey/export/passkey.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
package export

import (
"context"

"github.com/a-h/templ"
user "github.com/datasektionen/logout/services/user/export"
"github.com/go-webauthn/webauthn/webauthn"
"github.com/google/uuid"
)

type Service interface {
PasskeySettings(ctx context.Context, kthid string) (func() templ.Component, error)
}

type Passkey struct {
ID uuid.UUID `json:"id"`
Name string `json:"name"`
Expand Down
Loading

0 comments on commit 8ac7a88

Please sign in to comment.