feat(oauth): ARIA kann Provider selbst registrieren + Custom-Provider in Diagnostic & App
ARIA hat jetzt das META-Tool oauth_register_provider. Wenn Stefan einen Service nutzen will, der nicht in den (auf Spotify reduzierten) Defaults ist, kann sie auth_url/token_url/scopes/client_auth selbst eintragen — ARIA kennt typische OAuth-Endpunkte (Dropbox, Discord, Notion, Slack, Zoom, Trello, LinkedIn, Reddit, Twitch) aus ihrem Training. Sie traegt NUR die URLs ein, client_id/secret bleiben Stefans Job (Diagnostic / App-UI) — bewusste Trennung damit Credentials nicht im Chat-Verlauf landen. DEFAULT_PROVIDERS auf Spotify reduziert — Rest war aktuell ungenutzt und macht den Code unnoetig "groß". ARIA registriert on-demand. Diagnostic-UI: - Custom-Provider zeigen auth_url/token_url/scopes als sichtbare Felder - Defaults verstecken die Felder hinter "Default-URLs ueberschreiben (advanced)" damit man die Spotify-URLs nicht versehentlich loescht - "+ Custom OAuth-Provider hinzufuegen" Button mit Prompts fuer Name/URLs/Scopes - 🗑-Icon bei Custom-Services (Service komplett entfernen) App-UI (neu fuer unterwegs): - Settings → Sektion 🔑 "OAuth-Apps" zwischen Skills und Protokoll - OAuthBrowser-Komponente analog zu Trigger/Skill-Browser: Liste mit Status, Tap → Edit-Modal mit client_id/secret + Advanced-Toggle fuer URLs. "Autorisieren ↗" oeffnet System-Browser via Linking.openURL, redirected zur RVS-Callback-Page, Status-Refresh nach 8s. - "+ Custom"-Button → Full-Screen-Modal fuer Service-Anlage. - brainApi um listOAuthServices/getOAuthApps/saveOAuthApp/ deleteOAuthApp/authorizeOAuth/revokeOAuth erweitert. Workflow ist jetzt: "verbinde mich mit Dropbox" → ARIA registriert Provider → "trag client_id/secret in Settings ein" → Stefan macht das in App oder Diagnostic → "Autorisieren ↗" → fertig. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -121,6 +121,27 @@ export interface Memory {
|
||||
attachments?: MemoryAttachment[];
|
||||
}
|
||||
|
||||
/** OAuth-Service-Status wie aus Brain `/oauth/services` zurueckkommt. */
|
||||
export interface OAuthServiceStatus {
|
||||
service: string;
|
||||
configured: boolean;
|
||||
authenticated: boolean;
|
||||
expiresAt?: number | null;
|
||||
expiresInSec?: number | null;
|
||||
hasRefresh: boolean;
|
||||
scope?: string;
|
||||
isDefault: boolean;
|
||||
}
|
||||
|
||||
/** OAuth-App-Config (client_id/scopes/URLs) — client_secret kommt NIE rausgegeben. */
|
||||
export interface OAuthAppConfig {
|
||||
client_id: string;
|
||||
has_client_secret: boolean;
|
||||
scopes?: string[] | null;
|
||||
auth_url?: string | null;
|
||||
token_url?: string | null;
|
||||
}
|
||||
|
||||
/** Skill-Manifest wie aus Brain `/skills/list` zurueckkommt. */
|
||||
export interface Skill {
|
||||
name: string;
|
||||
@@ -376,6 +397,62 @@ export const brainApi = {
|
||||
getSkillLogs(name: string, limit: number = 20): Promise<any[]> {
|
||||
return _send(`/skills/${encodeURIComponent(name)}/logs?limit=${limit}`);
|
||||
},
|
||||
|
||||
// ── OAuth ────────────────────────────────────────────────────────
|
||||
|
||||
/** Liste aller Services mit Auth-Status (configured/authenticated/expires). */
|
||||
listOAuthServices(): Promise<{ services: OAuthServiceStatus[] }> {
|
||||
return _send('/oauth/services');
|
||||
},
|
||||
|
||||
/** Persistierte Provider-Configs (URLs/scopes/client_id, KEIN client_secret). */
|
||||
getOAuthApps(): Promise<{ apps: Record<string, OAuthAppConfig>; defaults: string[] }> {
|
||||
return _send('/oauth/apps');
|
||||
},
|
||||
|
||||
/** Provider-Config setzen/aktualisieren. Leerer client_secret laesst
|
||||
* den bestehenden Wert stehen. */
|
||||
saveOAuthApp(body: {
|
||||
service: string;
|
||||
client_id?: string;
|
||||
client_secret?: string;
|
||||
scopes?: string[];
|
||||
auth_url?: string;
|
||||
token_url?: string;
|
||||
}): Promise<{ ok: boolean; service: string }> {
|
||||
return _send('/oauth/apps', {
|
||||
method: 'POST',
|
||||
body,
|
||||
timeoutMs: 15000,
|
||||
});
|
||||
},
|
||||
|
||||
/** Service-Eintrag komplett entfernen (incl. Token). */
|
||||
deleteOAuthApp(service: string): Promise<{ ok: boolean }> {
|
||||
return _send(`/oauth/apps/${encodeURIComponent(service)}`, {
|
||||
method: 'DELETE',
|
||||
timeoutMs: 15000,
|
||||
});
|
||||
},
|
||||
|
||||
/** Authorize-URL bauen (Brain speichert state, gibt url + redirect_uri zurueck). */
|
||||
authorizeOAuth(service: string, scopes?: string[]): Promise<{
|
||||
url: string; state: string; redirect_uri: string; service: string;
|
||||
}> {
|
||||
return _send('/oauth/authorize', {
|
||||
method: 'POST',
|
||||
body: { service, scopes },
|
||||
timeoutMs: 15000,
|
||||
});
|
||||
},
|
||||
|
||||
/** Token loeschen (lokal — kein Provider-Revoke). */
|
||||
revokeOAuth(service: string): Promise<{ ok: boolean }> {
|
||||
return _send(`/oauth/${encodeURIComponent(service)}/revoke`, {
|
||||
method: 'POST',
|
||||
timeoutMs: 15000,
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
export default brainApi;
|
||||
|
||||
Reference in New Issue
Block a user