-
-
Notifications
You must be signed in to change notification settings - Fork 115
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Link apple identity natively #588
Comments
Hi @MilesV64, unfortunately, that isn't supported yet. The only way to link an account is through the OAuth web flow. We don't have an ETA for this, but it is on the roadmap, I'll keep this issue open for posting updates for this feature. Thanks. |
Hi @MilesV64, I ran into a similar issue with my app. Users can sign in anonymously, but at some point they want to create an account and link all their contributions to this new account. I was thinking about the following work-around without needed an OAuth web flow. It's far from perfect.. A native solution would be better but it doesn't exist yet... There will be issues, please let me know so I can try and resolve them! One security issue is obvious: I can't verify that the old uuid actually belonged to this user since functions aren't stateful and I can only call it after the user has signed in with apple (or OAuth, ...) since I need to know their new uuid. If there are solutions to this please let me know! My solution that seems to work in test environment: I create a function in Supabase to merge their Profile (table with some more info about auth.users. Profiles has a uuid 'user_id' which is a foreign key into auth.users.id, and a uuid 'profile_id' which is used in all other tables as foreign key (when a user deletes their account I don't want to cascade and delete all their contributions, instead I anonymize them). Anyways back to the function below. I call this function from the users device when they successfully auth with apple and pass their auth.user.id from the anonymous user and from the authenticated user. CREATE OR REPLACE FUNCTION public.merge_user_requested(old_uuid UUID, new_uuid UUID)
RETURNS VOID
SET search_path = ''
LANGUAGE plpgsql
SECURITY DEFINER
AS $$
DECLARE
old_profile RECORD;
caller_user UUID := COALESCE(auth.uid(), gen_random_uuid()); -- Get the caller's user ID or fallback to a random UUID
old_user_is_anonymous BOOLEAN;
old_profile_id UUID;
new_profile_id UUID;
BEGIN
-- Check if the user calling the function is the same as new_uuid
IF caller_user IS DISTINCT FROM new_uuid THEN
RAISE EXCEPTION 'Permission denied: You can only merge your own profiles.';
END IF;
-- Check if old_uuid is an anonymous account
SELECT is_anonymous INTO old_user_is_anonymous
FROM auth.users
WHERE id = old_uuid;
IF old_user_is_anonymous IS DISTINCT FROM TRUE THEN
RAISE EXCEPTION 'The old account must be an anonymous account to proceed with the merge.';
END IF;
-- Get the profile_id of the old_uuid
SELECT profile_id INTO old_profile_id
FROM profiles
WHERE user_id = old_uuid;
-- Get the profile_id of the new_uuid
SELECT profile_id INTO new_profile_id
FROM profiles
WHERE user_id = new_uuid;
-- Delete the unused new profile
DELETE FROM profiles WHERE user_id = new_uuid;
-- Update the old profile with the new auth.user.id
UPDATE profiles
SET
user_id = new_uuid,
updated_at = NOW()
WHERE user_id = old_uuid;
-- Delete the old user from the auth.users table since it is a waste of space.
DELETE FROM auth.users WHERE id = old_uuid;
END;
$$; func linkAnonymousAccountToApple(result: Result<ASAuthorization, Error>) async throws {
isLoading = true
defer { isLoading = false }
guard let credential: ASAuthorizationAppleIDCredential = try result.get().credential as? ASAuthorizationAppleIDCredential
else {
// Handle error
return
}
guard let idToken = credential.identityToken
.flatMap({ String(data: $0, encoding: .utf8) })
else {
// handle error
return
}
// Save the anonymous (old) user id
let old_uuid = user?.id
let session = try await SupabaseModel.shared.client.auth.signInWithIdToken(
credentials: .init(
provider: .apple,
idToken: idToken
)
)
user = session.user
// Unpack the old and new uuids and call the function using RPC
if let oldUUID = old_uuid, let newUUID = user?.id {
// Call the RPC with correctly named parameters
let params: [String: UUID] = [
"old_uuid": oldUUID,
"new_uuid": newUUID
]
// Add error handling here.
let _ = try await SupabaseModel.shared.client.rpc("merge_user_requested", params: params).execute()
} |
I'm currently stuck without this. Where can I learn about the "OAuth flow which redirects to web" approach? |
Using the swift client you can call (passing in your own redirect url ie try await supabaseClient.auth.linkIdentity(
provider: .apple,
redirectTo: redirect,
launchURL: launchURL
) Then |
Feature Request
We have native apple sign in, but no way (that I can see) of natively linking Apple as a sign in option to an existing account, we need to use the OAuth flow which redirects to web which is not a natural experience on an apple device for authenticating with apple.
Is it possible to skip the PKCE flow flor linking apple as an identity, authenticating natively?
The text was updated successfully, but these errors were encountered: