Commit 0ec3cb8d authored by Mahmoud Aglan's avatar Mahmoud Aglan

fix(account): guests and Google players could not delete their account

The local token check returned only id, role and email, so every account
read as an email account and deleting it asked for a password: impossible
for a guest (an anonymous user) or a Google player. The token's
app_metadata and is_anonymous now come through; a guest confirms instead
(found while testing the native app on the emulator). The confirm button's
label fits the dialog now (امسح خالص).
Co-Authored-By: 's avatarClaude Opus 5.5 <noreply@anthropic.com>
parent 61e7686a
...@@ -261,15 +261,25 @@ function handleMe(): void { ...@@ -261,15 +261,25 @@ function handleMe(): void {
jsonResponse([ jsonResponse([
'id' => $user['id'], 'id' => $user['id'],
'email' => $user['email'] ?? null, 'email' => $user['email'] ?? null,
'provider' => $user['app_metadata']['provider'] ?? 'email', 'provider' => authProviderOf($user),
'created_at' => $user['created_at'] ?? null 'created_at' => $user['created_at'] ?? null
]); ]);
} }
/**
* How the account signs in. A guest is an anonymous user with no app
* metadata: it used to read as "email", so deleting a guest account asked for
* a password the guest never had.
*/
function authProviderOf(array $user): string {
if (!empty($user['is_anonymous'])) return 'anonymous';
return (string)($user['app_metadata']['provider'] ?? 'email');
}
function handleDeleteAccount(array $input): void { function handleDeleteAccount(array $input): void {
$user = requireAuthUser(); $user = requireAuthUser();
$userId = $user['id']; $userId = $user['id'];
$provider = $user['app_metadata']['provider'] ?? 'email'; $provider = authProviderOf($user);
if ($provider === 'email') { if ($provider === 'email') {
$password = $input['password'] ?? ''; $password = $input['password'] ?? '';
......
...@@ -122,7 +122,11 @@ function verifyTokenLocally(string $token): ?array { ...@@ -122,7 +122,11 @@ function verifyTokenLocally(string $token): ?array {
if (!is_array($payload) || empty($payload['sub'])) return null; if (!is_array($payload) || empty($payload['sub'])) return null;
if (isset($payload['exp']) && (int)$payload['exp'] < time()) return null; if (isset($payload['exp']) && (int)$payload['exp'] < time()) return null;
return ['id' => $payload['sub'], 'role' => $payload['role'] ?? 'authenticated', 'email' => $payload['email'] ?? null]; // GoTrue puts how the account signs in in the token: callers (account
// deletion, auth.php me) read app_metadata.provider and is_anonymous.
return ['id' => $payload['sub'], 'role' => $payload['role'] ?? 'authenticated', 'email' => $payload['email'] ?? null,
'app_metadata' => is_array($payload['app_metadata'] ?? null) ? $payload['app_metadata'] : [],
'is_anonymous' => !empty($payload['is_anonymous'])];
} }
function base64UrlDecode(string $v): string { function base64UrlDecode(string $v): string {
......
...@@ -845,7 +845,7 @@ const strings = { ...@@ -845,7 +845,7 @@ const strings = {
'settings.sec_app': 'اللعبة', 'settings.sec_app': 'اللعبة',
'settings.sec_account': 'الحساب', 'settings.sec_account': 'الحساب',
'settings.sec_legal': 'قانوني', 'settings.sec_legal': 'قانوني',
'settings.delete_confirm_btn': 'امسح حسابي خالص', 'settings.delete_confirm_btn': 'امسح خالص',
'settings.err_wrong_password': 'الباسورد غلط', 'settings.err_wrong_password': 'الباسورد غلط',
'settings.err_password_required': 'اكتب الباسورد للتأكيد', 'settings.err_password_required': 'اكتب الباسورد للتأكيد',
'org.intro': 'اختار منظمة وقدّم طلب انضمام', 'org.intro': 'اختار منظمة وقدّم طلب انضمام',
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment