-
-
Notifications
You must be signed in to change notification settings - Fork 185
Description
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 likepersistSession: 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.
- it only returns the session content and not the user (although a
- 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)
- The supabase client could store the jwt session in memory within an edge function contexte allowing
getSession()
andgetAuthenticatorAssuranceLevel()
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!