Possible fix for sign in with apple migrations failing

This commit is contained in:
George Powell
2026-02-18 17:54:01 -05:00
parent c50cccd3d3
commit e8b2d2e35e
6 changed files with 153 additions and 17 deletions
+18 -4
View File
@@ -25,6 +25,12 @@ export const POST: RequestHandler = async ({ request, cookies }) => {
}
cookies.delete('apple_oauth_state', { path: '/' });
const anonId = stored.anonymousId;
if (!anonId) {
console.error('[Apple auth] Missing anonymousId in state cookie');
throw error(400, 'Missing anonymous ID — please return to the game and try again');
}
// Exchange authorization code for tokens
const tokens = await exchangeAppleCode(code, `${publicEnv.PUBLIC_SITE_URL}/auth/apple/callback`);
const claims = decodeAppleIdToken(tokens.id_token);
@@ -51,7 +57,8 @@ export const POST: RequestHandler = async ({ request, cookies }) => {
if (existingAppleUser) {
userId = existingAppleUser.id;
await auth.migrateAnonymousStats(stored.anonymousId, userId);
console.log(`[Apple auth] Returning Apple user: userId=${userId}, anonId=${anonId}`);
await auth.migrateAnonymousStats(anonId, userId);
} else if (claims.email) {
// 2. Check if email matches an existing email/password user
const existingEmailUser = await auth.getUserByEmail(claims.email);
@@ -59,10 +66,12 @@ export const POST: RequestHandler = async ({ request, cookies }) => {
// Link Apple account to existing user
await db.update(userTable).set({ appleId }).where(eq(userTable.id, existingEmailUser.id));
userId = existingEmailUser.id;
await auth.migrateAnonymousStats(stored.anonymousId, userId);
console.log(`[Apple auth] Linked Apple to existing email user: userId=${userId}, anonId=${anonId}`);
await auth.migrateAnonymousStats(anonId, userId);
} else {
// 3. Brand new user — use anonymousId as user ID to preserve local stats
userId = stored.anonymousId || crypto.randomUUID();
userId = anonId;
console.log(`[Apple auth] New user (has email): userId=${userId}`);
try {
await db.insert(userTable).values({
id: userId,
@@ -79,6 +88,8 @@ export const POST: RequestHandler = async ({ request, cookies }) => {
const retryUser = await auth.getUserByAppleId(appleId);
if (retryUser) {
userId = retryUser.id;
console.log(`[Apple auth] Race condition (has email): resolved to userId=${userId}, anonId=${anonId}`);
await auth.migrateAnonymousStats(anonId, userId);
} else {
throw error(500, 'Failed to create user');
}
@@ -89,7 +100,8 @@ export const POST: RequestHandler = async ({ request, cookies }) => {
}
} else {
// No email from Apple — create account with appleId only
userId = stored.anonymousId || crypto.randomUUID();
userId = anonId;
console.log(`[Apple auth] New user (no email): userId=${userId}`);
try {
await db.insert(userTable).values({
id: userId,
@@ -105,6 +117,8 @@ export const POST: RequestHandler = async ({ request, cookies }) => {
const retryUser = await auth.getUserByAppleId(appleId);
if (retryUser) {
userId = retryUser.id;
console.log(`[Apple auth] Race condition (no email): resolved to userId=${userId}, anonId=${anonId}`);
await auth.migrateAnonymousStats(anonId, userId);
} else {
throw error(500, 'Failed to create user');
}
+17 -6
View File
@@ -1,25 +1,36 @@
<script lang="ts">
import { page } from '$app/state';
import AuthModal from '$lib/components/AuthModal.svelte';
import { page } from "$app/state";
import { browser } from "$app/environment";
import AuthModal from "$lib/components/AuthModal.svelte";
let isOpen = $state(true);
const user = $derived(page.data.user);
const anonymousId = crypto.randomUUID();
let anonymousId = $state("");
$effect(() => {
if (browser) {
anonymousId = localStorage.getItem("bibdle-anonymous-id") ?? "";
}
});
</script>
<div class="min-h-screen bg-gray-900 flex items-center justify-center p-4">
{#if user}
<div class="text-white text-center space-y-4">
<p class="text-lg">Signed in as <strong>{user.email ?? 'no email'}</strong></p>
<p class="text-lg">
Signed in as <strong>{user.email ?? "no email"}</strong>
</p>
<form method="POST" action="/auth/logout">
<button class="px-4 py-2 bg-red-600 rounded-md hover:bg-red-700 transition-colors">
<button
class="px-4 py-2 bg-red-600 rounded-md hover:bg-red-700 transition-colors"
>
Sign Out
</button>
</form>
</div>
{:else}
<button
onclick={() => isOpen = true}
onclick={() => (isOpen = true)}
class="px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition-colors"
>
Open Auth Modal