Add members/invitations and code-based gateway setup to the Setup page

Gateway setup shows a `continuum-proxy enrol` command with a one-time
code; the manual settings stay behind "Set it up by hand". New members
section for inviting by email, plus an /invite page to accept, and the
login page honours a safe `next` redirect.
This commit is contained in:
2026-10-30 08:13:00 +00:00
parent 69f35c2a6b
commit 88b242d914
8 changed files with 336 additions and 6 deletions
+14 -2
View File
@@ -5,6 +5,15 @@ const error = ref<string | null>(null);
const client = useSupabaseClient();
const passwordLogin = useRuntimeConfig().public.passwordLogin;
const password = ref("");
const route = useRoute();
// Where to go after signing in. Only a path on this site: a `next` of
// `//elsewhere.example` or `https://...` would turn the sign-in page into an
// open redirect.
const next = computed(() => {
const wanted = route.query.next;
return typeof wanted === "string" && wanted.startsWith("/") && !wanted.startsWith("//") ? wanted : "/";
});
async function signInWithPassword() {
error.value = null;
@@ -17,12 +26,15 @@ async function signInWithPassword() {
return;
}
// The Supabase module redirects away from /login once a session exists.
await navigateTo("/");
await navigateTo(next.value);
}
async function sendMagicLink() {
error.value = null;
const { error: authError } = await client.auth.signInWithOtp({ email: email.value });
const { error: authError } = await client.auth.signInWithOtp({
email: email.value,
options: next.value === "/" ? undefined : { emailRedirectTo: `${window.location.origin}${next.value}` },
});
if (authError) {
error.value = authError.message;
return;