Skip to content

getAuthenticatorAssuranceLevel() dont work on edge function #1060

@Dramelac

Description

@Dramelac

Bug report

  • I confirm this is a bug with Supabase, not with my own application.
  • I confirm I have searched the Docs, GitHub Discussions, and Discord.

I'm aware the problematic of this issue is the same and the source of the problem also comes from the session but the subject and the implementation is not the same so I didn't consider it a duplicate of #910

Describe the bug

Hello everyone

I'm creating this issue because I'm trying to check the authentication level (aal) on the edge function side and impose aal2 if the user has enrolled at least one factor.
When I try to retrieve await supabaseClient.auth.mfa.getAuthenticatorAssuranceLevel() I get this:

{
  currentLevel: null,
  nextLevel: null,
  currentAuthenticationMethods: []
}

(Even though the MFA is properly configured for the current user)

To Reproduce

Here is my code from a supabase edge function. Run locally Using supabase-edge-runtime-1.67.2 (compatible with Deno v1.45.2):

const supabaseClient = createClient<Database, app_schema>(
        Deno.env.get("SUPABASE_URL") ?? "",
        Deno.env.get("SUPABASE_ANON_KEY") ?? "",
        {
            global: {headers: {Authorization: authHeader}},
            // I tried different auth options but nothing fix the getAuthenticatorAssuranceLevel response
            auth: {
                autoRefreshToken: false,
                persistSession: false,
                detectSessionInUrl: false,
                storage: false
            }
        }
    );
// getUser works, I can verify the session and get the list of verified factors but not the current aal
const current_user = await supabaseClient.auth.getUser();

// But not MFA policy check
const { data , error } = await supabaseClient.auth.mfa.getAuthenticatorAssuranceLevel()
console.log("Current MFA:", data)

// RLS query works too
[..]

The createClient code is from the official documentation exemple:
https://github.com/supabase/supabase/blob/14562e9c8abe793bd428eba3a1da196bf03f3e41/examples/edge-functions/supabase/functions/select-from-table-with-auth-rls/index.ts#L18-L30

What I tried to do as workaround:

  • Differents option on auth{} option like persistSession: false, storage: false to put the session in memory instead of local storage.
  • Manually set the session with await supabaseClient.auth.setSession(authHeader.replace("Bearer ", ""), "") but i get this error:
AuthSessionMissingError: Auth session missing!
    at p._setSession (https://esm.sh/@supabase/[email protected]/es2022/auth-js.mjs:3:30575)
    at https://esm.sh/@supabase/[email protected]/es2022/auth-js.mjs:3:30491
    at https://esm.sh/@supabase/[email protected]/es2022/auth-js.mjs:3:26917
    at p.qe [as lock] (https://esm.sh/@supabase/[email protected]/es2022/auth-js.mjs:3:14170)
    at p._acquireLock (https://esm.sh/@supabase/[email protected]/es2022/auth-js.mjs:3:26766)
    at p.setSession (https://esm.sh/@supabase/[email protected]/es2022/auth-js.mjs:3:30455)
    at eventLoopTick (ext:core/01_core.js:168:7)
    at async getSupabaseUserClient (file:///[..]/supabase/functions/_shared/supabaseUserClient.ts:34:41)
    at async Object.handler (file:///[..]/supabase/functions/my-actions/index.ts:34:28)
    at async respond (ext:sb_core_main_js/js/http.js:197:14) {
    __isAuthError: true,
    name: "AuthSessionMissingError",
    status: 400,
    code: undefined

We also had a conversation with @j4w8n about the situation: supabase/supabase-js#684 (comment)
To summarize:

  • The getClaims() function allow to check the session and its validity, but
    • it only returns the session content and not the user (although a getUser() call is actually executed, I could expect the function to return session AND user data at the same time).
    • MFA verification requires session data (aal) and user data (factors list) in the current state, i'll have to do another getUser() which mean more wait time and double request for the same purpose.
  • I could call getUser() manually and reimplement the JWT parsing myself, but that should be handled by the library; manual implementations are prone to error.

Expected behavior

I expect the getAuthenticatorAssuranceLevel() function to work in the context of the edge function.
What I could expect :

  • The function could have an optional argument to directly give the jwt session (like the getUser()function already have)
    Image
  • The supabase client could store the jwt session in memory within an edge function contexte allowing getSession() and getAuthenticatorAssuranceLevel() to work properly

System information

  • Version of supabase CLI: 2.22.6
  • supabase-edge-runtime-1.67.2

Additional context

Discussion of the subject on another issue:
supabase/supabase-js#684 (comment)

Thank you for your help!

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions