Skip to content

Commit 74aca42

Browse files
committed
Stack Supabase Auth UAT validation account state and closeout for usable sign in - PR_STACK_26166_157-160-supabase-sign-in-uat-ready
1 parent 91aaf9c commit 74aca42

14 files changed

Lines changed: 1088 additions & 569 deletions

account/create-account.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<meta charset="utf-8">
66
<meta name="viewport" content="width=device-width, initial-scale=1">
77
<title>Create Account - GameFoundryStudio</title>
8-
<meta name="description" content="Create a GameFoundryStudio account through the configured account provider.">
8+
<meta name="description" content="Create a GameFoundryStudio account through the account service.">
99
<link rel="icon" href="/favicon.svg">
1010
<link rel="stylesheet" href="../assets/theme-v2/css/theme.css">
1111
</head>
@@ -17,7 +17,7 @@
1717
<div class="container">
1818
<div class="kicker">Account</div>
1919
<h1>Create Account</h1>
20-
<p class="lede">Create an account through the configured account provider.</p>
20+
<p class="lede">Create an account through the account service.</p>
2121
</div>
2222
</section>
2323
<section class="section">
@@ -28,7 +28,7 @@ <h1>Create Account</h1>
2828
<div class="kicker">Account Access</div>
2929
<h2>Create Account</h2>
3030
</div>
31-
<p>Account creation is handled by the configured account provider.</p>
31+
<p>Account creation is handled by the account service.</p>
3232
<form class="content-stack" data-account-auth-form="create-account">
3333
<label for="createAccountEmail">Email</label>
3434
<input id="createAccountEmail" name="email" type="email" autocomplete="email" data-account-auth-email>

account/password-reset.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<meta charset="utf-8">
66
<meta name="viewport" content="width=device-width, initial-scale=1">
77
<title>Password Reset - GameFoundryStudio</title>
8-
<meta name="description" content="Request a GameFoundryStudio password reset through the configured account provider.">
8+
<meta name="description" content="Request a GameFoundryStudio password reset through the account service.">
99
<link rel="icon" href="/favicon.svg">
1010
<link rel="stylesheet" href="../assets/theme-v2/css/theme.css">
1111
</head>
@@ -17,7 +17,7 @@
1717
<div class="container">
1818
<div class="kicker">Account</div>
1919
<h1>Password Reset</h1>
20-
<p class="lede">Request a password reset through the configured account provider.</p>
20+
<p class="lede">Request a password reset through the account service.</p>
2121
</div>
2222
</section>
2323
<section class="section">
@@ -28,7 +28,7 @@ <h1>Password Reset</h1>
2828
<div class="kicker">Account Access</div>
2929
<h2>Password Reset</h2>
3030
</div>
31-
<p>Password reset email delivery is handled by the configured account provider.</p>
31+
<p>Password reset email delivery is handled by the account service.</p>
3232
<form class="content-stack" data-account-auth-form="password-reset">
3333
<label for="passwordResetEmail">Email</label>
3434
<input id="passwordResetEmail" name="email" type="email" autocomplete="email" data-account-auth-email>

assets/theme-v2/js/account-auth-actions.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ const passwordField = document.querySelector("[data-account-auth-password]");
44
const statusField = document.querySelector("[data-account-auth-status]");
55
const submitButton = document.querySelector("[data-account-auth-submit]");
66
const action = form?.getAttribute("data-account-auth-form") || "";
7+
const ACCOUNT_IDENTITY_SETUP_MESSAGE = "Account identity setup is incomplete. Please contact support.";
78
const AUTH_UNAVAILABLE_MESSAGE = "The site is currently unavailable. Please try again later.";
89
let authStatus = null;
910

@@ -32,6 +33,9 @@ async function readJson(response, fallbackMessage) {
3233
payload = null;
3334
}
3435
if (!response.ok || payload?.ok === false) {
36+
if (payload?.error === ACCOUNT_IDENTITY_SETUP_MESSAGE) {
37+
throw new Error(ACCOUNT_IDENTITY_SETUP_MESSAGE);
38+
}
3539
throw new Error(fallbackMessage);
3640
}
3741
return payload?.data || {};

assets/theme-v2/js/gamefoundry-partials.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -527,7 +527,7 @@
527527
return {
528528
role: "user",
529529
title: "Sign-in required",
530-
message: "Sign in as a local user to open Account pages."
530+
message: "Sign in with your account to open Account pages."
531531
};
532532
}
533533
return null;

assets/theme-v2/js/login-session.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ const identityField = document.querySelector("[data-login-identity]");
44
const passwordField = document.querySelector("[data-login-password]");
55
const statusField = document.querySelector("[data-login-status]");
66
const submitButton = document.querySelector("[data-login-submit]");
7+
const ACCOUNT_IDENTITY_SETUP_MESSAGE = "Account identity setup is incomplete. Please contact support.";
78
const AUTH_UNAVAILABLE_MESSAGE = "The site is currently unavailable. Please try again later.";
89
let authStatus = null;
910

@@ -65,6 +66,9 @@ async function readJson(response, fallbackMessage) {
6566
payload = null;
6667
}
6768
if (!response.ok || payload?.ok === false) {
69+
if (payload?.error === ACCOUNT_IDENTITY_SETUP_MESSAGE) {
70+
throw new Error(ACCOUNT_IDENTITY_SETUP_MESSAGE);
71+
}
6872
throw new Error(fallbackMessage);
6973
}
7074
return payload?.data || {};
@@ -79,6 +83,14 @@ async function requestAccountAuth(path, options = {}) {
7983
return readJson(response, AUTH_UNAVAILABLE_MESSAGE);
8084
}
8185

