@davidwoods/skylight-mcp 0.0.0-stage → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +22 -0
- package/README.md +583 -2
- package/THIRD_PARTY_NOTICES.md +38 -0
- package/dist/api/auth.d.ts +34 -0
- package/dist/api/auth.d.ts.map +1 -0
- package/dist/api/auth.js +328 -0
- package/dist/api/auth.js.map +1 -0
- package/dist/api/client.d.ts +103 -0
- package/dist/api/client.d.ts.map +1 -0
- package/dist/api/client.js +324 -0
- package/dist/api/client.js.map +1 -0
- package/dist/api/constants.d.ts +4 -0
- package/dist/api/constants.d.ts.map +1 -0
- package/dist/api/constants.js +4 -0
- package/dist/api/constants.js.map +1 -0
- package/dist/api/credential-store.d.ts +38 -0
- package/dist/api/credential-store.d.ts.map +1 -0
- package/dist/api/credential-store.js +273 -0
- package/dist/api/credential-store.js.map +1 -0
- package/dist/api/credential-types.d.ts +15 -0
- package/dist/api/credential-types.d.ts.map +1 -0
- package/dist/api/credential-types.js +11 -0
- package/dist/api/credential-types.js.map +1 -0
- package/dist/api/endpoints/calendar.d.ts +36 -0
- package/dist/api/endpoints/calendar.d.ts.map +1 -0
- package/dist/api/endpoints/calendar.js +74 -0
- package/dist/api/endpoints/calendar.js.map +1 -0
- package/dist/api/endpoints/categories.d.ts +32 -0
- package/dist/api/endpoints/categories.d.ts.map +1 -0
- package/dist/api/endpoints/categories.js +77 -0
- package/dist/api/endpoints/categories.js.map +1 -0
- package/dist/api/endpoints/chores.d.ts +50 -0
- package/dist/api/endpoints/chores.d.ts.map +1 -0
- package/dist/api/endpoints/chores.js +106 -0
- package/dist/api/endpoints/chores.js.map +1 -0
- package/dist/api/endpoints/devices.d.ts +6 -0
- package/dist/api/endpoints/devices.d.ts.map +1 -0
- package/dist/api/endpoints/devices.js +10 -0
- package/dist/api/endpoints/devices.js.map +1 -0
- package/dist/api/endpoints/frames.d.ts +6 -0
- package/dist/api/endpoints/frames.d.ts.map +1 -0
- package/dist/api/endpoints/frames.js +10 -0
- package/dist/api/endpoints/frames.js.map +1 -0
- package/dist/api/endpoints/lists.d.ts +55 -0
- package/dist/api/endpoints/lists.d.ts.map +1 -0
- package/dist/api/endpoints/lists.js +125 -0
- package/dist/api/endpoints/lists.js.map +1 -0
- package/dist/api/endpoints/meals.d.ts +154 -0
- package/dist/api/endpoints/meals.d.ts.map +1 -0
- package/dist/api/endpoints/meals.js +194 -0
- package/dist/api/endpoints/meals.js.map +1 -0
- package/dist/api/endpoints/messages.d.ts +98 -0
- package/dist/api/endpoints/messages.d.ts.map +1 -0
- package/dist/api/endpoints/messages.js +116 -0
- package/dist/api/endpoints/messages.js.map +1 -0
- package/dist/api/endpoints/misc.d.ts +27 -0
- package/dist/api/endpoints/misc.d.ts.map +1 -0
- package/dist/api/endpoints/misc.js +19 -0
- package/dist/api/endpoints/misc.js.map +1 -0
- package/dist/api/endpoints/photos.d.ts +13 -0
- package/dist/api/endpoints/photos.d.ts.map +1 -0
- package/dist/api/endpoints/photos.js +10 -0
- package/dist/api/endpoints/photos.js.map +1 -0
- package/dist/api/endpoints/rewards.d.ts +49 -0
- package/dist/api/endpoints/rewards.d.ts.map +1 -0
- package/dist/api/endpoints/rewards.js +106 -0
- package/dist/api/endpoints/rewards.js.map +1 -0
- package/dist/api/endpoints/shape.d.ts +11 -0
- package/dist/api/endpoints/shape.d.ts.map +1 -0
- package/dist/api/endpoints/shape.js +34 -0
- package/dist/api/endpoints/shape.js.map +1 -0
- package/dist/api/endpoints/taskbox.d.ts +13 -0
- package/dist/api/endpoints/taskbox.d.ts.map +1 -0
- package/dist/api/endpoints/taskbox.js +22 -0
- package/dist/api/endpoints/taskbox.js.map +1 -0
- package/dist/api/oauth.d.ts +62 -0
- package/dist/api/oauth.d.ts.map +1 -0
- package/dist/api/oauth.js +206 -0
- package/dist/api/oauth.js.map +1 -0
- package/dist/api/types.d.ts +277 -0
- package/dist/api/types.d.ts.map +1 -0
- package/dist/api/types.js +5 -0
- package/dist/api/types.js.map +1 -0
- package/dist/cli.d.ts +23 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +105 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +27 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +78 -0
- package/dist/config.js.map +1 -0
- package/dist/context.d.ts +17 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +17 -0
- package/dist/context.js.map +1 -0
- package/dist/doctor.d.ts +19 -0
- package/dist/doctor.d.ts.map +1 -0
- package/dist/doctor.js +109 -0
- package/dist/doctor.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -0
- package/dist/server.d.ts +7 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +29 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/calendar.d.ts +3 -0
- package/dist/tools/calendar.d.ts.map +1 -0
- package/dist/tools/calendar.js +298 -0
- package/dist/tools/calendar.js.map +1 -0
- package/dist/tools/chores.d.ts +3 -0
- package/dist/tools/chores.d.ts.map +1 -0
- package/dist/tools/chores.js +349 -0
- package/dist/tools/chores.js.map +1 -0
- package/dist/tools/family.d.ts +3 -0
- package/dist/tools/family.d.ts.map +1 -0
- package/dist/tools/family.js +182 -0
- package/dist/tools/family.js.map +1 -0
- package/dist/tools/lists.d.ts +3 -0
- package/dist/tools/lists.d.ts.map +1 -0
- package/dist/tools/lists.js +481 -0
- package/dist/tools/lists.js.map +1 -0
- package/dist/tools/meals.d.ts +3 -0
- package/dist/tools/meals.d.ts.map +1 -0
- package/dist/tools/meals.js +491 -0
- package/dist/tools/meals.js.map +1 -0
- package/dist/tools/messages.d.ts +3 -0
- package/dist/tools/messages.d.ts.map +1 -0
- package/dist/tools/messages.js +195 -0
- package/dist/tools/messages.js.map +1 -0
- package/dist/tools/misc.d.ts +3 -0
- package/dist/tools/misc.d.ts.map +1 -0
- package/dist/tools/misc.js +102 -0
- package/dist/tools/misc.js.map +1 -0
- package/dist/tools/photos.d.ts +3 -0
- package/dist/tools/photos.d.ts.map +1 -0
- package/dist/tools/photos.js +42 -0
- package/dist/tools/photos.js.map +1 -0
- package/dist/tools/planning.d.ts +15 -0
- package/dist/tools/planning.d.ts.map +1 -0
- package/dist/tools/planning.js +303 -0
- package/dist/tools/planning.js.map +1 -0
- package/dist/tools/registry.d.ts +39 -0
- package/dist/tools/registry.d.ts.map +1 -0
- package/dist/tools/registry.js +142 -0
- package/dist/tools/registry.js.map +1 -0
- package/dist/tools/rewards.d.ts +3 -0
- package/dist/tools/rewards.d.ts.map +1 -0
- package/dist/tools/rewards.js +339 -0
- package/dist/tools/rewards.js.map +1 -0
- package/dist/tools/tasks.d.ts +3 -0
- package/dist/tools/tasks.d.ts.map +1 -0
- package/dist/tools/tasks.js +68 -0
- package/dist/tools/tasks.js.map +1 -0
- package/dist/utils/dates.d.ts +26 -0
- package/dist/utils/dates.d.ts.map +1 -0
- package/dist/utils/dates.js +109 -0
- package/dist/utils/dates.js.map +1 -0
- package/dist/utils/errors.d.ts +45 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +102 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/schedule.d.ts +86 -0
- package/dist/utils/schedule.d.ts.map +1 -0
- package/dist/utils/schedule.js +189 -0
- package/dist/utils/schedule.js.map +1 -0
- package/package.json +76 -4
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Skylight Authentication
|
|
3
|
+
* Handles the browser-style OAuth login flow used by Skylight web.
|
|
4
|
+
*/
|
|
5
|
+
export interface OAuthTokenResponse {
|
|
6
|
+
access_token?: string;
|
|
7
|
+
token?: string;
|
|
8
|
+
token_type?: string;
|
|
9
|
+
scope?: string;
|
|
10
|
+
refresh_token?: string;
|
|
11
|
+
expires_in?: number;
|
|
12
|
+
created_at?: number;
|
|
13
|
+
[key: string]: unknown;
|
|
14
|
+
}
|
|
15
|
+
export interface AuthResult {
|
|
16
|
+
email: string;
|
|
17
|
+
token: string;
|
|
18
|
+
subscriptionStatus: string | null;
|
|
19
|
+
}
|
|
20
|
+
export declare function detectSubscriptionStatus(token: string): Promise<string | null>;
|
|
21
|
+
/**
|
|
22
|
+
* Login to Skylight with email and password.
|
|
23
|
+
* Replays the same browser OAuth flow observed from Skylight web.
|
|
24
|
+
*/
|
|
25
|
+
export declare function login(email: string, password: string): Promise<AuthResult>;
|
|
26
|
+
/**
|
|
27
|
+
* Get cached auth result or login if needed
|
|
28
|
+
*/
|
|
29
|
+
export declare function getAuth(email: string, password: string): Promise<AuthResult>;
|
|
30
|
+
/**
|
|
31
|
+
* Clear cached auth (for re-login)
|
|
32
|
+
*/
|
|
33
|
+
export declare function clearAuthCache(): void;
|
|
34
|
+
//# sourceMappingURL=auth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/api/auth.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAUH,MAAM,WAAW,kBAAkB;IACjC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;CACnC;AA2TD,wBAAsB,wBAAwB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CA0CpF;AAED;;;GAGG;AACH,wBAAsB,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAwBhF;AAKD;;GAEG;AACH,wBAAsB,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAOlF;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,IAAI,CAErC"}
|
package/dist/api/auth.js
ADDED
|
@@ -0,0 +1,328 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Skylight Authentication
|
|
3
|
+
* Handles the browser-style OAuth login flow used by Skylight web.
|
|
4
|
+
*/
|
|
5
|
+
import { createHash, randomUUID } from "node:crypto";
|
|
6
|
+
import { SKYLIGHT_API_VERSION, SKYLIGHT_BASE_URL, SKYLIGHT_WEB_APP_URL } from "./constants.js";
|
|
7
|
+
const REDIRECT_URI = `${SKYLIGHT_WEB_APP_URL}/welcome`;
|
|
8
|
+
const CLIENT_ID = "skylight-mobile";
|
|
9
|
+
const SCOPE = "everything";
|
|
10
|
+
const WEB_USER_AGENT = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:149.0) Gecko/20100101 Firefox/149.0";
|
|
11
|
+
class CookieJar {
|
|
12
|
+
cookies = new Map();
|
|
13
|
+
setFromResponse(response) {
|
|
14
|
+
const headerValues = typeof response.headers.getSetCookie === "function"
|
|
15
|
+
? response.headers.getSetCookie().flatMap((headerValue) => splitSetCookieHeader(headerValue))
|
|
16
|
+
: splitSetCookieHeader(response.headers.get("set-cookie"));
|
|
17
|
+
for (const header of headerValues) {
|
|
18
|
+
const [cookiePair] = header.split(";", 1);
|
|
19
|
+
const separatorIndex = cookiePair.indexOf("=");
|
|
20
|
+
if (separatorIndex <= 0) {
|
|
21
|
+
continue;
|
|
22
|
+
}
|
|
23
|
+
const name = cookiePair.slice(0, separatorIndex).trim();
|
|
24
|
+
const value = cookiePair.slice(separatorIndex + 1).trim();
|
|
25
|
+
if (name && value) {
|
|
26
|
+
this.cookies.set(name, value);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
toHeader() {
|
|
31
|
+
if (this.cookies.size === 0) {
|
|
32
|
+
return undefined;
|
|
33
|
+
}
|
|
34
|
+
return Array.from(this.cookies.entries())
|
|
35
|
+
.map(([name, value]) => `${name}=${value}`)
|
|
36
|
+
.join("; ");
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
function splitSetCookieHeader(headerValue) {
|
|
40
|
+
if (!headerValue) {
|
|
41
|
+
return [];
|
|
42
|
+
}
|
|
43
|
+
const cookies = [];
|
|
44
|
+
let current = "";
|
|
45
|
+
let inExpiresAttribute = false;
|
|
46
|
+
for (let index = 0; index < headerValue.length; index += 1) {
|
|
47
|
+
const char = headerValue[index];
|
|
48
|
+
const remainingHeader = headerValue.slice(index).toLowerCase();
|
|
49
|
+
if (!inExpiresAttribute && remainingHeader.startsWith("expires=")) {
|
|
50
|
+
inExpiresAttribute = true;
|
|
51
|
+
}
|
|
52
|
+
if (char === "," && !inExpiresAttribute) {
|
|
53
|
+
cookies.push(current.trim());
|
|
54
|
+
current = "";
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
if (inExpiresAttribute && char === ";") {
|
|
58
|
+
inExpiresAttribute = false;
|
|
59
|
+
}
|
|
60
|
+
current += char;
|
|
61
|
+
}
|
|
62
|
+
if (current.trim()) {
|
|
63
|
+
cookies.push(current.trim());
|
|
64
|
+
}
|
|
65
|
+
return cookies;
|
|
66
|
+
}
|
|
67
|
+
function createPkceVerifier() {
|
|
68
|
+
return randomUUID().replace(/-/g, "") + randomUUID().replace(/-/g, "");
|
|
69
|
+
}
|
|
70
|
+
function createPkceChallenge(verifier) {
|
|
71
|
+
return createHash("sha256").update(verifier).digest("base64url");
|
|
72
|
+
}
|
|
73
|
+
function createState() {
|
|
74
|
+
return randomUUID().replace(/-/g, "").slice(0, 10);
|
|
75
|
+
}
|
|
76
|
+
function buildAuthorizeUrl(params) {
|
|
77
|
+
const url = new URL("/oauth/authorize", SKYLIGHT_BASE_URL);
|
|
78
|
+
url.searchParams.set("client_id", CLIENT_ID);
|
|
79
|
+
url.searchParams.set("code_challenge", params.codeChallenge);
|
|
80
|
+
url.searchParams.set("code_challenge_method", "S256");
|
|
81
|
+
url.searchParams.set("redirect_uri", REDIRECT_URI);
|
|
82
|
+
url.searchParams.set("response_type", "code");
|
|
83
|
+
url.searchParams.set("scope", SCOPE);
|
|
84
|
+
url.searchParams.set("state", params.state);
|
|
85
|
+
if (params.prompt) {
|
|
86
|
+
url.searchParams.set("prompt", params.prompt);
|
|
87
|
+
}
|
|
88
|
+
return url.toString();
|
|
89
|
+
}
|
|
90
|
+
function parseAuthenticityToken(html) {
|
|
91
|
+
const match = html.match(/name=["']authenticity_token["'][^>]*value=["']([^"']+)["']/i);
|
|
92
|
+
if (!match) {
|
|
93
|
+
throw new Error("Could not find authenticity token in Skylight login form");
|
|
94
|
+
}
|
|
95
|
+
return match[1];
|
|
96
|
+
}
|
|
97
|
+
function parseAuthorizationCode(location, expectedState) {
|
|
98
|
+
const url = new URL(location);
|
|
99
|
+
const state = url.searchParams.get("state");
|
|
100
|
+
const code = url.searchParams.get("code");
|
|
101
|
+
if (!code) {
|
|
102
|
+
throw new Error("OAuth redirect did not include an authorization code");
|
|
103
|
+
}
|
|
104
|
+
if (state !== expectedState) {
|
|
105
|
+
throw new Error("OAuth state mismatch during Skylight login");
|
|
106
|
+
}
|
|
107
|
+
return code;
|
|
108
|
+
}
|
|
109
|
+
function getDeviceMetadata() {
|
|
110
|
+
const platform = process.platform === "darwin" ? "Macintosh" :
|
|
111
|
+
process.platform === "win32" ? "Windows" :
|
|
112
|
+
process.platform === "linux" ? "Linux" :
|
|
113
|
+
process.platform;
|
|
114
|
+
return {
|
|
115
|
+
skylight_api_client_device_fingerprint: randomUUID(),
|
|
116
|
+
skylight_api_client_device_platform: "web",
|
|
117
|
+
skylight_api_client_device_name: "unknown",
|
|
118
|
+
skylight_api_client_device_os_version: "unknown",
|
|
119
|
+
skylight_api_client_device_app_version: "unknown",
|
|
120
|
+
skylight_api_client_device_hardware: platform,
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
async function fetchWithCookies(url, init, cookieJar) {
|
|
124
|
+
const headers = new Headers(init.headers);
|
|
125
|
+
const cookieHeader = cookieJar.toHeader();
|
|
126
|
+
if (cookieHeader) {
|
|
127
|
+
headers.set("Cookie", cookieHeader);
|
|
128
|
+
}
|
|
129
|
+
const response = await fetch(url, {
|
|
130
|
+
...init,
|
|
131
|
+
headers,
|
|
132
|
+
redirect: "manual",
|
|
133
|
+
});
|
|
134
|
+
cookieJar.setFromResponse(response);
|
|
135
|
+
return response;
|
|
136
|
+
}
|
|
137
|
+
async function beginOAuthFlow(state, codeChallenge, cookieJar) {
|
|
138
|
+
const response = await fetchWithCookies(buildAuthorizeUrl({ state, codeChallenge, prompt: "login" }), {
|
|
139
|
+
method: "GET",
|
|
140
|
+
headers: {
|
|
141
|
+
Accept: "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
|
|
142
|
+
"User-Agent": WEB_USER_AGENT,
|
|
143
|
+
Referer: `${SKYLIGHT_WEB_APP_URL}/`,
|
|
144
|
+
},
|
|
145
|
+
}, cookieJar);
|
|
146
|
+
const location = response.headers.get("location");
|
|
147
|
+
if (response.status !== 302 || !location) {
|
|
148
|
+
response.body?.cancel();
|
|
149
|
+
throw new Error(`Unexpected authorize response: HTTP ${response.status}`);
|
|
150
|
+
}
|
|
151
|
+
response.body?.cancel();
|
|
152
|
+
return new URL(location).toString();
|
|
153
|
+
}
|
|
154
|
+
async function loadLoginForm(loginUrl, cookieJar) {
|
|
155
|
+
const response = await fetchWithCookies(loginUrl, {
|
|
156
|
+
method: "GET",
|
|
157
|
+
headers: {
|
|
158
|
+
Accept: "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
|
|
159
|
+
"User-Agent": WEB_USER_AGENT,
|
|
160
|
+
Referer: `${SKYLIGHT_WEB_APP_URL}/`,
|
|
161
|
+
},
|
|
162
|
+
}, cookieJar);
|
|
163
|
+
if (!response.ok) {
|
|
164
|
+
response.body?.cancel();
|
|
165
|
+
throw new Error(`Failed to load Skylight login form: HTTP ${response.status}`);
|
|
166
|
+
}
|
|
167
|
+
return response.text();
|
|
168
|
+
}
|
|
169
|
+
async function submitLoginForm(email, password, authenticityToken, cookieJar) {
|
|
170
|
+
const body = new URLSearchParams({
|
|
171
|
+
authenticity_token: authenticityToken,
|
|
172
|
+
email,
|
|
173
|
+
password,
|
|
174
|
+
});
|
|
175
|
+
const response = await fetchWithCookies(`${SKYLIGHT_BASE_URL}/auth/session`, {
|
|
176
|
+
method: "POST",
|
|
177
|
+
headers: {
|
|
178
|
+
Accept: "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
|
|
179
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
180
|
+
Origin: SKYLIGHT_BASE_URL,
|
|
181
|
+
Referer: `${SKYLIGHT_BASE_URL}/auth/session/new`,
|
|
182
|
+
"User-Agent": WEB_USER_AGENT,
|
|
183
|
+
},
|
|
184
|
+
body,
|
|
185
|
+
}, cookieJar);
|
|
186
|
+
const location = response.headers.get("location");
|
|
187
|
+
if (response.status === 302 && location) {
|
|
188
|
+
response.body?.cancel();
|
|
189
|
+
return new URL(location, SKYLIGHT_BASE_URL).toString();
|
|
190
|
+
}
|
|
191
|
+
const errorBody = await response.text();
|
|
192
|
+
if (response.status === 401 || response.status === 422) {
|
|
193
|
+
throw new Error("Invalid email or password. Please check your SKYLIGHT_EMAIL and SKYLIGHT_PASSWORD environment variables.");
|
|
194
|
+
}
|
|
195
|
+
throw new Error(`Skylight login form submission failed: HTTP ${response.status}${errorBody ? ` - ${errorBody.slice(0, 200)}` : ""}`);
|
|
196
|
+
}
|
|
197
|
+
async function authorizeAuthenticatedSession(authorizeUrl, cookieJar) {
|
|
198
|
+
const response = await fetchWithCookies(authorizeUrl, {
|
|
199
|
+
method: "GET",
|
|
200
|
+
headers: {
|
|
201
|
+
Accept: "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
|
|
202
|
+
Referer: `${SKYLIGHT_BASE_URL}/auth/session/new`,
|
|
203
|
+
"User-Agent": WEB_USER_AGENT,
|
|
204
|
+
},
|
|
205
|
+
}, cookieJar);
|
|
206
|
+
const location = response.headers.get("location");
|
|
207
|
+
if (response.status !== 302 || !location) {
|
|
208
|
+
response.body?.cancel();
|
|
209
|
+
throw new Error(`Unexpected post-login authorize response: HTTP ${response.status}`);
|
|
210
|
+
}
|
|
211
|
+
response.body?.cancel();
|
|
212
|
+
return location;
|
|
213
|
+
}
|
|
214
|
+
async function exchangeAuthorizationCode(code, codeVerifier) {
|
|
215
|
+
const tokenBody = new URLSearchParams({
|
|
216
|
+
grant_type: "authorization_code",
|
|
217
|
+
client_id: CLIENT_ID,
|
|
218
|
+
scope: SCOPE,
|
|
219
|
+
redirect_uri: REDIRECT_URI,
|
|
220
|
+
code,
|
|
221
|
+
code_verifier: codeVerifier,
|
|
222
|
+
...getDeviceMetadata(),
|
|
223
|
+
});
|
|
224
|
+
const response = await fetch(`${SKYLIGHT_BASE_URL}/oauth/token`, {
|
|
225
|
+
method: "POST",
|
|
226
|
+
headers: {
|
|
227
|
+
Accept: "application/json, text/javascript; q=0.01",
|
|
228
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
229
|
+
Origin: SKYLIGHT_WEB_APP_URL,
|
|
230
|
+
Referer: `${SKYLIGHT_WEB_APP_URL}/`,
|
|
231
|
+
"User-Agent": WEB_USER_AGENT,
|
|
232
|
+
},
|
|
233
|
+
body: tokenBody,
|
|
234
|
+
});
|
|
235
|
+
if (!response.ok) {
|
|
236
|
+
const errorBody = await response.text();
|
|
237
|
+
throw new Error(`OAuth token exchange failed: HTTP ${response.status}${errorBody ? ` - ${errorBody.slice(0, 200)}` : ""}`);
|
|
238
|
+
}
|
|
239
|
+
const data = (await response.json());
|
|
240
|
+
const token = data.access_token ?? data.token;
|
|
241
|
+
if (!token) {
|
|
242
|
+
throw new Error("OAuth token exchange did not return an access token");
|
|
243
|
+
}
|
|
244
|
+
return token;
|
|
245
|
+
}
|
|
246
|
+
export async function detectSubscriptionStatus(token) {
|
|
247
|
+
try {
|
|
248
|
+
const response = await fetch(`${SKYLIGHT_BASE_URL}/api/plus_access`, {
|
|
249
|
+
method: "GET",
|
|
250
|
+
headers: {
|
|
251
|
+
Accept: "application/json",
|
|
252
|
+
Authorization: `Bearer ${token}`,
|
|
253
|
+
Origin: SKYLIGHT_WEB_APP_URL,
|
|
254
|
+
Referer: `${SKYLIGHT_WEB_APP_URL}/`,
|
|
255
|
+
"Skylight-Api-Version": SKYLIGHT_API_VERSION,
|
|
256
|
+
"User-Agent": "SkylightMobile (web)",
|
|
257
|
+
},
|
|
258
|
+
});
|
|
259
|
+
if (response.status === 401 || response.status === 403 || response.status === 404) {
|
|
260
|
+
response.body?.cancel();
|
|
261
|
+
return "free";
|
|
262
|
+
}
|
|
263
|
+
if (!response.ok) {
|
|
264
|
+
response.body?.cancel();
|
|
265
|
+
return null;
|
|
266
|
+
}
|
|
267
|
+
const rawBody = await response.text();
|
|
268
|
+
if (!rawBody.trim()) {
|
|
269
|
+
return "plus";
|
|
270
|
+
}
|
|
271
|
+
const body = JSON.parse(rawBody);
|
|
272
|
+
const text = JSON.stringify(body).toLowerCase();
|
|
273
|
+
if (text.includes("\"subscription_status\":\"plus\"") || text.includes("\"plus\":true") || text.includes("\"has_access\":true")) {
|
|
274
|
+
return "plus";
|
|
275
|
+
}
|
|
276
|
+
if (text.includes("\"subscription_status\":\"free\"") || text.includes("\"plus\":false") || text.includes("\"has_access\":false")) {
|
|
277
|
+
return "free";
|
|
278
|
+
}
|
|
279
|
+
return "plus";
|
|
280
|
+
}
|
|
281
|
+
catch {
|
|
282
|
+
return null;
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* Login to Skylight with email and password.
|
|
287
|
+
* Replays the same browser OAuth flow observed from Skylight web.
|
|
288
|
+
*/
|
|
289
|
+
export async function login(email, password) {
|
|
290
|
+
console.error("[auth] Starting OAuth login.");
|
|
291
|
+
const cookieJar = new CookieJar();
|
|
292
|
+
const state = createState();
|
|
293
|
+
const codeVerifier = createPkceVerifier();
|
|
294
|
+
const codeChallenge = createPkceChallenge(codeVerifier);
|
|
295
|
+
const loginUrl = await beginOAuthFlow(state, codeChallenge, cookieJar);
|
|
296
|
+
const loginHtml = await loadLoginForm(loginUrl, cookieJar);
|
|
297
|
+
const authenticityToken = parseAuthenticityToken(loginHtml);
|
|
298
|
+
const authorizeUrl = await submitLoginForm(email, password, authenticityToken, cookieJar);
|
|
299
|
+
const callbackLocation = await authorizeAuthenticatedSession(authorizeUrl, cookieJar);
|
|
300
|
+
const authorizationCode = parseAuthorizationCode(callbackLocation, state);
|
|
301
|
+
const token = await exchangeAuthorizationCode(authorizationCode, codeVerifier);
|
|
302
|
+
const subscriptionStatus = await detectSubscriptionStatus(token);
|
|
303
|
+
console.error("[auth] OAuth login successful.");
|
|
304
|
+
return {
|
|
305
|
+
email,
|
|
306
|
+
token,
|
|
307
|
+
subscriptionStatus,
|
|
308
|
+
};
|
|
309
|
+
}
|
|
310
|
+
// Cache for auth result
|
|
311
|
+
let cachedAuth = null;
|
|
312
|
+
/**
|
|
313
|
+
* Get cached auth result or login if needed
|
|
314
|
+
*/
|
|
315
|
+
export async function getAuth(email, password) {
|
|
316
|
+
if (cachedAuth) {
|
|
317
|
+
return cachedAuth;
|
|
318
|
+
}
|
|
319
|
+
cachedAuth = await login(email, password);
|
|
320
|
+
return cachedAuth;
|
|
321
|
+
}
|
|
322
|
+
/**
|
|
323
|
+
* Clear cached auth (for re-login)
|
|
324
|
+
*/
|
|
325
|
+
export function clearAuthCache() {
|
|
326
|
+
cachedAuth = null;
|
|
327
|
+
}
|
|
328
|
+
//# sourceMappingURL=auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/api/auth.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { type Config } from "../config.js";
|
|
2
|
+
import { type CredentialStore } from "./credential-types.js";
|
|
3
|
+
/**
|
|
4
|
+
* Skylight subscription status types
|
|
5
|
+
*/
|
|
6
|
+
export type SubscriptionStatus = "plus" | "free" | "trial" | null;
|
|
7
|
+
export interface RequestOptions {
|
|
8
|
+
method?: "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
|
|
9
|
+
params?: Record<string, string | boolean | number | undefined>;
|
|
10
|
+
body?: unknown;
|
|
11
|
+
/** Override Skylight-Api-Version for this request (some resources need a newer one). */
|
|
12
|
+
apiVersion?: string;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Skylight API Client
|
|
16
|
+
* Handles authentication and HTTP requests to the Skylight API
|
|
17
|
+
*/
|
|
18
|
+
export declare class SkylightClient {
|
|
19
|
+
private config;
|
|
20
|
+
private resolvedToken;
|
|
21
|
+
private loginPromise;
|
|
22
|
+
private subscriptionStatus;
|
|
23
|
+
private store;
|
|
24
|
+
private stored;
|
|
25
|
+
private storedLoaded;
|
|
26
|
+
private refreshPromise;
|
|
27
|
+
/**
|
|
28
|
+
* @param store Where the OAuth credential lives. `null` means "no stored
|
|
29
|
+
* credential is available" (hosted mode, where the token arrives in config).
|
|
30
|
+
*/
|
|
31
|
+
constructor(config?: Config, store?: CredentialStore | null);
|
|
32
|
+
private getStore;
|
|
33
|
+
/** Load the stored OAuth credential once. Fails closed if the store is unusable. */
|
|
34
|
+
private loadStored;
|
|
35
|
+
/**
|
|
36
|
+
* Refresh tokens rotate on use, so concurrent refreshes would invalidate each
|
|
37
|
+
* other. Share one in-flight promise, and re-read the store first in case
|
|
38
|
+
* another process already rotated the credential.
|
|
39
|
+
*/
|
|
40
|
+
private refreshStored;
|
|
41
|
+
/**
|
|
42
|
+
* Get the authentication credentials
|
|
43
|
+
* If using email/password auth, will login first
|
|
44
|
+
*/
|
|
45
|
+
private getCredentials;
|
|
46
|
+
/**
|
|
47
|
+
* Perform login and return token and userId
|
|
48
|
+
*/
|
|
49
|
+
private performLogin;
|
|
50
|
+
/**
|
|
51
|
+
* Build the Authorization header
|
|
52
|
+
* Email/password auth now resolves to an OAuth bearer token.
|
|
53
|
+
* Manual token auth still respects the configured auth type.
|
|
54
|
+
*/
|
|
55
|
+
private getAuthHeader;
|
|
56
|
+
/**
|
|
57
|
+
* Build URL with query parameters
|
|
58
|
+
*/
|
|
59
|
+
private buildUrl;
|
|
60
|
+
/**
|
|
61
|
+
* Handle API response errors
|
|
62
|
+
*/
|
|
63
|
+
private handleResponseError;
|
|
64
|
+
/**
|
|
65
|
+
* Make an authenticated request to the Skylight API
|
|
66
|
+
*/
|
|
67
|
+
request<T>(endpoint: string, options?: RequestOptions, isRetry?: boolean): Promise<T>;
|
|
68
|
+
/**
|
|
69
|
+
* GET request helper
|
|
70
|
+
*/
|
|
71
|
+
get<T>(endpoint: string, params?: Record<string, string | boolean | number | undefined>): Promise<T>;
|
|
72
|
+
/**
|
|
73
|
+
* POST request helper
|
|
74
|
+
*/
|
|
75
|
+
post<T>(endpoint: string, body: unknown): Promise<T>;
|
|
76
|
+
/**
|
|
77
|
+
* Get the frame ID from config
|
|
78
|
+
*/
|
|
79
|
+
get frameId(): string;
|
|
80
|
+
/**
|
|
81
|
+
* Get the timezone from config
|
|
82
|
+
*/
|
|
83
|
+
get timezone(): string;
|
|
84
|
+
/**
|
|
85
|
+
* Check if user has Plus subscription
|
|
86
|
+
*/
|
|
87
|
+
hasPlus(): boolean;
|
|
88
|
+
/**
|
|
89
|
+
* Get the subscription status
|
|
90
|
+
*/
|
|
91
|
+
getSubscriptionStatus(): SubscriptionStatus;
|
|
92
|
+
/**
|
|
93
|
+
* Initialize the client (triggers login if using email/password auth)
|
|
94
|
+
*/
|
|
95
|
+
initialize(): Promise<void>;
|
|
96
|
+
}
|
|
97
|
+
export declare function getClient(): SkylightClient;
|
|
98
|
+
/**
|
|
99
|
+
* Initialize the process-wide client and return it.
|
|
100
|
+
* Resolves credentials (and logs in, for the deprecated email/password path).
|
|
101
|
+
*/
|
|
102
|
+
export declare function initializeClient(config?: Config, store?: CredentialStore | null): Promise<SkylightClient>;
|
|
103
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/api/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,KAAK,MAAM,EAAE,MAAM,cAAc,CAAC;AAGrE,OAAO,EAAwB,KAAK,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAUnF;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC;AAElE,MAAM,WAAW,cAAc;IAC7B,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,CAAC;IACrD,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,SAAS,CAAC,CAAC;IAC/D,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,wFAAwF;IACxF,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;GAGG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,aAAa,CAAuB;IAC5C,OAAO,CAAC,YAAY,CAA2C;IAC/D,OAAO,CAAC,kBAAkB,CAA4B;IACtD,OAAO,CAAC,KAAK,CAAyB;IACtC,OAAO,CAAC,MAAM,CAAiC;IAC/C,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,cAAc,CAA0C;IAEhE;;;OAGG;gBACS,MAAM,CAAC,EAAE,MAAM,EAAE,KAAK,GAAE,eAAe,GAAG,IAAW;IAKjE,OAAO,CAAC,QAAQ;IAOhB,oFAAoF;YACtE,UAAU;IAexB;;;;OAIG;IACH,OAAO,CAAC,aAAa;IAkCrB;;;OAGG;YACW,cAAc;IAwC5B;;OAEG;YACW,YAAY;IAa1B;;;;OAIG;YACW,aAAa;IAU3B;;OAEG;IACH,OAAO,CAAC,QAAQ;IAoBhB;;OAEG;YACW,mBAAmB;IAyCjC;;OAEG;IACG,OAAO,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,GAAE,cAAmB,EAAE,OAAO,UAAQ,GAAG,OAAO,CAAC,CAAC,CAAC;IAmD7F;;OAEG;IACG,GAAG,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,SAAS,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAI1G;;OAEG;IACG,IAAI,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC;IAI1D;;OAEG;IACH,IAAI,OAAO,IAAI,MAAM,CAEpB;IAED;;OAEG;IACH,IAAI,QAAQ,IAAI,MAAM,CAErB;IAED;;OAEG;IACH,OAAO,IAAI,OAAO;IAIlB;;OAEG;IACH,qBAAqB,IAAI,kBAAkB;IAI3C;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;CAGlC;AAMD,wBAAgB,SAAS,IAAI,cAAc,CAO1C;AAED;;;GAGG;AACH,wBAAsB,gBAAgB,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,KAAK,GAAE,eAAe,GAAG,IAAW,GAAG,OAAO,CAAC,cAAc,CAAC,CAIrH"}
|