CMS auth flows
UI for authentication; the logic lives in @gg-software/auth. Typical wiring:
LoginForm → your API → useAuth().login(session) from @gg-software/auth/react.
LoginForm
Email + password with client-side format validation, remember-me and a forgot-password
link. Async onSubmit drives the loading state.
import { LoginForm } from '@gg-software/cms';
import { useAuth } from '@gg-software/auth/react';
function SignIn() {
const { login } = useAuth();
const [error, setError] = useState<string>();
return (
<LoginForm
error={error}
onSubmit={async ({ email, password, remember }) => {
const session = await api.signIn(email, password);
if (!session) return setError('Wrong email or password.');
login(session);
}}
onForgotPassword={() => router.push('/forgot-password')}
/>
);
}| Prop | Type | Default | Description |
|---|---|---|---|
onSubmit* | (credentials: LoginCredentials) => void | Promise<void> | — | called with the credentials on a valid submit; may be async |
error | ReactNode | — | server-side error shown above the fields (wrong password, …) |
loading | boolean | false | external loading state; the form also tracks async onSubmit itself |
showRemember | boolean | true | show the "Remember me" checkbox (default true) |
onForgotPassword | (() => void) | — | renders a "Forgot password?" link |
submitLabel | string | Sign in | |
className | string | — |
* required · generated from packages/cms/src/auth/LoginForm.tsx
LoginPage
Full-viewport login screen: centered card with logo, title and a LoginForm (all LoginForm props pass through).
import { LoginPage } from '@gg-software/cms';
<LoginPage
logo={<Logo />}
title="Sign in to Acme"
subtitle="Admin panel"
footer={<>No account? <a href="/contact">Contact us</a></>}
onSubmit={signIn}
/>;| Prop | Type | Default | Description |
|---|---|---|---|
onSubmit* | (credentials: LoginCredentials) => void | Promise<void> | — | called with the credentials on a valid submit; may be async |
error | ReactNode | — | server-side error shown above the fields (wrong password, …) |
loading | boolean | — | external loading state; the form also tracks async onSubmit itself |
showRemember | boolean | — | show the "Remember me" checkbox (default true) |
onForgotPassword | (() => void) | — | renders a "Forgot password?" link |
submitLabel | string | — | |
className | string | — | |
logo | ReactNode | — | logo/brand above the card |
title | ReactNode | Sign in | |
subtitle | ReactNode | — | muted line under the title |
footer | ReactNode | — | below the card (sign-up link, legal) |
* required · generated from packages/cms/src/auth/LoginPage.tsx
ForgotPasswordForm
Asks for the account email; once onSubmit resolves, a success message replaces the form.
<ForgotPasswordForm onSubmit={(email) => api.sendResetLink(email)} onBack={() => router.push('/login')} />| Prop | Type | Default | Description |
|---|---|---|---|
onSubmit* | (email: string) => void | Promise<void> | — | send the reset email; when it resolves, a success message replaces the form |
error | ReactNode | — | |
loading | boolean | false | |
successMessage | ReactNode | If an account exists for that email, a reset link is on its way. | |
submitLabel | string | Send reset link | |
onBack | (() => void) | — | back-to-login link |
className | string | — |
* required · generated from packages/cms/src/auth/ForgotPasswordForm.tsx
ResetPasswordForm
New password + confirmation, validated for strength (utils isStrongPassword) and match.
<ResetPasswordForm
onSubmit={(password) => api.resetPassword(token, password)}
requirements={{ minLength: 10, symbol: true }}
/>| Prop | Type | Default | Description |
|---|---|---|---|
onSubmit* | (password: string) => void | Promise<void> | — | called with the new password on a valid submit |
error | ReactNode | — | |
loading | boolean | false | |
requirements | PasswordRequirements | — | strength rules (utils isStrongPassword; default: 8+ chars, upper, lower, digit) |
hint | ReactNode | At least 8 characters with an uppercase letter, a lowercase letter and a number. | shown under the first field, defaults to a rules summary |
submitLabel | string | Set new password | |
className | string | — |
* required · generated from packages/cms/src/auth/ResetPasswordForm.tsx
PermissionGate
Renders children only when the current user (from @gg-software/auth/react’s
AuthProvider) passes all specified checks; with no checks it just requires an
authenticated session.
import { PermissionGate } from '@gg-software/cms';
<PermissionGate permission="delete:orders" fallback={null}>
<Button danger>Delete</Button>
</PermissionGate>
<PermissionGate anyRole={['admin', 'editor']} fallback={<NoAccess />}>
<ContentEditor />
</PermissionGate>| Prop | Type | Default | Description |
|---|---|---|---|
children* | ReactNode | — | rendered when every specified condition passes |
permission | string | — | required permission, e.g. "delete:orders" (wildcards in grants respected) |
role | string | — | required role |
anyRole | string[] | — | at least one of these roles |
fallback | ReactNode | null | rendered instead when a condition fails (default null) |
* required · generated from packages/cms/src/auth/PermissionGate.tsx