fix(desktop): harden session, meeting, caption and LLM lifecycles; route LLM calls through the gateway
This commit is contained in:
parent
3a46437f28
commit
ddc78546f0
62 changed files with 4786 additions and 648 deletions
24
apps/mobile-rn/__tests__/logout-scope-redteam-r2-1.test.ts
Normal file
24
apps/mobile-rn/__tests__/logout-scope-redteam-r2-1.test.ts
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
// 로그아웃은 이 기기의 세션만 폐기한다(scope 'local').
|
||||
// 기본값 'global' 은 계정의 모든 refresh token 을 폐기해 데스크톱까지 로그아웃시켰다.
|
||||
const mockSignOut = jest.fn()
|
||||
|
||||
jest.mock('../src/lib/supabase', () => ({
|
||||
supabase: {
|
||||
auth: {
|
||||
signOut: (...args: unknown[]) => mockSignOut(...args),
|
||||
},
|
||||
},
|
||||
}))
|
||||
|
||||
import { signOutWithLocalFallback } from '../src/lib/logout'
|
||||
|
||||
describe('per-device logout scope', () => {
|
||||
beforeEach(() => jest.clearAllMocks())
|
||||
|
||||
test('revokes only this device session, never the whole account', async () => {
|
||||
mockSignOut.mockResolvedValue({ error: null })
|
||||
await signOutWithLocalFallback(jest.fn(async () => undefined))
|
||||
expect(mockSignOut).toHaveBeenCalledTimes(1)
|
||||
expect(mockSignOut).toHaveBeenCalledWith({ scope: 'local' })
|
||||
})
|
||||
})
|
||||
|
|
@ -8,13 +8,17 @@ export interface LocalLogoutResult {
|
|||
* Attempts server-side refresh-token revocation first, then always performs
|
||||
* the caller's local secure purge. A network outage must not trap a user in a
|
||||
* signed-in device or leave a reusable refresh token in local storage.
|
||||
*
|
||||
* Only this device's session is revoked (scope 'local'). The auth client's
|
||||
* default scope is 'global', which revoked every refresh token of the account
|
||||
* and silently signed the user out of their desktops as well.
|
||||
*/
|
||||
export async function signOutWithLocalFallback(
|
||||
purgeLocalSession: () => Promise<void>,
|
||||
): Promise<LocalLogoutResult> {
|
||||
let remoteRevocationConfirmed = false
|
||||
try {
|
||||
const { error } = await supabase.auth.signOut()
|
||||
const { error } = await supabase.auth.signOut({ scope: 'local' })
|
||||
remoteRevocationConfirmed = error === null
|
||||
} catch {
|
||||
remoteRevocationConfirmed = false
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue