supabase / auth

A JWT based API for managing users and issuing JWT tokens
https://supabase.com/docs/guides/auth
MIT License
1.55k stars 375 forks source link

auth.signOut fails after deletings user #1801

Open lenzi-e opened 1 month ago

lenzi-e commented 1 month ago

Bug report

Describe the bug

I have an edge function that I invoke via supabas-js which soft deletes a user. This will successfully delete the user. After that I call auth.signOut() and get the following error:

Error signing out: Auth session missing!

To Reproduce

Steps to reproduce the behavior, please provide code snippets or a repository:

Soft delete a user. (I used an edge function like this:)

      const { data, error } = await supabase.functions.invoke("delete-user", {
        body: {
          name,
          email,
          details: formValues.feedback,
        },
      });
  const { data, error } = await supabaseServiceRoleClient.auth.admin.deleteUser(userId, true)

It is successful and returns:

{"user": {}}

Here is the logs:

{
  "event_message": "{\"auth_event\":{\"action\":\"user_deleted\",\"actor_id\":\"xxxx\",\"actor_username\":\"service_role\",\"actor_via_sso\":false,\"log_type\":\"team\",\"traits\":{\"user_email\":\"xxxx\",\"user_id\":\"xxxx\",\"user_phone\":\"\"}},\"component\":\"api\",\"duration\":58542176,\"level\":\"info\",\"method\":\"DELETE\",\"msg\":\"request completed\",\"path\":\"/admin/users/xxxx\",\"referer\":\"xxxx://\",\"remote_addr\":\"xxxx\",\"request_id\":\"8d12a3075508ce88-SJC\",\"status\":200,\"time\":\"2024-10-11T23:30:14Z\",\"user_id\":\"xxxx\"}",
  "id": "xxxx",
  "metadata": [
    {
      "message": null,
      "timestamp": null,
      "__MONOTONIC_TIMESTAMP": null,
      "CODE_FUNC": null,
      "instance_id": null,
      "status": "200",
      "_CMDLINE": null,
      "method": "DELETE",
      "_SYSTEMD_CGROUP": null,
      "CODE_FILE": null,
      "EXECUTABLE": null,
      "_EXE": null,
      "UNIT": null,
      "level": "info",
      "_COMM": null,
      "duration": "58542176",
      "issuer": null,
      "_LINE_BREAK": null,
      "_SOURCE_REALTIME_TIMESTAMP": null,
      "msg": "request completed",
      "action": null,
      "login_method": null,
      "_UID": null,
      "host": "xxxx",
      "PRIORITY": null,
      "_CAP_EFFECTIVE": null,
      "_PID": null,
      "INVOCATION_ID": null,
      "_SYSTEMD_UNIT": null,
      "source_type": null,
      "SYSLOG_FACILITY": null,
      "request_id": "xxxx",
      "CODE_LINE": null,
      "path": "/admin/users/xxxx",
      "component": "api",
      "project": null,
      "user_id": "xxxx",
      "auth_event": [
        {
          "action": "user_deleted",
          "actor_id": "xxxx",
          "actor_name": null,
          "actor_username": "service_role",
          "actor_via_sso": false,
          "log_type": "team",
          "traits": [
            {
              "channel": null,
              "identity_id": null,
              "provider": null,
              "provider_id": null,
              "provider_type": null,
              "user_email": "xxxx",
              "user_id": "xxxx",
              "user_phone": null
            }
          ]
        }
      ],
      "args": [],
      "panic": null,
      "referer": "xxxx://",
      "factor_id": null,
      "provider": null,
      "client_id": null,
      "stack": null,
      "remote_addr": "xxxx",
      "_SYSTEMD_SLICE": null,
      "_SYSTEMD_INVOCATION_ID": null,
      "header": null,
      "_MACHINE_ID": null,
      "_AUDIT_LOGINUID": null,
      "_TRANSPORT": null,
      "_SELINUX_CONTEXT": null,
      "MESSAGE_ID": null,
      "__REALTIME_TIMESTAMP": null,
      "metadata": [],
      "_STREAM_ID": null,
      "metering": null,
      "time": null,
      "_GID": null,
      "_BOOT_ID": null,
      "SYSLOG_IDENTIFIER": null,
      "_AUDIT_SESSION": null,
      "error": null
    }
  ],
  "timestamp": 1728689414000000
}