86+
async function requestCurrentSession() {
87+
const response = await fetch("/api/session/current", {
88+
headers: { "accept": "application/json" },
89+
method: "GET",
90+
});
91+
return readJson(response, AUTH_UNAVAILABLE_MESSAGE);
92+
}
93+
8294
function unavailableMessage(status) {
8395
return status?.message || AUTH_UNAVAILABLE_MESSAGE;
8496
}
@@ -95,6 +107,14 @@ async function refreshAccountAuthStatus() {
95107
}
96108
try {
97109
authStatus = await requestAccountAuth("status");
110+
if (authStatus.ready) {
111+
const session = await requestCurrentSession();
112+
if (session?.authenticated) {
113+
setFormEnabled(false);
114+
setStatus(`Signed in as ${session.displayName || session.label || "Account"}.`);
115+
return authStatus;
116+
}
117+
}
98118
setFormEnabled(Boolean(authStatus.ready));
99119
setStatus(authStatus.ready ? "Account service is available." : unavailableMessage(authStatus));
100120
} catch (error) {
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
# PR_26166_157-first-real-sign-in-validation
2+
3+
## Branch Validation
4+
5+
- Current branch: main
6+
- Expected branch: main
7+
- Branch validation: PASS
8+
9+
## Purpose
10+
11+
Validate real Supabase Create Account, Sign In, Session, Role Resolution, Sign Out, and Password Reset flows without adding new infrastructure.
12+
13+
## Requirement Checklist
14+
15+
- PASS - Real Create Account path validated against configured DEV Supabase.
16+
- PASS - Real Sign In path validated against configured DEV Supabase.
17+
- PASS - Current Session path validated after sign in.
18+
- PASS - Role resolution validated; created account resolved with `user`.
19+
- PASS - Sign Out validated; session returned to unauthenticated.
20+
- PASS - Password Reset validated with production-safe message.
21+
- PASS - No new infrastructure was added for this validation PR.
22+
- PASS - Product data remained Local DB.
23+
- PASS - No full samples smoke was run.
24+
25+
## Validation Lane Report
26+
27+
- contract: PASS - `node --test tests/dev-runtime/SupabaseProviderContractStub.test.mjs`
28+
- runtime: PASS - live local API probe against configured DEV Supabase.
29+
- integration: PASS - `npm run validate:supabase-dev`
30+
- Playwright: PASS - targeted auth/session Playwright subset.
31+
- samples: SKIP - explicitly out of scope.
32+
33+
## Changed Files
34+
35+
- Dedicated runtime implementation: none for this validation PR.
36+
- Stack reports/artifacts: `docs_build/dev/reports/*`
37+
- Shared stack tests: `tests/playwright/tools/LoginSessionMode.spec.mjs`
38+
39+
## Playwright V8 Coverage
40+
41+
- Artifact: `docs_build/dev/reports/playwright_v8_coverage_report.txt`
42+
- Status: WARN advisory for files not collected by current Chromium V8 coverage; targeted behavior validation passed.
43+
44+
## Skipped Lanes
45+
46+
- samples: SKIP - explicitly out of scope.
47+
- full workspace suite: SKIP - targeted auth/session validation was requested for this stack.
48+
49+
## Live DEV Evidence
50+
51+
Sanitized live UAT probe:
52+
53+
```json
54+
{
55+
"authStatus": {
56+
"status": 200,
57+
"configured": true,
58+
"ready": true,
59+
"identityTablesReady": true,
60+
"productDataProvider": "local-db"
61+
},
62+
"createAccount": {
63+
"status": 200,
64+
"identityProvisioned": true,
65+
"roleSlugs": ["user"],
66+
"userKeyLooksLikeUlid": true
67+
},
68+
"signIn": {
69+
"status": 200,
70+
"sessionResolved": true,
71+
"roleSlugs": ["user"]
72+
},
73+
"signedInSession": {
74+
"status": 200,
75+
"authenticated": true,
76+
"roleSlugs": ["user"],
77+
"userKeyLooksLikeUlid": true
78+
},
79+
"signOut": {
80+
"status": 200,
81+
"authenticated": false
82+
},
83+
"signedOutSession": {
84+
"status": 200,
85+
"authenticated": false,
86+
"displayName": "Login"
87+
},
88+
"passwordReset": {
89+
"status": 200,
90+
"action": "password-reset",
91+
"message": "If an account exists for that email, password reset instructions will be sent."
92+
}
93+
}
94+
```
95+
96+
## Manual Validation Notes
97+
98+
1. Start the local API runtime with Supabase Auth env configured and `GAMEFOUNDRY_DB_PROVIDER=local-db`.
99+
2. Open `account/create-account.html` and create a new account.
100+
3. Open `account/sign-in.html`, sign in, and confirm the Account nav shows the signed-in user.
101+
4. Confirm `/api/session/current` returns authenticated with the `user` role.
102+
5. Use the Account logout action and confirm the session returns to signed out.
103+
6. Open `account/password-reset.html` and request a password reset.
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# PR_26166_158-account-flow-error-polish
2+
3+
## Branch Validation
4+
5+
- Current branch: main
6+
- Expected branch: main
7+
- Branch validation: PASS
8+
9+
## Purpose
10+
11+
Polish user-facing account errors and remove provider/internal wording from active account flows.
12+
13+
## Requirement Checklist
14+
15+
- PASS - Generic unavailable message remains for site/provider failures: `The site is currently unavailable. Please try again later.`
16+
- PASS - Identity provisioning failures show the actionable support message: `Account identity setup is incomplete. Please contact support.`
17+
- PASS - Active Create Account and Password Reset copy says `account service`, not provider-specific wording.
18+
- PASS - No DEV wording appears in active account flow UI.
19+
- PASS - Browser still calls backend API contracts only.
20+
- PASS - No secrets, `.env`, password tables, or auth fallback changes were added.
21+
22+
## Implementation Evidence
23+
24+
- `assets/theme-v2/js/account-auth-actions.js` now allows only the safe identity setup support message through failed auth responses; other failed responses remain generic.
25+
- `assets/theme-v2/js/login-session.js` uses the same safe-message rule for Sign In.
26+
- `account/create-account.html` and `account/password-reset.html` now use account-service wording.
27+
- `assets/theme-v2/js/gamefoundry-partials.js` no longer tells users to sign in as a `local user` on protected Account pages.
28+
29+
## Changed Files
30+
31+
- `account/create-account.html`
32+
- `account/password-reset.html`
33+
- `assets/theme-v2/js/account-auth-actions.js`
34+
- `assets/theme-v2/js/login-session.js`
35+
- `assets/theme-v2/js/gamefoundry-partials.js`
36+
- `tests/playwright/tools/LoginSessionMode.spec.mjs`
37+
38+
## Validation Lane Report
39+
40+
- static: PASS - changed-file syntax checks passed.
41+
- Playwright: PASS - targeted browser test confirms identity setup support message renders and provider details are not exposed.
42+
- samples: SKIP - explicitly out of scope.
43+
44+
## Playwright V8 Coverage
45+
46+
- Artifact: `docs_build/dev/reports/playwright_v8_coverage_report.txt`
47+
- Status: WARN advisory for some changed JS files not collected by current Chromium V8 coverage; behavior passed through Playwright.
48+
49+
## Skipped Lanes
50+
51+
- samples: SKIP - explicitly out of scope.
52+
- full workspace suite: SKIP - targeted auth/session validation was requested for this stack.
53+
54+
## Manual Validation Notes
55+
56+
1. Temporarily create an Auth user without a matching app identity row.
57+
2. Attempt Sign In.
58+
3. Confirm the page shows `Account identity setup is incomplete. Please contact support.`
59+
4. Break or omit auth configuration and confirm the page shows the generic unavailable message.
60+
5. Confirm Create Account and Password Reset pages use account-service language.
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# PR_26166_159-account-session-ui-state
2+
3+
## Branch Validation
4+
5+
- Current branch: main
6+
- Expected branch: main
7+
- Branch validation: PASS
8+
9+
## Purpose
10+
11+
Show signed-in and signed-out account state consistently while preserving guest browsing and guest-save redirects.
12+
13+
## Requirement Checklist
14+
15+
- PASS - Sign In page checks current session through `/api/session/current`.
16+
- PASS - Signed-in users see `Signed in as <name>.` on the Sign In page.
17+
- PASS - Signed-in users have the Sign In submit button disabled on the Sign In page.
18+
- PASS - Header Account nav shows the signed-in display name after successful sign in.
19+
- PASS - Logout clears the current session and returns Account nav to `Sign In`.
20+
- PASS - Guest browsing remains allowed.
21+
- PASS - Guest saving still redirects to `account/sign-in.html`.
22+
- PASS - No browser-owned provider logic was added.
23+
24+
## Implementation Evidence
25+
26+
- `assets/theme-v2/js/login-session.js` reads current session through the backend session API after account service readiness.
27+
- `assets/theme-v2/js/gamefoundry-partials.js` retains shared header/account state behavior and updates protected Account copy.
28+
- Targeted Playwright covers signed-in Sign In page state, logout state, and guest save redirect.
29+
30+
## Changed Files
31+
32+
- `assets/theme-v2/js/login-session.js`
33+
- `assets/theme-v2/js/gamefoundry-partials.js`
34+
- `tests/playwright/tools/LoginSessionMode.spec.mjs`
35+
36+
## Validation Lane Report
37+
38+
- static: PASS - changed-file syntax checks passed.
39+
- Playwright: PASS - targeted auth/session subset passed 5/5.
40+
- samples: SKIP - explicitly out of scope.
41+
42+
## Playwright V8 Coverage
43+
44+
- Artifact: `docs_build/dev/reports/playwright_v8_coverage_report.txt`
45+
- Status: WARN advisory for some changed JS files not collected by current Chromium V8 coverage; signed-in/signed-out behavior passed through Playwright.
46+
47+
## Skipped Lanes
48+
49+
- samples: SKIP - explicitly out of scope.
50+
- full workspace suite: SKIP - targeted auth/session validation was requested for this stack.
51+
52+
## Manual Validation Notes
53+
54+
1. Sign in with a valid account.
55+
2. Confirm Account nav shows the signed-in display name.
56+
3. Visit `account/sign-in.html` while signed in.
57+
4. Confirm status reads `Signed in as <name>.` and Sign In is disabled.
58+
5. Sign out from the Account menu and confirm protected Account pages block access.
59+
6. Open a guest-allowed Toolbox page and confirm browsing remains possible.
60+
7. Trigger a guest save action and confirm it redirects to `account/sign-in.html`.

0 commit comments

Comments
 (0)