This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
// SPDX-License-Identifier: LicenseRef-ConusAI-Template-1.0
|
||||
// The person's own account (joint contract §12): what the app keeps about them, the export of it, and
|
||||
// the deletion of the account. The page is a user page, under `settings`, which is a reserved
|
||||
// organization slug, so no organization's path can shadow it.
|
||||
//
|
||||
// The export and the deletion are the account module's procedures; this page only renders them, and
|
||||
// the client host beside it ends the browser modules' context once a deletion answered. The analytics
|
||||
// panel (ADR-049) erases or exports what the platform's own stores keep about the person's visits,
|
||||
// through the account.analytics procedures: the deployment token stays on the server. With the fake
|
||||
// platform its procedures answer "unavailable".
|
||||
|
||||
import { ACCOUNT_PATH, accountDeletionStatus } from "@app/modules/account/contract"
|
||||
import { analyticsLabels, deletionLabels, exportLabels, pageLabels } from "@app/modules/account/ui"
|
||||
import { loadAuthConfig } from "@conusai-kit/auth"
|
||||
import { meGet } from "@conusai-kit/tenancy"
|
||||
import { redirect } from "next/navigation"
|
||||
import type { ReactElement } from "react"
|
||||
import { orFallback, signInHref } from "../../../src/server/guard"
|
||||
import { pageContext } from "../../../src/server/page"
|
||||
import { AccountPanels } from "../../../src/ui/account"
|
||||
|
||||
export const dynamic = "force-dynamic"
|
||||
|
||||
/**
|
||||
* Where a person signs in again to delete their account: straight to the provider (the sign-in page
|
||||
* sends somebody already signed in away), or, in development, the dev login with their own address.
|
||||
* Either opens a new session, whose sign-in is then recent.
|
||||
*/
|
||||
function reauthHref(email: string): string {
|
||||
const back = `return_to=${encodeURIComponent(ACCOUNT_PATH)}`
|
||||
const config = loadAuthConfig()
|
||||
if (config.oidc) return `/auth/sign-in/start?${back}`
|
||||
if (config.devLogin) return `/auth/dev-login?email=${encodeURIComponent(email)}&${back}`
|
||||
return `/auth/sign-in?${back}`
|
||||
}
|
||||
|
||||
export default async function AccountPage(): Promise<ReactElement> {
|
||||
const { caller, i18n, signedIn, path } = await pageContext()
|
||||
if (!signedIn) redirect(signInHref(path))
|
||||
const t = (key: string, values?: Record<string, string | number>) => i18n.message(`account.${key}`, values)
|
||||
const page = pageLabels(t)
|
||||
const [me, status] = await orFallback(path, () =>
|
||||
Promise.all([caller.call(meGet, undefined), caller.call(accountDeletionStatus, undefined)]),
|
||||
)
|
||||
const failed = i18n.message("app.failed")
|
||||
return (
|
||||
<main>
|
||||
<h1>{page.title}</h1>
|
||||
<p>{page.intro}</p>
|
||||
<section aria-labelledby="account-profile">
|
||||
<h2 id="account-profile">{page.profileHeading}</h2>
|
||||
<dl>
|
||||
<dt>{page.name}</dt>
|
||||
<dd>{me.displayName}</dd>
|
||||
<dt>{page.email}</dt>
|
||||
<dd>{me.email}</dd>
|
||||
</dl>
|
||||
</section>
|
||||
<AccountPanels
|
||||
exportLabels={exportLabels(t, failed)}
|
||||
analyticsLabels={analyticsLabels(t, failed)}
|
||||
deletion={{
|
||||
labels: deletionLabels(t, failed, status, me.email),
|
||||
interactive: status.interactive,
|
||||
recentSignIn: status.recentSignIn,
|
||||
reauthHref: reauthHref(me.email),
|
||||
deletion: status.deletion,
|
||||
}}
|
||||
/>
|
||||
</main>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user