|
| 1 | +-- app.settings.jwt_secret has been removed, see https://github.com/orgs/supabase/discussions/30606 |
| 2 | +-- now we fetch the secret from vault. The redeem_access_token function is the same as before |
| 3 | +-- (see file 20230906110845_access_token.sql) except the part where we fetch the jwt_secret. |
| 4 | +create or replace function public.redeem_access_token( |
| 5 | + access_token text |
| 6 | +) |
| 7 | + returns text |
| 8 | + language plpgsql |
| 9 | + security definer |
| 10 | + strict |
| 11 | +as $$ |
| 12 | +declare |
| 13 | + token_id uuid; |
| 14 | + token bytea; |
| 15 | + tokens_row app.user_id_and_token_hash; |
| 16 | + token_valid boolean; |
| 17 | + now timestamp; |
| 18 | + one_hour_from_now timestamp; |
| 19 | + issued_at int; |
| 20 | + expiry_at int; |
| 21 | + jwt_secret text; |
| 22 | +begin |
| 23 | + -- validate access token |
| 24 | + if length(access_token) != 64 then |
| 25 | + raise exception 'Invalid token'; |
| 26 | + end if; |
| 27 | + |
| 28 | + if substring(access_token from 1 for 4) != 'dbd_' then |
| 29 | + raise exception 'Invalid token'; |
| 30 | + end if; |
| 31 | + |
| 32 | + token_id := substring(access_token from 5 for 32)::uuid; |
| 33 | + token := app.base64url_decode(substring(access_token from 37)); |
| 34 | + |
| 35 | + select t.user_id, t.token_hash |
| 36 | + into tokens_row |
| 37 | + from app.access_tokens t |
| 38 | + where t.id = token_id; |
| 39 | + |
| 40 | + -- TODO: do a constant time comparison |
| 41 | + if tokens_row.token_hash != sha256(token) then |
| 42 | + raise exception 'Invalid token'; |
| 43 | + end if; |
| 44 | + |
| 45 | + -- Generate JWT token |
| 46 | + now := current_timestamp; |
| 47 | + one_hour_from_now := now + interval '1 hour'; |
| 48 | + issued_at := date_part('epoch', now); |
| 49 | + expiry_at := date_part('epoch', one_hour_from_now); |
| 50 | + |
| 51 | + -- read the jwt secret from vault |
| 52 | + select decrypted_secret |
| 53 | + into jwt_secret |
| 54 | + from vault.decrypted_secrets |
| 55 | + where name = 'app.jwt_secret'; |
| 56 | + |
| 57 | + return sign(json_build_object( |
| 58 | + 'aud', 'authenticated', |
| 59 | + 'role', 'authenticated', |
| 60 | + 'iss', 'database.dev', |
| 61 | + 'sub', tokens_row.user_id, |
| 62 | + 'iat', issued_at, |
| 63 | + 'exp', expiry_at |
| 64 | + ), jwt_secret); |
| 65 | +end; |
| 66 | +$$; |
0 commit comments