feat(makelore): add platform oidc login

This commit is contained in:
brother7 committed 2026-10-10 17:29:33 +08:00
1 parent 87d3f03d75
commit 7236def07d
12 files changed
+528 -10

No files matched your search

+8 -1
View File
@@ -284,7 +284,14 @@ function App() {
useEffect(() => {
const unsubscribe = subscribeHostEvent('auth:session-changed', (session) => {
useAuthStore.getState().applyMainSession(session);
const auth = useAuthStore.getState();
auth.applyMainSession(session);
// A platform OIDC callback is committed by Main and only carries the
// session credentials. Reload the current account so the renderer gets
// the stable username and module permissions before routing.
if (session) {
void auth.init().catch(() => undefined);
}
});
return unsubscribe;
}, []);
+36
View File
@@ -6,6 +6,7 @@ import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { hostApiFetch } from '@/lib/host-api';
import { invokeIpc } from '@/lib/api-client';
import { useAuthStore } from '@/stores/auth';
import { useProviderStore } from '@/stores/providers';
import logoSvg from '@/assets/logo.svg';
@@ -307,6 +308,30 @@ export function Login() {
}
};
const handlePlatformLogin = async () => {
if (!agreed || busy) return;
setSubmitError(null);
setSubmitting(true);
try {
const response = await hostApiFetch<{
success?: unknown;
authorizationUrl?: unknown;
}>('/api/auth/platform/start', {
method: 'POST',
cache: 'no-store',
body: JSON.stringify({}),
});
if (response.success !== true) throw new Error('平台登录暂时不可用,请稍后重试。');
const authorizationUrl = getSafeExternalUrl(response.authorizationUrl);
if (!authorizationUrl) throw new Error('平台登录地址无效,请稍后重试。');
await invokeIpc('shell:openExternal', authorizationUrl);
} catch (loginError) {
setSubmitError(loginError instanceof Error ? loginError.message : String(loginError));
} finally {
setSubmitting(false);
}
};
const handleSendCode = async () => {
if (
sendingCode
@@ -464,6 +489,17 @@ export function Login() {
</form>
)}
<Button
type="button"
variant="outline"
className="w-full"
disabled={!agreed || busy}
onClick={() => void handlePlatformLogin()}
>
{submitting && <Loader2 className="mr-2 h-4 w-4 animate-spin" />}
平台账号登录
</Button>
<label className="flex items-start gap-2 text-xs leading-5 text-muted-foreground">
<input type="checkbox" className="mt-1" checked={agreed} onChange={(event) => setAgreed(event.target.checked)} />
<span>