Skip to content

Comments

fix(frontend): require confirmation before URL login session#1688

Merged
riderx merged 11 commits intomainfrom
riderx/fix-login-url-tokens
Feb 25, 2026
Merged

fix(frontend): require confirmation before URL login session#1688
riderx merged 11 commits intomainfrom
riderx/fix-login-url-tokens

Conversation

@riderx
Copy link
Member

@riderx riderx commented Feb 24, 2026

Summary (AI generated)

  • Prevent automatic login from /login query tokens by requiring explicit user confirmation before setting a session.
  • Remove access_token and refresh_token from the query string after they are detected.
  • Add confirmation, accept, and decline flow in src/pages/login.vue for query-token session sign-in.

Motivation (AI generated)

The previous behavior authenticated automatically when access_token and refresh_token were present in /login URL query parameters, enabling login CSRF/session-fixation and accidental forced sign-ins from crafted links.

Business Impact (AI generated)

  • Improves account security for console sign-in flows.
  • Prevents users from being involuntarily signed into attacker-controlled sessions.
  • Reduces token exposure in URLs (history/logs/refs) by clearing query params immediately.

Test Plan (AI generated)

  • bun lint src/pages/login.vue
  • Open /login?access_token=...&refresh_token=... and verify the confirmation prompt appears before sign-in.
  • Confirm URL no longer contains access_token and refresh_token after page load.
  • Verify Continue sets the session and proceeds to dashboard flow.
  • Verify Cancel keeps you on login and does not set the session.
  • Verify normal /login path is unchanged when no query session tokens are present.

Generated with AI

Summary by CodeRabbit

  • New Features
    • Session authentication now includes a confirmation step when tokens are provided via URL
    • Users can explicitly accept or decline external session setup through a new prompt with Continue and Cancel options during login

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 24, 2026

Warning

Rate limit exceeded

@riderx has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 24 minutes and 31 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 7ed011a and bdbbb57.

📒 Files selected for processing (8)
  • package.json
  • src/pages/admin/dashboard/replication.vue
  • supabase/functions/_backend/files/preview.ts
  • supabase/functions/_backend/public/build/index.ts
  • supabase/functions/_backend/public/replication.ts
  • supabase/functions/_backend/utils/version.ts
  • supabase/migrations/20260224100000_fix_webhook_rls_org_scoping.sql
  • tests/build-upload-head-routing.test.ts
📝 Walkthrough

Walkthrough

A single-file change adds session-passing via URL tokens to the login page. The implementation introduces a deferred two-step authentication flow: tokens are extracted from the URL and stored temporarily, displaying a prompt to the user; accepting the prompt triggers session setup via Supabase; declining clears stored tokens and returns to the original login form.

Changes

Cohort / File(s) Summary
Session Token Query Flow
src/pages/login.vue
Introduces reactive refs for storing URL-passed access/refresh tokens and a session flag. Adds acceptQuerySession() to authenticate stored tokens via Supabase and declineQuerySession() to clear tokens. Modifies UI conditionally to show accept/cancel prompt when query tokens are present, replacing immediate authentication with deferred processing.

Sequence Diagram(s)

sequenceDiagram
    actor User
    participant LoginComponent as Login Component
    participant SupabaseAuth as Supabase Auth

    User->>LoginComponent: Arrive with token in URL
    activate LoginComponent
    LoginComponent->>LoginComponent: Parse & store tokens<br/>(querySessionAccessToken,<br/>querySessionRefreshToken)<br/>Set hasQuerySession=true
    LoginComponent->>LoginComponent: Remove tokens from URL
    deactivate LoginComponent
    
    LoginComponent->>User: Display "Accept/Cancel" prompt

    alt User Accepts
        User->>LoginComponent: Click Accept
        activate LoginComponent
        LoginComponent->>SupabaseAuth: setSession(stored tokens)
        activate SupabaseAuth
        SupabaseAuth-->>LoginComponent: Success
        deactivate SupabaseAuth
        LoginComponent->>LoginComponent: Clear stored tokens<br/>Set hasQuerySession=false
        deactivate LoginComponent
        LoginComponent->>User: Proceed to next login step
    else User Declines
        User->>LoginComponent: Click Cancel
        activate LoginComponent
        LoginComponent->>LoginComponent: Clear tokens & flags<br/>Hide loader
        deactivate LoginComponent
        LoginComponent->>User: Show original login form
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

