When autologin is rejected the panel offers '휴대폰으로 로그인 (QR)'. It opens a 5-minute LAN relay to the launcher UI guarded by a one-time token (first phone to open the QR URL is the only client allowed) and shows the URL as a QR code. The relay closes as soon as a new session appears, on cancel, on expiry, and on unload. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
31 lines
952 B
TypeScript
31 lines
952 B
TypeScript
import { callable } from "@decky/api";
|
|
|
|
export type Phase = "off" | "connecting" | "on" | "error" | "missing";
|
|
|
|
export interface NodeInfo {
|
|
sid: number;
|
|
label: string;
|
|
rtt: number | null;
|
|
}
|
|
|
|
export interface VpnState {
|
|
phase: Phase;
|
|
message: string | null;
|
|
node_mode: "auto" | "manual";
|
|
node: NodeInfo | null;
|
|
ip: string | null;
|
|
country: string | null;
|
|
connected_since: number | null;
|
|
tunnel: boolean;
|
|
need_login: boolean;
|
|
login: { url: string; expires_at: number } | null;
|
|
}
|
|
|
|
export const getState = callable<[], VpnState>("get_state");
|
|
export const connect = callable<[], VpnState>("connect");
|
|
export const disconnect = callable<[], VpnState>("disconnect");
|
|
export const setNode = callable<[choice: string], VpnState>("set_node");
|
|
export const listNodes = callable<[], NodeInfo[]>("list_nodes");
|
|
export const startLogin = callable<[], VpnState>("start_login");
|
|
export const stopLogin = callable<[], VpnState>("stop_login");
|