Try to logout.

await supabase.auth.signOut();

Get the error:

Error signing out: Auth session missing!

Here is the log:

{
  "event_message": "{\"component\":\"api\",\"error\":\"Session not found\",\"level\":\"info\",\"method\":\"POST\",\"msg\":\"session id (xxxx) doesn't exist\",\"path\":\"/logout\",\"referer\":\"xxxx://\",\"remote_addr\":\"xxxx\",\"request_id\":\"xxxx\",\"time\":\"2024-10-11T23:30:43Z\"}",
  "id": "xxxx",
  "metadata": [
    {
      "message": null,
      "timestamp": null,
      "__MONOTONIC_TIMESTAMP": null,
      "CODE_FUNC": null,
      "instance_id": null,
      "status": null,
      "_CMDLINE": null,
      "method": "POST",
      "_SYSTEMD_CGROUP": null,
      "CODE_FILE": null,
      "EXECUTABLE": null,
      "_EXE": null,
      "UNIT": null,
      "level": "info",
      "_COMM": null,
      "duration": null,
      "issuer": null,
      "_LINE_BREAK": null,
      "_SOURCE_REALTIME_TIMESTAMP": null,
      "msg": "session id (xxxx) doesn't exist",
      "action": null,
      "login_method": null,
      "_UID": null,
      "host": "xxxx",
      "PRIORITY": null,
      "_CAP_EFFECTIVE": null,
      "_PID": null,
      "INVOCATION_ID": null,
      "_SYSTEMD_UNIT": null,
      "source_type": null,
      "SYSLOG_FACILITY": null,
      "request_id": "xxxx",
      "CODE_LINE": null,
      "path": "/logout",
      "component": "api",
      "project": null,
      "user_id": null,
      "auth_event": [],
      "args": [],
      "panic": null,
      "referer": "xxxx://",
      "factor_id": null,
      "provider": null,
      "client_id": null,
      "stack": null,
      "remote_addr": "xxxx",
      "_SYSTEMD_SLICE": null,
      "_SYSTEMD_INVOCATION_ID": null,
      "header": null,
      "_MACHINE_ID": null,
      "_AUDIT_LOGINUID": null,
      "_TRANSPORT": null,
      "_SELINUX_CONTEXT": null,
      "MESSAGE_ID": null,
      "__REALTIME_TIMESTAMP": null,
      "metadata": [],
      "_STREAM_ID": null,
      "metering": null,
      "time": null,
      "_GID": null,
      "_BOOT_ID": null,
      "SYSLOG_IDENTIFIER": null,
      "_AUDIT_SESSION": null,
      "error": "Session not found"
    }
  ],
  "timestamp": 1728689443000000
}

Expected behavior

I expect the logout, after the user deletion, to work successfully.

lenzi-e commented 1 month ago

I found a workaround until this is fixed. I tried clearing cookies and didn't have any luck. And (as the issue states) signOut was throwing an error. But if I clear the cookies directly before calling signout, then it works as expected. I'm using react-native / expo and this is how I cleared the cookies:

await AsyncStorage.clear();
await supabase.auth.signOut();
kangmingtay commented 4 weeks ago

@lenzi-e hmm we fixed this issue in https://github.com/supabase/auth-js/pull/894 but it seems that you are on the version of supabase-js that has the fix so this might be a different issue 🤔

this stems from the browser not knowing that the user has been deleted by the edge function - when the signout method is called from the browser, it's using the access token stored in the browser to make the sign out request but since the user no longer exists, an error is returned.

the expected behaviour is for the client lib to catch this error and just remove the user session from the cookies in the browser