Tokens hop through URLs, seeking safe ground,
A prompt greets the traveler, decisions abound,
Accept or decline, the choice now yours,
Supabase awaits beyond the doors,
Two steps, one session, the dance refined—
Let the rabbit guide what Fate designed! 🐰✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Description check ❓ Inconclusive The description includes AI-generated Summary, Motivation, Business Impact, and Test Plan sections covering the changes, but does not follow the repository's required template structure with proper section organization. Restructure to match the template: reorganize content under the required sections (Summary, Test plan, Screenshots, Checklist), use proper checkboxes for the checklist items, and clearly document manual testing steps.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main change: requiring user confirmation before URL-based session login, which directly addresses the security vulnerability in the changeset.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch riderx/fix-login-url-tokens

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: fa82fb8143

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines 306 to 309
hasQuerySession.value = false
querySessionAccessToken.value = ''
querySessionRefreshToken.value = ''
if (res.error) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve query session tokens until setSession succeeds

Clearing hasQuerySession and both stored tokens before checking res.error makes transient setSession failures unrecoverable in this tab. Because the URL tokens were already removed in checkLogin, any temporary network/backend error after clicking Continue drops the only remaining credentials and forces the user to request a brand-new login link instead of retrying. Keep these values until setSession succeeds (or the user explicitly cancels) so a retry is possible.

Useful? React with 👍 / 👎.

riderx and others added 4 commits February 24, 2026 23:27
* fix(build): handle tus HEAD upload route

* fix(build): chain HEAD middleware correctly
* fix(security): protect replication endpoint

* fix(api): require replication endpoint internal api secret

* fix(api): allow admin JWT access to replication endpoint

* fix(frontend): use admin session only when no replication secret
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
src/pages/login.vue (1)

370-379: Use DaisyUI button styles for the new interactive controls.

For consistency with project UI conventions, switch these new actions to DaisyUI button classes/components.

As per coding guidelines, src/**/*.vue should "Use DaisyUI components (d-btn, d-input, d-card) for interactive elements in Vue components".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/pages/login.vue` around lines 370 - 379, Replace the raw <button>
elements for the Continue and decline actions with DaisyUI button components
(use d-btn) so they follow project conventions; locate the elements that call
acceptQuerySession and declineQuerySession and swap them to <d-btn> instances,
transferring attributes like type and click handlers
(`@click`="acceptQuerySession" / `@click`="declineQuerySession"), mapping visual
styles to appropriate DaisyUI props/classes (e.g., primary/outline or variant
props) and ensuring v-if="!isLoading" and any accessibility attributes remain;
keep any custom classes that are still needed only if they don’t conflict with
d-btn styling and ensure the dark-mode/hover states are expressed via DaisyUI
variants rather than raw utility classes.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/pages/login.vue`:
- Around line 300-309: In acceptQuerySession(), when supabase.auth.setSession
returns res.error, stop only logging to console and show a user-facing error
notification (e.g., use your app's toast/notify helper) that includes
res.error.message (or res.error) so the user knows Continue failed; ensure you
still set isLoading.value = false and return after showing the toast. Target the
error handling block that currently does console.error('Cannot set auth',
res.error) and replace/augment it with a call to the app's toast function
(passing a clear message and the error text) before returning.
- Around line 365-381: The confirmation prompt and button labels inside the
hasQuerySession block are hardcoded English; replace them with localized strings
using the app's i18n method (e.g., this.$t or useI18n/t) so the prompt text and
the three button labels ("Continue", "Cancel", and the paragraph) use
translation keys; update the template where hasQuerySession is rendered and
ensure acceptQuerySession and declineQuerySession still handle clicks while
referencing the new translation keys (and keep the isLoading condition
unchanged).

---

Nitpick comments:
In `@src/pages/login.vue`:
- Around line 370-379: Replace the raw <button> elements for the Continue and
decline actions with DaisyUI button components (use d-btn) so they follow
project conventions; locate the elements that call acceptQuerySession and
declineQuerySession and swap them to <d-btn> instances, transferring attributes
like type and click handlers (`@click`="acceptQuerySession" /
`@click`="declineQuerySession"), mapping visual styles to appropriate DaisyUI
props/classes (e.g., primary/outline or variant props) and ensuring
v-if="!isLoading" and any accessibility attributes remain; keep any custom
classes that are still needed only if they don’t conflict with d-btn styling and
ensure the dark-mode/hover states are expressed via DaisyUI variants rather than
raw utility classes.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 38ce641 and 7ed011a.

📒 Files selected for processing (1)
  • src/pages/login.vue

Comment on lines +300 to +309
async function acceptQuerySession() {
isLoading.value = true
const res = await supabase.auth.setSession({
access_token: querySessionAccessToken.value,
refresh_token: querySessionRefreshToken.value,
})
if (res.error) {
console.error('Cannot set auth', res.error)
isLoading.value = false
return
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Show a user-facing error when query-session setup fails.

On setSession failure, the flow only logs to console. Please surface a toast/error so users know why Continue did not work.

💡 Suggested patch
 async function acceptQuerySession() {
   isLoading.value = true
   const res = await supabase.auth.setSession({
     access_token: querySessionAccessToken.value,
     refresh_token: querySessionRefreshToken.value,
   })
   if (res.error) {
     console.error('Cannot set auth', res.error)
+    toast.error(t('invalid-auth'))
     isLoading.value = false
     return
   }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
async function acceptQuerySession() {
isLoading.value = true
const res = await supabase.auth.setSession({
access_token: querySessionAccessToken.value,
refresh_token: querySessionRefreshToken.value,
})
if (res.error) {
console.error('Cannot set auth', res.error)
isLoading.value = false
return
async function acceptQuerySession() {
isLoading.value = true
const res = await supabase.auth.setSession({
access_token: querySessionAccessToken.value,
refresh_token: querySessionRefreshToken.value,
})
if (res.error) {
console.error('Cannot set auth', res.error)
toast.error(t('invalid-auth'))
isLoading.value = false
return
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/pages/login.vue` around lines 300 - 309, In acceptQuerySession(), when
supabase.auth.setSession returns res.error, stop only logging to console and
show a user-facing error notification (e.g., use your app's toast/notify helper)
that includes res.error.message (or res.error) so the user knows Continue
failed; ensure you still set isLoading.value = false and return after showing
the toast. Target the error handling block that currently does
console.error('Cannot set auth', res.error) and replace/augment it with a call
to the app's toast function (passing a clear message and the error text) before
returning.

Comment on lines +365 to +381
<div v-if="hasQuerySession" class="overflow-hidden bg-white rounded-md shadow-md dark:bg-slate-800">
<div class="py-6 px-4 space-y-4 text-gray-500 sm:py-7 sm:px-8">
<p class="text-sm">
This link contains a login session. Continue to sign in with this session?
</p>
<button
v-if="!isLoading" type="button" data-test="accept-query-session"
class="inline-flex justify-center items-center py-4 px-4 w-full text-base font-semibold text-white rounded-md transition-all duration-200 hover:bg-blue-700 focus:bg-blue-700 bg-muted-blue-700 focus:outline-hidden"
@click="acceptQuerySession"
>
Continue
</button>
<button
v-if="!isLoading" type="button" class="inline-flex justify-center items-center py-4 px-4 w-full text-base font-semibold text-slate-700 rounded-md border border-slate-300 transition-all duration-200 hover:bg-slate-50 dark:text-slate-200 dark:border-slate-600 dark:hover:bg-slate-700"
@click="declineQuerySession"
>
Cancel
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Localize the new confirmation copy.

The prompt and button labels are hardcoded English, which bypasses locale support in this page.

🌐 Suggested patch
-            <p class="text-sm">
-              This link contains a login session. Continue to sign in with this session?
-            </p>
+            <p class="text-sm">
+              {{ t('query-session-confirmation') }}
+            </p>
...
-              Continue
+              {{ t('continue') }}
...
-              Cancel
+              {{ t('cancel') }}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<div v-if="hasQuerySession" class="overflow-hidden bg-white rounded-md shadow-md dark:bg-slate-800">
<div class="py-6 px-4 space-y-4 text-gray-500 sm:py-7 sm:px-8">
<p class="text-sm">
This link contains a login session. Continue to sign in with this session?
</p>
<button
v-if="!isLoading" type="button" data-test="accept-query-session"
class="inline-flex justify-center items-center py-4 px-4 w-full text-base font-semibold text-white rounded-md transition-all duration-200 hover:bg-blue-700 focus:bg-blue-700 bg-muted-blue-700 focus:outline-hidden"
@click="acceptQuerySession"
>
Continue
</button>
<button
v-if="!isLoading" type="button" class="inline-flex justify-center items-center py-4 px-4 w-full text-base font-semibold text-slate-700 rounded-md border border-slate-300 transition-all duration-200 hover:bg-slate-50 dark:text-slate-200 dark:border-slate-600 dark:hover:bg-slate-700"
@click="declineQuerySession"
>
Cancel
<div v-if="hasQuerySession" class="overflow-hidden bg-white rounded-md shadow-md dark:bg-slate-800">
<div class="py-6 px-4 space-y-4 text-gray-500 sm:py-7 sm:px-8">
<p class="text-sm">
{{ t('query-session-confirmation') }}
</p>
<button
v-if="!isLoading" type="button" data-test="accept-query-session"
class="inline-flex justify-center items-center py-4 px-4 w-full text-base font-semibold text-white rounded-md transition-all duration-200 hover:bg-blue-700 focus:bg-blue-700 bg-muted-blue-700 focus:outline-hidden"
`@click`="acceptQuerySession"
>
{{ t('continue') }}
</button>
<button
v-if="!isLoading" type="button" class="inline-flex justify-center items-center py-4 px-4 w-full text-base font-semibold text-slate-700 rounded-md border border-slate-300 transition-all duration-200 hover:bg-slate-50 dark:text-slate-200 dark:border-slate-600 dark:hover:bg-slate-700"
`@click`="declineQuerySession"
>
{{ t('cancel') }}
</button>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/pages/login.vue` around lines 365 - 381, The confirmation prompt and
button labels inside the hasQuerySession block are hardcoded English; replace
them with localized strings using the app's i18n method (e.g., this.$t or
useI18n/t) so the prompt text and the three button labels ("Continue", "Cancel",
and the paragraph) use translation keys; update the template where
hasQuerySession is rendered and ensure acceptQuerySession and
declineQuerySession still handle clicks while referencing the new translation
keys (and keep the isLoading condition unchanged).

@sonarqubecloud
Copy link

@riderx riderx merged commit c006d1c into main Feb 25, 2026
14 checks passed
@riderx riderx deleted the riderx/fix-login-url-tokens branch February 25, 2026 02:16
riderx added a commit that referenced this pull request Feb 25, 2026
* fix(security): revoke anon access to exist_app_v2 rpc

* fix(build): restore TUS HEAD upload routing (#1664)

* fix(build): handle tus HEAD upload route

* fix(build): chain HEAD middleware correctly

* chore(release): 12.116.2

* fix(security): protect replication endpoint (#1686)

* fix(security): protect replication endpoint

* fix(api): require replication endpoint internal api secret

* fix(api): allow admin JWT access to replication endpoint

* fix(frontend): use admin session only when no replication secret

* fix(security): revoke PUBLIC execute on exist_app_v2 rpc

* fix(security): revoke anon execute on exist_app_v2 rpc

* fix(database): enforce org-scoped webhook rls (#1676)

* fix: use exact app_id match for preview lookup (#1674)

* fix(backend): use exact app_id match for preview lookup

* fix(backend): preserve case-insensitive preview app lookup

* chore(release): 12.116.3

* fix(security): revoke anon access to exist_app_v2 rpc

* fix(security): revoke PUBLIC execute on exist_app_v2 rpc

* fix(security): revoke anon execute on exist_app_v2 rpc

* fix(frontend): require confirmation before URL login session (#1688)

* fix(frontend): require confirmation for URL session login

* fix(build): restore TUS HEAD upload routing (#1664)

* fix(build): handle tus HEAD upload route

* fix(build): chain HEAD middleware correctly

* chore(release): 12.116.2

* fix(security): protect replication endpoint (#1686)

* fix(security): protect replication endpoint

* fix(api): require replication endpoint internal api secret

* fix(api): allow admin JWT access to replication endpoint

* fix(frontend): use admin session only when no replication secret

* fix(frontend): retain tokens until query login succeeds

* fix(database): enforce org-scoped webhook rls (#1676)

* fix: use exact app_id match for preview lookup (#1674)

* fix(backend): use exact app_id match for preview lookup

* fix(backend): preserve case-insensitive preview app lookup

* chore(release): 12.116.3

* fix(frontend): require confirmation for URL session login

* fix(frontend): retain tokens until query login succeeds

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>

* chore(release): 12.116.4

* Riderx/fix email otp rpc reopen (#1693)

* fix(security): restrict email otp verification rpc path

* fix(security): also revoke otp rpc execute from public

* fix(security): record email otp verification via service-side rpc

* fix(security): harden email otp verification RPC usage

* fix(db): drop legacy record_email_otp_verified overload

* fix(frontend): delete replaced profile images from storage (#1683)

* fix(frontend): delete replaced profile images from storage

* fix(backend): clean stale unlinked user avatars

* fix(build): restore TUS HEAD upload routing (#1664)

* fix(build): handle tus HEAD upload route

* fix(build): chain HEAD middleware correctly

* chore(release): 12.116.2

* fix(security): protect replication endpoint (#1686)

* fix(security): protect replication endpoint

* fix(api): require replication endpoint internal api secret

* fix(api): allow admin JWT access to replication endpoint

* fix(frontend): use admin session only when no replication secret

* fix: address sonar regex exec suggestions

* fix(database): enforce org-scoped webhook rls (#1676)

* fix: use exact app_id match for preview lookup (#1674)

* fix(backend): use exact app_id match for preview lookup

* fix(backend): preserve case-insensitive preview app lookup

* chore(release): 12.116.3

* fix(frontend): delete replaced profile images from storage

* fix(backend): clean stale unlinked user avatars

* fix: address sonar regex exec suggestions

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>

* fix: restrict find_apikey_by_value RPC to service role (#1672)

* fix(security): restrict find_apikey_by_value to service role

* fix(build): restore TUS HEAD upload routing (#1664)

* fix(build): handle tus HEAD upload route

* fix(build): chain HEAD middleware correctly

* chore(release): 12.116.2

* fix(security): protect replication endpoint (#1686)

* fix(security): protect replication endpoint

* fix(api): require replication endpoint internal api secret

* fix(api): allow admin JWT access to replication endpoint

* fix(frontend): use admin session only when no replication secret

* fix(database): enforce org-scoped webhook rls (#1676)

* fix: use exact app_id match for preview lookup (#1674)

* fix(backend): use exact app_id match for preview lookup

* fix(backend): preserve case-insensitive preview app lookup

* chore(release): 12.116.3

* fix(security): restrict find_apikey_by_value to service role

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>

* fix: secure get_total_metrics rpc (#1671)

* fix(db): harden get_total_metrics rpc auth

* fix(db): qualify org_id and harden rpc role checks

* fix(db): align get_total_metrics auth overloads

* fix(db): harden get_total_metrics rpc auth

* fix(db): qualify org_id and harden rpc role checks

* fix(db): align get_total_metrics auth overloads

* fix(db): harden get_total_metrics rpc auth

* fix(db): qualify org_id and harden rpc role checks

* fix(db): align get_total_metrics auth overloads

* fix(backend): validate stripe redirect URLs (#1681)

* fix(backend): validate stripe redirect URLs

* fix(build): restore TUS HEAD upload routing (#1664)

* fix(build): handle tus HEAD upload route

* fix(build): chain HEAD middleware correctly

* chore(release): 12.116.2

* fix(security): protect replication endpoint (#1686)

* fix(security): protect replication endpoint

* fix(api): require replication endpoint internal api secret

* fix(api): allow admin JWT access to replication endpoint

* fix(frontend): use admin session only when no replication secret

* test(backend): add stripe redirect validation tests

* test(backend): fix stripe redirect unit test env setup

* fix(database): enforce org-scoped webhook rls (#1676)

* fix: use exact app_id match for preview lookup (#1674)

* fix(backend): use exact app_id match for preview lookup

* fix(backend): preserve case-insensitive preview app lookup

* chore(release): 12.116.3

* fix(backend): validate stripe redirect URLs

* test(backend): add stripe redirect validation tests

* test(backend): fix stripe redirect unit test env setup

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>

* feat(api): auto cleanup EXIF image metadata (#1673)

* feat(api): auto cleanup image metadata on updates

* fix: preserve content type when stripping image metadata

* fix(security): restrict get_orgs_v6(userid uuid) access (#1677)

* fix(security): restrict get_orgs_v6(uuid) execution to private roles

* fix(build): restore TUS HEAD upload routing (#1664)

* fix(build): handle tus HEAD upload route

* fix(build): chain HEAD middleware correctly

* chore(release): 12.116.2

* fix(security): protect replication endpoint (#1686)

* fix(security): protect replication endpoint

* fix(api): require replication endpoint internal api secret

* fix(api): allow admin JWT access to replication endpoint

* fix(frontend): use admin session only when no replication secret

* fix(database): enforce org-scoped webhook rls (#1676)

* fix: use exact app_id match for preview lookup (#1674)

* fix(backend): use exact app_id match for preview lookup

* fix(backend): preserve case-insensitive preview app lookup

* chore(release): 12.116.3

* fix(security): restrict get_orgs_v6(uuid) execution to private roles

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>

* fix(security): revoke anon access to apikey oracle RPCs (#1670)

* fix(security): restrict apikey oracle rpc execution

* fix(build): restore TUS HEAD upload routing (#1664)

* fix(build): handle tus HEAD upload route

* fix(build): chain HEAD middleware correctly

* chore(release): 12.116.2

* fix(security): protect replication endpoint (#1686)

* fix(security): protect replication endpoint

* fix(api): require replication endpoint internal api secret

* fix(api): allow admin JWT access to replication endpoint

* fix(frontend): use admin session only when no replication secret

* fix: remove anon-backed get_user_id calls in private apikey flows

* fix(database): enforce org-scoped webhook rls (#1676)

* fix: use exact app_id match for preview lookup (#1674)

* fix(backend): use exact app_id match for preview lookup

* fix(backend): preserve case-insensitive preview app lookup

* chore(release): 12.116.3

* fix(security): restrict apikey oracle rpc execution

* fix: remove anon-backed get_user_id calls in private apikey flows

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>

* fix(security): require capgkey auth in exist_app_v2

* fix(api): block scoped apikey key creation (#1685)

* fix(api): block scoped apikeys from creating keys

* fix(build): restore TUS HEAD upload routing (#1664)

* fix(build): handle tus HEAD upload route

* fix(build): chain HEAD middleware correctly

* chore(release): 12.116.2

* fix(security): protect replication endpoint (#1686)

* fix(security): protect replication endpoint

* fix(api): require replication endpoint internal api secret

* fix(api): allow admin JWT access to replication endpoint

* fix(frontend): use admin session only when no replication secret

* fix(database): enforce org-scoped webhook rls (#1676)

* test: fix apikey test lint violations

* fix: use exact app_id match for preview lookup (#1674)

* fix(backend): use exact app_id match for preview lookup

* fix(backend): preserve case-insensitive preview app lookup

* chore(release): 12.116.3

* fix(api): block scoped apikeys from creating keys

* test: fix apikey test lint violations

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>

* fix: restrict webhook secret access to admin-only (#1692)

* fix(security): restrict webhook secret read access

* fix(rls): restrict webhook reads to admins

* fix(security): keep only apikey-based exist_app_v2 check

* fix(security): require capgkey auth in exist_app_v2

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant