chore: proper auth handling (#65)

Co-authored-by: Shubham Naik <shub@memgpt.ai>
This commit is contained in:
Shubham Naik
2025-11-05 16:35:37 -08:00
committed by GitHub
parent cc73396e7a
commit 58362c9c46
2 changed files with 43 additions and 1 deletions

View File

@@ -140,6 +140,7 @@ export async function refreshAccessToken(
grant_type: "refresh_token",
client_id: OAUTH_CONFIG.clientId,
refresh_token: refreshToken,
refresh_token_mode: "new",
}),
});
@@ -154,6 +155,39 @@ export async function refreshAccessToken(
}
/**
* Revoke a refresh token (logout)
*/
export async function revokeToken(refreshToken: string): Promise<void> {
try {
const response = await fetch(
`${OAUTH_CONFIG.authBaseUrl}/api/oauth/revoke`,
{
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
client_id: OAUTH_CONFIG.clientId,
token: refreshToken,
token_type_hint: "refresh_token",
}),
},
);
// OAuth 2.0 revoke endpoint should return 200 even if token is already invalid
if (!response.ok) {
const error = (await response.json()) as OAuthError;
console.error(
`Warning: Failed to revoke token: ${error.error_description || error.error}`,
);
// Don't throw - we still want to clear local credentials
}
} catch (error) {
console.error("Warning: Failed to revoke token:", error);
// Don't throw - we still want to clear local credentials
}
}
/**
* Validate credentials by checking health endpoint
* Validate credentials by checking an authenticated endpoint
* Uses SDK's agents.list() which requires valid authentication
*/

View File

@@ -669,7 +669,7 @@ export default function App({
kind: "command",
id: cmdId,
input: msg,
output: "Clearing credentials...",
output: "Logging out...",
phase: "running",
});
buffersRef.current.order.push(cmdId);
@@ -680,6 +680,14 @@ export default function App({
try {
const { settingsManager } = await import("../settings-manager");
const currentSettings = settingsManager.getSettings();
// Revoke refresh token on server if we have one
if (currentSettings.refreshToken) {
const { revokeToken } = await import("../auth/oauth");
await revokeToken(currentSettings.refreshToken);
}
// Clear local credentials
const newEnv = { ...currentSettings.env };
delete newEnv.LETTA_API_KEY;
// Note: LETTA_BASE_URL is intentionally NOT deleted from settings