chore(release): publish db 0.8.21, cli 0.8.65 and seven in-flight packages
Carries the rollback refusal in db and the matching CLI message, together with the auth, captcha, csr, dev-server, dev-toolbar, ui and validation changes that were already in the working tree, since publishing stages from it and those files would otherwise ship without being recorded here. @wrnexus/auth 0.8.28 -> 0.8.29 @wrnexus/captcha 0.8.15 -> 0.8.16 @wrnexus/cli 0.8.64 -> 0.8.65 @wrnexus/csr 0.8.37 -> 0.8.38 @wrnexus/db 0.8.20 -> 0.8.21 @wrnexus/dev-server 0.8.60 -> 0.8.61 @wrnexus/dev-toolbar 0.8.17 -> 0.8.18 @wrnexus/ui 0.8.75 -> 0.8.76 @wrnexus/validation 0.8.12 -> 0.8.13 Also declares Event among the browser globals captcha's client asset already lists, which was the last lint failure, and reformats four files. typecheck, lint, 1998 tests and format:check all pass. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
b807f7b5a7
commit
06433e4ac4
28 files changed
+194
-43
No files matched your search
@@ -7,6 +7,10 @@ component InvitationAccept {
|
||||
token = ""
|
||||
redirect = "/account"
|
||||
organization = "your workspace"
|
||||
workspace = ""
|
||||
team = ""
|
||||
role = ""
|
||||
expires = ""
|
||||
inviter = "A workspace administrator"
|
||||
title = "Accept your invitation"
|
||||
description = "Create your password to join the workspace."
|
||||
@@ -18,10 +22,17 @@ component InvitationAccept {
|
||||
}
|
||||
view {
|
||||
<section {...attrs} data-wrnexus-runtime="auth" class='w-full max-w-md rounded-[var(--wrn-radius-lg)] border border-[var(--wrn-color-border)] bg-[var(--wrn-color-surface)] p-6 text-[var(--wrn-color-text)] shadow-[var(--wrn-shadow-2)] {class}'>
|
||||
<span class="flex size-11 items-center justify-center rounded-full bg-[color-mix(in_srgb,var(--wrn-color-primary)_12%,transparent)] text-[var(--wrn-color-primary)]"><span class="icon-[lucide--user-round-plus] size-5"></span></span>
|
||||
<span class="mx-auto flex size-11 items-center justify-center rounded-full bg-[color-mix(in_srgb,var(--wrn-color-primary)_12%,transparent)] text-[var(--wrn-color-primary)]"><span class="icon-[lucide--user-round-plus] size-5"></span></span>
|
||||
<h1 class="mb-0 mt-4 text-2xl font-semibold">{title}</h1>
|
||||
<p class="mb-0 mt-2 text-sm text-[var(--wrn-color-muted)]">{description}</p>
|
||||
<div class="mt-5 rounded-[var(--wrn-radius-sm)] border border-[var(--wrn-color-border)] bg-[var(--wrn-color-surface-2)] p-4 text-sm"><p class="m-0 font-semibold">{organization}</p><p class="mb-0 mt-1 text-[var(--wrn-color-muted)]">Invited by {inviter}</p></div>
|
||||
<div class="mt-5 grid gap-2 rounded-[var(--wrn-radius-sm)] border border-[var(--wrn-color-border)] bg-[var(--wrn-color-surface-2)] p-4 text-sm">
|
||||
<p class="m-0 font-semibold">{organization}</p>
|
||||
{#if workspace}<p class="m-0 text-[var(--wrn-color-muted)]"><span class="font-medium text-[var(--wrn-color-text)]">Workspace:</span> {workspace}</p>{/if}
|
||||
{#if team}<p class="m-0 text-[var(--wrn-color-muted)]"><span class="font-medium text-[var(--wrn-color-text)]">Team:</span> {team}</p>{/if}
|
||||
{#if role}<p class="m-0 text-[var(--wrn-color-muted)]"><span class="font-medium text-[var(--wrn-color-text)]">Role:</span> {role}</p>{/if}
|
||||
<p class="m-0 text-[var(--wrn-color-muted)]"><span class="font-medium text-[var(--wrn-color-text)]">Invited by:</span> {inviter}</p>
|
||||
{#if expires}<p class="m-0 text-xs text-[var(--wrn-color-muted)]">Invitation expires {expires}</p>{/if}
|
||||
</div>
|
||||
<form method="post" action='{action}' data-schema='{schema}' data-redirect='{redirect}' novalidate class="mt-5 space-y-4">
|
||||
<input type="hidden" name="token" value='{token}' />
|
||||
<Input id="auth-invitation-name" name="displayName" label="Display name" autocomplete="name" placeholder="Enter your display name" icon="icon-[lucide--user]" color="{color}" size="{size}" />
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@wrnexus/auth",
|
||||
"version": "0.8.26",
|
||||
"version": "0.8.29",
|
||||
"description": "Complete authentication, account security, MFA, passkeys, recovery, devices, risk, and audit system for WRNexusJS.",
|
||||
"type": "module",
|
||||
"sideEffects": false,
|
||||
|
||||
@@ -98,6 +98,9 @@ export interface AuthEngine {
|
||||
ttlMs?: number;
|
||||
baseUrl?: string;
|
||||
}): Promise<{ token: string; user: ReturnType<typeof publicUser> }>;
|
||||
inspectInvitation(
|
||||
token: string,
|
||||
): Promise<{ target?: string; expiresAt: number; metadata: Record<string, unknown> } | undefined>;
|
||||
acceptInvitation(
|
||||
token: string,
|
||||
input: { password?: string; displayName?: string },
|
||||
@@ -1483,6 +1486,16 @@ export function createAuthEngine(options: AuthEngineOptions): AuthEngine {
|
||||
return { token, user: publicUser(user) };
|
||||
},
|
||||
|
||||
async inspectInvitation(raw) {
|
||||
const token = await inspectToken(raw, "invite");
|
||||
if (!token) return undefined;
|
||||
return {
|
||||
target: token.target,
|
||||
expiresAt: token.expiresAt,
|
||||
metadata: { ...(token.metadata ?? {}) },
|
||||
};
|
||||
},
|
||||
|
||||
async acceptInvitation(raw, input) {
|
||||
const token = await inspectToken(raw, "invite");
|
||||
if (!token)
|
||||
|
||||
@@ -388,9 +388,14 @@ describe("authentication engine", () => {
|
||||
displayName: "Invited User",
|
||||
roles: ["member"],
|
||||
invitedBy: "admin-user",
|
||||
metadata: { organizationName: "Acme", workspaceName: "Product" },
|
||||
baseUrl: "https://example.test",
|
||||
});
|
||||
expect(messages.at(-1)?.template).toBe("invitation");
|
||||
expect(await engine.inspectInvitation(invitation.token)).toMatchObject({
|
||||
target: "invited@example.com",
|
||||
metadata: { organizationName: "Acme", workspaceName: "Product" },
|
||||
});
|
||||
const accepted = await engine.acceptInvitation(invitation.token, {
|
||||
password: "StrongPassword123",
|
||||
});
|
||||
@@ -399,6 +404,7 @@ describe("authentication engine", () => {
|
||||
expect(
|
||||
(await engine.acceptInvitation(invitation.token, { password: "StrongPassword123" })).ok,
|
||||
).toBe(false);
|
||||
expect(await engine.inspectInvitation(invitation.token)).toBeUndefined();
|
||||
});
|
||||
|
||||
test("customizes delivered token links without application-owned auth APIs", async () => {
|
||||
|
||||
Reference in new issue
Block a user