forked from retoor/devplacepy
Implements the moderation and consent obligations a social platform carries, so the web version and any client that speaks to it enforce the same rules. Moderation core (services/moderation/, database/moderation.py): a reportable target registry, the content filter and its choke points, the report queue with atomic resolution, enforcement actions, consent tracking, maturity gating, and account deletion with a grace window. Surfaces: POST /reports plus the member report list, /admin/moderation and the per-report admin view, /workspaces, terms acceptance at /auth/terms, consent and account deletion under /profile, the report button and dialog partials, the maturity gate, and the moderation stylesheet and ReportDialog client. Every user-generated surface stays reportable by construction: new content tables are registered in REPORTABLE_TARGETS or listed in UNREPORTABLE_TABLES with a reason, and the registry test fails the suite on anything left unclassified. Docs: community guidelines, content moderation, intellectual property, privacy, terms, contact, and the admin-only moderation operations page, plus the moderation API group and the Devii moderation actions. Compliance record: applecomp.md is the requirement register, applechanges.md the gap analysis against this codebase, and appleimpl.md the implementation design they resolve to. Tests cover the report flow, admin moderation, consent, account deletion, terms acceptance, workspaces, and the registry invariant across the unit, api, and e2e tiers.
147 lines
6.6 KiB
Python
147 lines
6.6 KiB
Python
# retoor <retoor@molodetz.nl>
|
|
|
|
from .._shared import endpoint, field
|
|
|
|
GROUP = {
|
|
"slug": "auth",
|
|
"title": "Authentication",
|
|
"intro": """
|
|
# Authentication
|
|
|
|
Create an account, sign in, recover your password, and log out. These are the only endpoints
|
|
that set or clear the `session` cookie; every other request authenticates with the methods
|
|
described in [Authentication](/docs/authentication.html). The shared rules (content
|
|
negotiation, pagination, status codes) live in [Conventions and Errors](/docs/conventions.html).
|
|
|
|
## Page vs. action
|
|
|
|
The GET endpoints render HTML sign-up, login, and password-reset forms; they also return the
|
|
page data as JSON when requested with `Accept: application/json` (including `page` to
|
|
distinguish the form type).
|
|
|
|
The POST endpoints are **actions**: they accept form fields, set or clear the `session` cookie,
|
|
and return a `302` redirect (or the JSON envelope for JSON callers).
|
|
|
|
**Sign-up requires a unique `username` and `email`** plus a `confirm_password` that matches the
|
|
password; **you log in with your `email` and password**. JSON callers receive validation errors
|
|
as a `422` with the shape `{ "fields": {...}, "messages": [...] }`.
|
|
""",
|
|
"endpoints": [
|
|
endpoint(
|
|
id="auth-signup",
|
|
method="GET",
|
|
path="/auth/signup",
|
|
title="Sign up page",
|
|
summary="Render the registration form. Returns an HTML page.",
|
|
auth="public",
|
|
interactive=True,
|
|
),
|
|
endpoint(
|
|
id="auth-signup-post",
|
|
method="POST",
|
|
path="/auth/signup",
|
|
title="Sign up",
|
|
summary="Create a new account. Sets the session cookie on success.",
|
|
auth="public",
|
|
encoding="form",
|
|
destructive=False,
|
|
params=[
|
|
field("username", "form", "string", True, "alice", "Username, 3-32 characters (letters, numbers, hyphens, underscores)."),
|
|
field("email", "form", "string", True, "alice@example.com", "Email address; must be unique and contain an @."),
|
|
field("password", "form", "string", True, "mysecret", "Password, 6+ characters."),
|
|
field("confirm_password", "form", "string", True, "mysecret", "Must match password."),
|
|
field("birth_date", "form", "string", True, "01/01/1990", "Date of birth, DD/MM/YYYY or YYYY-MM-DD. Only the derived age band is stored; the date is discarded."),
|
|
field("accept_terms", "form", "enum", True, "1", "Acceptance of the Terms of Service and Community Guidelines.", ["1"]),
|
|
],
|
|
notes=[
|
|
"Signup is refused below the platform minimum age (`moderation_minimum_age`).",
|
|
"Accepting records the terms, privacy and activity-recording consents; "
|
|
"third-party AI processing stays off until it is granted separately.",
|
|
],
|
|
),
|
|
endpoint(
|
|
id="auth-login",
|
|
method="GET",
|
|
path="/auth/login",
|
|
title="Log in page",
|
|
summary="Render the login form. Returns an HTML page.",
|
|
auth="public",
|
|
interactive=True,
|
|
params=[
|
|
field("next", "query", "string", False, "", "Redirect target after login."),
|
|
],
|
|
),
|
|
endpoint(
|
|
id="auth-login-post",
|
|
method="POST",
|
|
path="/auth/login",
|
|
title="Log in",
|
|
summary="Authenticate with email and password. Sets the session cookie.",
|
|
auth="public",
|
|
encoding="form",
|
|
params=[
|
|
field("email", "form", "string", True, "alice@example.com", "Your registered email."),
|
|
field("password", "form", "string", True, "mysecret", "Your password."),
|
|
field("remember_me", "form", "string", False, "on", "Send 'on' to extend the session to the remember-me lifetime."),
|
|
field("next", "form", "string", False, "", "Redirect target after login."),
|
|
],
|
|
),
|
|
endpoint(
|
|
id="auth-forgot-password",
|
|
method="GET",
|
|
path="/auth/forgot-password",
|
|
title="Forgot password page",
|
|
summary="Render the forgot-password form. Returns an HTML page.",
|
|
auth="public",
|
|
interactive=True,
|
|
),
|
|
endpoint(
|
|
id="auth-forgot-password-post",
|
|
method="POST",
|
|
path="/auth/forgot-password",
|
|
title="Request password reset",
|
|
summary="Send a password-reset email with a one-time link.",
|
|
auth="public",
|
|
encoding="form",
|
|
params=[
|
|
field("email", "form", "string", True, "alice@example.com", "Your registered email."),
|
|
],
|
|
),
|
|
endpoint(
|
|
id="auth-reset-password",
|
|
method="GET",
|
|
path="/auth/reset-password/{token}",
|
|
title="Reset password page",
|
|
summary="Render the password-reset form (only valid with a one-time token). Returns an HTML page.",
|
|
auth="public",
|
|
interactive=True,
|
|
params=[
|
|
field("token", "path", "string", True, "RESET_TOKEN", "The one-time reset token from the email."),
|
|
],
|
|
),
|
|
endpoint(
|
|
id="auth-reset-password-post",
|
|
method="POST",
|
|
path="/auth/reset-password/{token}",
|
|
title="Reset password",
|
|
summary="Set a new password using a one-time reset token.",
|
|
auth="public",
|
|
encoding="form",
|
|
params=[
|
|
field("token", "path", "string", True, "RESET_TOKEN", "The one-time reset token from the email."),
|
|
field("password", "form", "string", True, "newpass", "New password, 6+ characters."),
|
|
field("confirm_password", "form", "string", True, "newpass", "Must match password."),
|
|
],
|
|
),
|
|
endpoint(
|
|
id="auth-logout",
|
|
method="GET",
|
|
path="/auth/logout",
|
|
title="Log out",
|
|
summary="Clear the session cookie and redirect to the landing page.",
|
|
auth="public",
|
|
interactive=False,
|
|
),
|
|
],
|
|
}
|