alpic 0.0.0-dev.92ced96 → 0.0.0-dev.936aa4f
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/dist/__tests__/auth.e2e.test.d.ts +1 -0
- package/dist/__tests__/auth.e2e.test.js +129 -0
- package/dist/__tests__/auth.e2e.test.js.map +1 -0
- package/dist/__tests__/deploy.e2e.test.d.ts +1 -0
- package/dist/__tests__/deploy.e2e.test.js +220 -0
- package/dist/__tests__/deploy.e2e.test.js.map +1 -0
- package/dist/__tests__/fixtures/demo-project/index.d.ts +1 -0
- package/dist/__tests__/fixtures/demo-project/index.js +4 -0
- package/dist/__tests__/fixtures/demo-project/index.js.map +1 -0
- package/dist/__tests__/git.e2e.test.d.ts +1 -0
- package/dist/__tests__/git.e2e.test.js +225 -0
- package/dist/__tests__/git.e2e.test.js.map +1 -0
- package/dist/__tests__/mock-server.d.ts +22 -0
- package/dist/__tests__/mock-server.js +461 -0
- package/dist/__tests__/mock-server.js.map +1 -0
- package/dist/__tests__/utils.d.ts +61 -0
- package/dist/__tests__/utils.js +196 -0
- package/dist/__tests__/utils.js.map +1 -0
- package/dist/api.d.ts +4 -0
- package/dist/api.js +20 -0
- package/dist/api.js.map +1 -0
- package/dist/commands/deploy.d.ts +9 -0
- package/dist/commands/deploy.js +83 -0
- package/dist/commands/deploy.js.map +1 -0
- package/dist/commands/git/connect.d.ts +9 -0
- package/dist/commands/git/connect.js +58 -0
- package/dist/commands/git/connect.js.map +1 -0
- package/dist/commands/git/disconnect.d.ts +9 -0
- package/dist/commands/git/disconnect.js +50 -0
- package/dist/commands/git/disconnect.js.map +1 -0
- package/dist/commands/{hello.d.ts → git.d.ts} +1 -1
- package/dist/commands/git.js +17 -0
- package/dist/commands/git.js.map +1 -0
- package/dist/commands/login.d.ts +6 -0
- package/dist/commands/login.js +27 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/logout.d.ts +6 -0
- package/dist/commands/logout.js +20 -0
- package/dist/commands/logout.js.map +1 -0
- package/dist/commands/telemetry/disable.d.ts +5 -0
- package/dist/commands/telemetry/disable.js +14 -0
- package/dist/commands/telemetry/disable.js.map +1 -0
- package/dist/commands/telemetry/enable.d.ts +5 -0
- package/dist/commands/telemetry/enable.js +13 -0
- package/dist/commands/telemetry/enable.js.map +1 -0
- package/dist/commands/telemetry/status.d.ts +5 -0
- package/dist/commands/telemetry/status.js +19 -0
- package/dist/commands/telemetry/status.js.map +1 -0
- package/dist/commands/whoami.d.ts +6 -0
- package/dist/commands/whoami.js +25 -0
- package/dist/commands/whoami.js.map +1 -0
- package/dist/lib/alpic-command.d.ts +4 -0
- package/dist/lib/alpic-command.js +17 -0
- package/dist/lib/alpic-command.js.map +1 -0
- package/dist/lib/archive.d.ts +7 -0
- package/dist/lib/archive.js +55 -0
- package/dist/lib/archive.js.map +1 -0
- package/dist/lib/auth/auth.d.ts +2 -0
- package/dist/lib/auth/auth.js +26 -0
- package/dist/lib/auth/auth.js.map +1 -0
- package/dist/lib/auth/credentials.d.ts +12 -0
- package/dist/lib/auth/credentials.js +29 -0
- package/dist/lib/auth/credentials.js.map +1 -0
- package/dist/lib/auth/oauth/client.d.ts +9 -0
- package/dist/lib/auth/oauth/client.js +37 -0
- package/dist/lib/auth/oauth/client.js.map +1 -0
- package/dist/lib/auth/oauth/constants.d.ts +4 -0
- package/dist/lib/auth/oauth/constants.js +5 -0
- package/dist/lib/auth/oauth/constants.js.map +1 -0
- package/dist/lib/auth/oauth/prepare.d.ts +6 -0
- package/dist/lib/auth/oauth/prepare.js +29 -0
- package/dist/lib/auth/oauth/prepare.js.map +1 -0
- package/dist/lib/auth/oauth/server.d.ts +8 -0
- package/dist/lib/auth/oauth/server.js +107 -0
- package/dist/lib/auth/oauth/server.js.map +1 -0
- package/dist/lib/auth/oauth/token.d.ts +1 -0
- package/dist/lib/auth/oauth/token.js +36 -0
- package/dist/lib/auth/oauth/token.js.map +1 -0
- package/dist/lib/auth/whoami.d.ts +28 -0
- package/dist/lib/auth/whoami.js +34 -0
- package/dist/lib/auth/whoami.js.map +1 -0
- package/dist/lib/config.d.ts +11 -0
- package/dist/lib/config.js +31 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/deployment.d.ts +21 -0
- package/dist/lib/deployment.js +38 -0
- package/dist/lib/deployment.js.map +1 -0
- package/dist/lib/git.d.ts +14 -0
- package/dist/lib/git.js +105 -0
- package/dist/lib/git.js.map +1 -0
- package/dist/lib/global-config.d.ts +9 -0
- package/dist/lib/global-config.js +48 -0
- package/dist/lib/global-config.js.map +1 -0
- package/dist/lib/project.d.ts +67 -0
- package/dist/lib/project.js +285 -0
- package/dist/lib/project.js.map +1 -0
- package/dist/lib/telemetry.d.ts +7 -0
- package/dist/lib/telemetry.js +66 -0
- package/dist/lib/telemetry.js.map +1 -0
- package/dist/lib/upload.d.ts +1 -0
- package/dist/lib/upload.js +14 -0
- package/dist/lib/upload.js.map +1 -0
- package/dist/posthog.d.ts +3 -0
- package/dist/posthog.js +10 -0
- package/dist/posthog.js.map +1 -0
- package/dist/types.d.ts +7 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +29 -6
- package/dist/commands/hello.js +0 -10
- package/dist/commands/hello.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"enable.js","sourceRoot":"","sources":["../../../src/commands/telemetry/enable.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AACtC,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAEpD,MAAM,CAAC,OAAO,OAAO,eAAgB,SAAQ,OAAO;IAClD,MAAM,CAAU,WAAW,GAAG,wCAAwC,CAAC;IAEvE,KAAK,CAAC,GAAG;QACP,MAAM,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;QAClC,UAAU,CAAC,IAAI,CAAC,CAAC;QACjB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,oBAAoB,EAAE,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;QACjF,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,sCAAsC,CAAC,CAAC,CAAC;IAClE,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Command } from "@oclif/core";
|
|
2
|
+
import chalk from "chalk";
|
|
3
|
+
import { getMachineId, isEnabled } from "../../lib/telemetry.js";
|
|
4
|
+
export default class TelemetryStatus extends Command {
|
|
5
|
+
static description = "Show Alpic telemetry settings for this machine";
|
|
6
|
+
async run() {
|
|
7
|
+
await this.parse(TelemetryStatus);
|
|
8
|
+
const enabled = isEnabled();
|
|
9
|
+
console.log(chalk.bold.underline("Alpic Telemetry"));
|
|
10
|
+
console.log();
|
|
11
|
+
console.log("Status:", enabled ? chalk.green.bold("Enabled") : chalk.yellow.bold("Disabled"));
|
|
12
|
+
console.log(chalk.gray("Machine ID:"), getMachineId());
|
|
13
|
+
console.log();
|
|
14
|
+
console.log(chalk.gray("To opt out, run: alpic telemetry disable"));
|
|
15
|
+
console.log(chalk.gray("Or set: ALPIC_TELEMETRY_DISABLED=1"));
|
|
16
|
+
console.log(chalk.gray("Debug mode: ALPIC_TELEMETRY_DEBUG=1"));
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.js","sourceRoot":"","sources":["../../../src/commands/telemetry/status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AACtC,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAEjE,MAAM,CAAC,OAAO,OAAO,eAAgB,SAAQ,OAAO;IAClD,MAAM,CAAU,WAAW,GAAG,gDAAgD,CAAC;IAE/E,KAAK,CAAC,GAAG;QACP,MAAM,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;QAClC,MAAM,OAAO,GAAG,SAAS,EAAE,CAAC;QAC5B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC,CAAC;QACrD,OAAO,CAAC,GAAG,EAAE,CAAC;QACd,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;QAC9F,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,YAAY,EAAE,CAAC,CAAC;QACvD,OAAO,CAAC,GAAG,EAAE,CAAC;QACd,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,0CAA0C,CAAC,CAAC,CAAC;QACpE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,oCAAoC,CAAC,CAAC,CAAC;QAC9D,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,qCAAqC,CAAC,CAAC,CAAC;IACjE,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import * as p from "@clack/prompts";
|
|
2
|
+
import chalk from "chalk";
|
|
3
|
+
import { AlpicCommand } from "../lib/alpic-command.js";
|
|
4
|
+
import { getWhoamiInfo } from "../lib/auth/whoami.js";
|
|
5
|
+
export class Whoami extends AlpicCommand {
|
|
6
|
+
static description = "Show the current Alpic identity (API key or logged-in user)";
|
|
7
|
+
static examples = ["<%= config.bin %> whoami"];
|
|
8
|
+
async run() {
|
|
9
|
+
await this.parse(Whoami);
|
|
10
|
+
p.intro("Reading authentication status…");
|
|
11
|
+
const info = await getWhoamiInfo();
|
|
12
|
+
if (!info) {
|
|
13
|
+
p.cancel("Not logged in. Run `alpic login` or set ALPIC_API_KEY.");
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
if (info.method === "api_key") {
|
|
17
|
+
const msg = `Authenticated via API key — Team: ${chalk.green(info.team?.name ?? "unknown")}`;
|
|
18
|
+
p.outro(msg);
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
const msg = `Authenticated as ${chalk.green(info.name)} (${chalk.cyan(info.email)})`;
|
|
22
|
+
p.outro(msg);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=whoami.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"whoami.js","sourceRoot":"","sources":["../../src/commands/whoami.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,gBAAgB,CAAC;AACpC,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAEtD,MAAM,OAAO,MAAO,SAAQ,YAAY;IACtC,MAAM,CAAU,WAAW,GAAG,6DAA6D,CAAC;IAE5F,MAAM,CAAU,QAAQ,GAAG,CAAC,0BAA0B,CAAC,CAAC;IAExD,KAAK,CAAC,GAAG;QACP,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAEzB,CAAC,CAAC,KAAK,CAAC,gCAAgC,CAAC,CAAC;QAE1C,MAAM,IAAI,GAAG,MAAM,aAAa,EAAE,CAAC;QAEnC,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,CAAC,CAAC,MAAM,CAAC,wDAAwD,CAAC,CAAC;YACnE,OAAO;QACT,CAAC;QAED,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YAC9B,MAAM,GAAG,GAAG,qCAAqC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,IAAI,SAAS,CAAC,EAAE,CAAC;YAC7F,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YACb,OAAO;QACT,CAAC;QAED,MAAM,GAAG,GAAG,oBAAoB,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC;QACrF,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACf,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import * as p from "@clack/prompts";
|
|
2
|
+
import { Command } from "@oclif/core";
|
|
3
|
+
import { ORPCError } from "@orpc/client";
|
|
4
|
+
export class AlpicCommand extends Command {
|
|
5
|
+
async catch(error) {
|
|
6
|
+
if (error instanceof ORPCError) {
|
|
7
|
+
p.cancel(`An error occurred while connecting to Alpic: ${error.message}`);
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
if (error instanceof Error) {
|
|
11
|
+
p.cancel(error.message);
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
p.cancel(String(error));
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=alpic-command.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"alpic-command.js","sourceRoot":"","sources":["../../src/lib/alpic-command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,gBAAgB,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AACtC,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC,MAAM,OAAgB,YAAa,SAAQ,OAAO;IACvC,KAAK,CAAC,KAAK,CAAC,KAAc;QACjC,IAAI,KAAK,YAAY,SAAS,EAAE,CAAC;YAC/B,CAAC,CAAC,MAAM,CAAC,gDAAgD,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;YAC1E,OAAO;QACT,CAAC;QACD,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;YAC3B,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YACxB,OAAO;QACT,CAAC;QACD,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;IAC1B,CAAC;CACF"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export declare function ensureGitAvailable(): void;
|
|
2
|
+
export declare function getGitFiles(deployDir: string): string[];
|
|
3
|
+
export declare function getFilesToPack(deployDir: string): string[];
|
|
4
|
+
export declare function createTarArchive(files: string[], deployDir: string): Promise<{
|
|
5
|
+
tmpDir: string;
|
|
6
|
+
archivePath: string;
|
|
7
|
+
}>;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { execSync } from "node:child_process";
|
|
2
|
+
import { existsSync, mkdtempSync, rmSync } from "node:fs";
|
|
3
|
+
import { tmpdir } from "node:os";
|
|
4
|
+
import { join, resolve } from "node:path";
|
|
5
|
+
import { create as tarCreate } from "tar";
|
|
6
|
+
const GIT_FILES_MAX_BUFFER = 10 * 1024 * 1024;
|
|
7
|
+
function isGitRepository(dir) {
|
|
8
|
+
return existsSync(join(resolve(dir), ".git"));
|
|
9
|
+
}
|
|
10
|
+
export function ensureGitAvailable() {
|
|
11
|
+
try {
|
|
12
|
+
execSync("git --version", { stdio: "ignore" });
|
|
13
|
+
}
|
|
14
|
+
catch {
|
|
15
|
+
throw new Error("Git is required to deploy. Please install git and ensure it is available in your PATH.");
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
export function getGitFiles(deployDir) {
|
|
19
|
+
const dir = resolve(deployDir);
|
|
20
|
+
const output = execSync("git ls-files -z --cached --others --exclude-standard -- .", {
|
|
21
|
+
cwd: dir,
|
|
22
|
+
encoding: "utf8",
|
|
23
|
+
maxBuffer: GIT_FILES_MAX_BUFFER,
|
|
24
|
+
});
|
|
25
|
+
const files = output.split("\0").filter(Boolean);
|
|
26
|
+
if (files.length === 0) {
|
|
27
|
+
throw new Error("No tracked or untracked files found. Ensure you are in a git repository with files to deploy.");
|
|
28
|
+
}
|
|
29
|
+
return files;
|
|
30
|
+
}
|
|
31
|
+
export function getFilesToPack(deployDir) {
|
|
32
|
+
const dir = resolve(deployDir);
|
|
33
|
+
if (isGitRepository(dir)) {
|
|
34
|
+
return getGitFiles(deployDir);
|
|
35
|
+
}
|
|
36
|
+
ensureGitAvailable();
|
|
37
|
+
execSync("git init", { cwd: dir });
|
|
38
|
+
try {
|
|
39
|
+
return getGitFiles(deployDir);
|
|
40
|
+
}
|
|
41
|
+
finally {
|
|
42
|
+
rmSync(join(dir, ".git"), { recursive: true });
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
export async function createTarArchive(files, deployDir) {
|
|
46
|
+
const tmpDir = mkdtempSync(join(tmpdir(), "alpic-deploy-"));
|
|
47
|
+
const archivePath = join(tmpDir, "source.tar.gz");
|
|
48
|
+
await tarCreate({
|
|
49
|
+
gzip: true,
|
|
50
|
+
file: archivePath,
|
|
51
|
+
cwd: deployDir,
|
|
52
|
+
}, files);
|
|
53
|
+
return { tmpDir, archivePath };
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=archive.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"archive.js","sourceRoot":"","sources":["../../src/lib/archive.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAC1D,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,MAAM,IAAI,SAAS,EAAE,MAAM,KAAK,CAAC;AAE1C,MAAM,oBAAoB,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC;AAE9C,SAAS,eAAe,CAAC,GAAW;IAClC,OAAO,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;AAChD,CAAC;AAED,MAAM,UAAU,kBAAkB;IAChC,IAAI,CAAC;QACH,QAAQ,CAAC,eAAe,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;IACjD,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,wFAAwF,CAAC,CAAC;IAC5G,CAAC;AACH,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,SAAiB;IAC3C,MAAM,GAAG,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;IAC/B,MAAM,MAAM,GAAG,QAAQ,CAAC,2DAA2D,EAAE;QACnF,GAAG,EAAE,GAAG;QACR,QAAQ,EAAE,MAAM;QAChB,SAAS,EAAE,oBAAoB;KAChC,CAAC,CAAC;IACH,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACjD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CAAC,+FAA+F,CAAC,CAAC;IACnH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,SAAiB;IAC9C,MAAM,GAAG,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;IAC/B,IAAI,eAAe,CAAC,GAAG,CAAC,EAAE,CAAC;QACzB,OAAO,WAAW,CAAC,SAAS,CAAC,CAAC;IAChC,CAAC;IACD,kBAAkB,EAAE,CAAC;IACrB,QAAQ,CAAC,UAAU,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC;IACnC,IAAI,CAAC;QACH,OAAO,WAAW,CAAC,SAAS,CAAC,CAAC;IAChC,CAAC;YAAS,CAAC;QACT,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACjD,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,KAAe,EAAE,SAAiB;IACvE,MAAM,MAAM,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,eAAe,CAAC,CAAC,CAAC;IAC5D,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IAClD,MAAM,SAAS,CACb;QACE,IAAI,EAAE,IAAI;QACV,IAAI,EAAE,WAAW;QACjB,GAAG,EAAE,SAAS;KACf,EACD,KAAK,CACN,CAAC;IACF,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC;AACjC,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import * as p from "@clack/prompts";
|
|
2
|
+
import { getValidAccessToken } from "./oauth/token.js";
|
|
3
|
+
export async function getApiToken() {
|
|
4
|
+
return process.env.ALPIC_API_KEY ?? getValidAccessToken();
|
|
5
|
+
}
|
|
6
|
+
export async function ensureAuthenticated() {
|
|
7
|
+
const isAuthenticatedViaApiKey = checkApiKey();
|
|
8
|
+
if (isAuthenticatedViaApiKey)
|
|
9
|
+
return true;
|
|
10
|
+
const isAuthenticatedViaOAuth = await checkOAuth();
|
|
11
|
+
if (isAuthenticatedViaOAuth)
|
|
12
|
+
return true;
|
|
13
|
+
p.cancel("Not authenticated. Run `alpic login` or set ALPIC_API_KEY. Get an API key from Team settings in the Alpic dashboard.");
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
function checkApiKey() {
|
|
17
|
+
return process.env.ALPIC_API_KEY !== undefined;
|
|
18
|
+
}
|
|
19
|
+
async function checkOAuth() {
|
|
20
|
+
const token = await getValidAccessToken();
|
|
21
|
+
if (!token) {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
return true;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../../src/lib/auth/auth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,gBAAgB,CAAC;AAEpC,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAEvD,MAAM,CAAC,KAAK,UAAU,WAAW;IAC/B,OAAO,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,mBAAmB,EAAE,CAAC;AAC5D,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mBAAmB;IACvC,MAAM,wBAAwB,GAAG,WAAW,EAAE,CAAC;IAC/C,IAAI,wBAAwB;QAAE,OAAO,IAAI,CAAC;IAC1C,MAAM,uBAAuB,GAAG,MAAM,UAAU,EAAE,CAAC;IACnD,IAAI,uBAAuB;QAAE,OAAO,IAAI,CAAC;IAEzC,CAAC,CAAC,MAAM,CACN,sHAAsH,CACvH,CAAC;IACF,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,WAAW;IAClB,OAAO,OAAO,CAAC,GAAG,CAAC,aAAa,KAAK,SAAS,CAAC;AACjD,CAAC;AACD,KAAK,UAAU,UAAU;IACvB,MAAM,KAAK,GAAG,MAAM,mBAAmB,EAAE,CAAC;IAC1C,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export declare const CREDENTIALS_FILE: string;
|
|
2
|
+
export interface Credentials {
|
|
3
|
+
access_token: string;
|
|
4
|
+
refresh_token?: string;
|
|
5
|
+
expires_at: number;
|
|
6
|
+
scopes?: string[];
|
|
7
|
+
}
|
|
8
|
+
export declare const credentials: {
|
|
9
|
+
load: () => Credentials | null;
|
|
10
|
+
save: (creds: Credentials) => void;
|
|
11
|
+
clear: () => void;
|
|
12
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import XDGAppPaths from "xdg-app-paths";
|
|
4
|
+
const xdgAppPaths = XDGAppPaths({ name: "alpic" });
|
|
5
|
+
const CREDENTIALS_DIR = xdgAppPaths.config();
|
|
6
|
+
export const CREDENTIALS_FILE = join(CREDENTIALS_DIR, "credentials.json");
|
|
7
|
+
export const credentials = {
|
|
8
|
+
load: () => {
|
|
9
|
+
if (!existsSync(CREDENTIALS_FILE)) {
|
|
10
|
+
return null;
|
|
11
|
+
}
|
|
12
|
+
try {
|
|
13
|
+
return JSON.parse(readFileSync(CREDENTIALS_FILE, "utf-8"));
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
save: (creds) => {
|
|
20
|
+
mkdirSync(CREDENTIALS_DIR, { recursive: true });
|
|
21
|
+
writeFileSync(CREDENTIALS_FILE, JSON.stringify(creds, null, 2), { encoding: "utf-8", mode: 0o600 });
|
|
22
|
+
},
|
|
23
|
+
clear: () => {
|
|
24
|
+
if (existsSync(CREDENTIALS_FILE)) {
|
|
25
|
+
unlinkSync(CREDENTIALS_FILE);
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
//# sourceMappingURL=credentials.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credentials.js","sourceRoot":"","sources":["../../../src/lib/auth/credentials.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACzF,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,WAAW,MAAM,eAAe,CAAC;AAExC,MAAM,WAAW,GAAG,WAAW,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;AACnD,MAAM,eAAe,GAAG,WAAW,CAAC,MAAM,EAAE,CAAC;AAC7C,MAAM,CAAC,MAAM,gBAAgB,GAAG,IAAI,CAAC,eAAe,EAAE,kBAAkB,CAAC,CAAC;AAS1E,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,IAAI,EAAE,GAAuB,EAAE;QAC7B,IAAI,CAAC,UAAU,CAAC,gBAAgB,CAAC,EAAE,CAAC;YAClC,OAAO,IAAI,CAAC;QACd,CAAC;QACD,IAAI,CAAC;YACH,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,gBAAgB,EAAE,OAAO,CAAC,CAAgB,CAAC;QAC5E,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IACD,IAAI,EAAE,CAAC,KAAkB,EAAE,EAAE;QAC3B,SAAS,CAAC,eAAe,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAChD,aAAa,CAAC,gBAAgB,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IACtG,CAAC;IACD,KAAK,EAAE,GAAG,EAAE;QACV,IAAI,UAAU,CAAC,gBAAgB,CAAC,EAAE,CAAC;YACjC,UAAU,CAAC,gBAAgB,CAAC,CAAC;QAC/B,CAAC;IACH,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
declare function exchangeAuthorizationCode(code: string, codeVerifier: string): Promise<Response>;
|
|
2
|
+
declare function fetchNewTokens(refreshToken: string): Promise<Response>;
|
|
3
|
+
declare function fetchUserInfo(accessToken: string): Promise<Response>;
|
|
4
|
+
export declare const oauthClient: {
|
|
5
|
+
exchangeAuthorizationCode: typeof exchangeAuthorizationCode;
|
|
6
|
+
fetchNewTokens: typeof fetchNewTokens;
|
|
7
|
+
fetchUserInfo: typeof fetchUserInfo;
|
|
8
|
+
};
|
|
9
|
+
export {};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { COGNITO_CLIENT_ID, COGNITO_URL } from "./constants.js";
|
|
2
|
+
const tokenUrl = new URL("/oauth2/token", COGNITO_URL).href;
|
|
3
|
+
function exchangeAuthorizationCode(code, codeVerifier) {
|
|
4
|
+
return fetch(tokenUrl, {
|
|
5
|
+
method: "POST",
|
|
6
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
7
|
+
body: new URLSearchParams({
|
|
8
|
+
grant_type: "authorization_code",
|
|
9
|
+
client_id: COGNITO_CLIENT_ID,
|
|
10
|
+
code: code,
|
|
11
|
+
code_verifier: codeVerifier,
|
|
12
|
+
}),
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
function fetchNewTokens(refreshToken) {
|
|
16
|
+
return fetch(tokenUrl, {
|
|
17
|
+
method: "POST",
|
|
18
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
19
|
+
body: new URLSearchParams({
|
|
20
|
+
grant_type: "refresh_token",
|
|
21
|
+
client_id: COGNITO_CLIENT_ID,
|
|
22
|
+
refresh_token: refreshToken,
|
|
23
|
+
}),
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
function fetchUserInfo(accessToken) {
|
|
27
|
+
const userInfoUrl = new URL("/oauth2/userInfo", COGNITO_URL).href;
|
|
28
|
+
return fetch(userInfoUrl, {
|
|
29
|
+
headers: { Authorization: `Bearer ${accessToken}` },
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
export const oauthClient = {
|
|
33
|
+
exchangeAuthorizationCode,
|
|
34
|
+
fetchNewTokens,
|
|
35
|
+
fetchUserInfo,
|
|
36
|
+
};
|
|
37
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../../../src/lib/auth/oauth/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAEhE,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,eAAe,EAAE,WAAW,CAAC,CAAC,IAAI,CAAC;AAE5D,SAAS,yBAAyB,CAAC,IAAY,EAAE,YAAoB;IACnE,OAAO,KAAK,CAAC,QAAQ,EAAE;QACrB,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,cAAc,EAAE,mCAAmC,EAAE;QAChE,IAAI,EAAE,IAAI,eAAe,CAAC;YACxB,UAAU,EAAE,oBAAoB;YAChC,SAAS,EAAE,iBAAiB;YAC5B,IAAI,EAAE,IAAI;YACV,aAAa,EAAE,YAAY;SAC5B,CAAC;KACH,CAAC,CAAC;AACL,CAAC;AAED,SAAS,cAAc,CAAC,YAAoB;IAC1C,OAAO,KAAK,CAAC,QAAQ,EAAE;QACrB,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,cAAc,EAAE,mCAAmC,EAAE;QAChE,IAAI,EAAE,IAAI,eAAe,CAAC;YACxB,UAAU,EAAE,eAAe;YAC3B,SAAS,EAAE,iBAAiB;YAC5B,aAAa,EAAE,YAAY;SAC5B,CAAC;KACH,CAAC,CAAC;AACL,CAAC;AAED,SAAS,aAAa,CAAC,WAAmB;IACxC,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,kBAAkB,EAAE,WAAW,CAAC,CAAC,IAAI,CAAC;IAClE,OAAO,KAAK,CAAC,WAAW,EAAE;QACxB,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,WAAW,EAAE,EAAE;KACpD,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,yBAAyB;IACzB,cAAc;IACd,aAAa;CACd,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export const COGNITO_URL = process.env.ALPIC_COGNITO_URL ?? "https://auth.alpic.ai";
|
|
2
|
+
export const COGNITO_CLIENT_ID = process.env.ALPIC_COGNITO_CLIENT_ID ?? "1023dpimab488tfv4sh4bdk2r";
|
|
3
|
+
export const LOOPBACK_HOST = "127.0.0.1";
|
|
4
|
+
export const LOOPBACK_PORT = 38472;
|
|
5
|
+
//# sourceMappingURL=constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../../src/lib/auth/oauth/constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,uBAAuB,CAAC;AACpF,MAAM,CAAC,MAAM,iBAAiB,GAAG,OAAO,CAAC,GAAG,CAAC,uBAAuB,IAAI,2BAA2B,CAAC;AAEpG,MAAM,CAAC,MAAM,aAAa,GAAG,WAAW,CAAC;AACzC,MAAM,CAAC,MAAM,aAAa,GAAG,KAAK,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import crypto from "node:crypto";
|
|
2
|
+
import { COGNITO_CLIENT_ID, COGNITO_URL, LOOPBACK_HOST, LOOPBACK_PORT } from "./constants.js";
|
|
3
|
+
const SCOPES = ["openid", "email", "profile", "aws.cognito.signin.user.admin"];
|
|
4
|
+
const redirectUri = `http://${LOOPBACK_HOST}:${LOOPBACK_PORT}/callback`;
|
|
5
|
+
export function prepareOAuthConfig() {
|
|
6
|
+
const { codeVerifier, codeChallenge } = generatePKCE();
|
|
7
|
+
const state = generateState();
|
|
8
|
+
const baseUrl = COGNITO_URL.replace(/\/$/, "");
|
|
9
|
+
const authorizeUrl = new URL(`${baseUrl}/oauth2/authorize`);
|
|
10
|
+
authorizeUrl.searchParams.set("response_type", "code");
|
|
11
|
+
authorizeUrl.searchParams.set("client_id", COGNITO_CLIENT_ID);
|
|
12
|
+
authorizeUrl.searchParams.set("redirect_uri", redirectUri);
|
|
13
|
+
authorizeUrl.searchParams.set("scope", SCOPES.join(" "));
|
|
14
|
+
authorizeUrl.searchParams.set("state", state);
|
|
15
|
+
authorizeUrl.searchParams.set("code_challenge", codeChallenge);
|
|
16
|
+
authorizeUrl.searchParams.set("code_challenge_method", "S256");
|
|
17
|
+
return { authorizeUrl: authorizeUrl.toString(), codeVerifier, state, redirectUri };
|
|
18
|
+
}
|
|
19
|
+
const BASE64URL_ENCODE = (buf) => buf.toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
20
|
+
function generatePKCE() {
|
|
21
|
+
const codeVerifier = BASE64URL_ENCODE(crypto.randomBytes(32));
|
|
22
|
+
const digest = crypto.createHash("sha256").update(codeVerifier).digest();
|
|
23
|
+
const codeChallenge = BASE64URL_ENCODE(digest);
|
|
24
|
+
return { codeVerifier, codeChallenge };
|
|
25
|
+
}
|
|
26
|
+
function generateState() {
|
|
27
|
+
return BASE64URL_ENCODE(crypto.randomBytes(16));
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=prepare.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prepare.js","sourceRoot":"","sources":["../../../../src/lib/auth/oauth/prepare.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,aAAa,CAAC;AAEjC,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAE9F,MAAM,MAAM,GAAG,CAAC,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,+BAA+B,CAAC,CAAC;AAE/E,MAAM,WAAW,GAAG,UAAU,aAAa,IAAI,aAAa,WAAW,CAAC;AAExE,MAAM,UAAU,kBAAkB;IAChC,MAAM,EAAE,YAAY,EAAE,aAAa,EAAE,GAAG,YAAY,EAAE,CAAC;IACvD,MAAM,KAAK,GAAG,aAAa,EAAE,CAAC;IAE9B,MAAM,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IAC/C,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,GAAG,OAAO,mBAAmB,CAAC,CAAC;IAC5D,YAAY,CAAC,YAAY,CAAC,GAAG,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC;IACvD,YAAY,CAAC,YAAY,CAAC,GAAG,CAAC,WAAW,EAAE,iBAAiB,CAAC,CAAC;IAC9D,YAAY,CAAC,YAAY,CAAC,GAAG,CAAC,cAAc,EAAE,WAAW,CAAC,CAAC;IAC3D,YAAY,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IACzD,YAAY,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IAC9C,YAAY,CAAC,YAAY,CAAC,GAAG,CAAC,gBAAgB,EAAE,aAAa,CAAC,CAAC;IAC/D,YAAY,CAAC,YAAY,CAAC,GAAG,CAAC,uBAAuB,EAAE,MAAM,CAAC,CAAC;IAE/D,OAAO,EAAE,YAAY,EAAE,YAAY,CAAC,QAAQ,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC;AACrF,CAAC;AAED,MAAM,gBAAgB,GAAG,CAAC,GAAW,EAAE,EAAE,CACvC,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;AAEpF,SAAS,YAAY;IACnB,MAAM,YAAY,GAAG,gBAAgB,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC;IAC9D,MAAM,MAAM,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,MAAM,EAAE,CAAC;IACzE,MAAM,aAAa,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAC;IAC/C,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,CAAC;AACzC,CAAC;AAED,SAAS,aAAa;IACpB,OAAO,gBAAgB,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC;AAClD,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Credentials } from "../credentials.js";
|
|
2
|
+
type CallbackServerProps = {
|
|
3
|
+
codeVerifier: string;
|
|
4
|
+
state: string;
|
|
5
|
+
redirectUri: string;
|
|
6
|
+
};
|
|
7
|
+
export declare const listenToOAuthCallback: ({ codeVerifier, state, redirectUri }: CallbackServerProps) => Promise<Credentials>;
|
|
8
|
+
export {};
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import * as p from "@clack/prompts";
|
|
2
|
+
import { createServer } from "node:http";
|
|
3
|
+
import { oauthClient } from "./client.js";
|
|
4
|
+
import { LOOPBACK_HOST, LOOPBACK_PORT } from "./constants.js";
|
|
5
|
+
const createCallbackServer = ({ codeVerifier, state, onSuccess, onError, }) => createServer(async (req, res) => {
|
|
6
|
+
const url = req.url ?? "/";
|
|
7
|
+
if (!url.startsWith("/callback")) {
|
|
8
|
+
p.log.message(`Ignoring request to ${url}`);
|
|
9
|
+
res.writeHead(404).end();
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
const q = new URL(url, `http://${req.headers.host}`).searchParams;
|
|
13
|
+
const code = q.get("code");
|
|
14
|
+
const returnedState = q.get("state");
|
|
15
|
+
if (!code || !returnedState) {
|
|
16
|
+
p.log.error("Callback missing code or state");
|
|
17
|
+
res.writeHead(400, { "Content-Type": "text/html" });
|
|
18
|
+
res.end(html("Login failed", "Missing code or state in callback.", false));
|
|
19
|
+
onError(new Error("Missing code or state in callback"));
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
if (returnedState !== state) {
|
|
23
|
+
p.log.error("State mismatch (expected same as redirect)");
|
|
24
|
+
res.writeHead(400, { "Content-Type": "text/html" });
|
|
25
|
+
res.end(html("Login failed", "Invalid state (possible CSRF).", false));
|
|
26
|
+
onError(new Error("Invalid state"));
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
try {
|
|
30
|
+
const tokenRes = await oauthClient.exchangeAuthorizationCode(code, codeVerifier);
|
|
31
|
+
if (!tokenRes.ok) {
|
|
32
|
+
const text = await tokenRes.text();
|
|
33
|
+
p.log.error(`Token endpoint returned ${tokenRes.status}: ${text.slice(0, 200)}`);
|
|
34
|
+
res.writeHead(400, { "Content-Type": "text/html" });
|
|
35
|
+
res.end(html("Login failed", "Token exchange failed. Try again.", false));
|
|
36
|
+
onError(new Error(`Token exchange failed: ${text}`));
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
p.log.success("✅ Authentication successful");
|
|
40
|
+
const data = (await tokenRes.json());
|
|
41
|
+
const defaultExpiresIn = 3600_000;
|
|
42
|
+
const expiresAt = data.expires_in ? Date.now() + data.expires_in * 1000 : Date.now() + defaultExpiresIn;
|
|
43
|
+
const credentials = {
|
|
44
|
+
access_token: data.access_token,
|
|
45
|
+
refresh_token: data.refresh_token,
|
|
46
|
+
expires_at: expiresAt,
|
|
47
|
+
scopes: data.scope?.split(" "),
|
|
48
|
+
};
|
|
49
|
+
res.writeHead(200, { "Content-Type": "text/html" });
|
|
50
|
+
res.end(html("Logged in", "You can close this window.", true));
|
|
51
|
+
onSuccess(credentials);
|
|
52
|
+
}
|
|
53
|
+
catch (e) {
|
|
54
|
+
p.log.error(e instanceof Error ? e.message : String(e));
|
|
55
|
+
res.writeHead(500, { "Content-Type": "text/html" });
|
|
56
|
+
res.end(html("Login failed", "Token exchange error. Try again.", false));
|
|
57
|
+
onError(e instanceof Error ? e : new Error(String(e)));
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
export const listenToOAuthCallback = ({ codeVerifier, state, redirectUri }) => {
|
|
61
|
+
return new Promise((resolve, reject) => {
|
|
62
|
+
const callbackServer = createCallbackServer({
|
|
63
|
+
codeVerifier,
|
|
64
|
+
state,
|
|
65
|
+
redirectUri,
|
|
66
|
+
onSuccess: (creds) => {
|
|
67
|
+
callbackServer.close();
|
|
68
|
+
resolve(creds);
|
|
69
|
+
},
|
|
70
|
+
onError: (err) => {
|
|
71
|
+
callbackServer.close();
|
|
72
|
+
reject(err);
|
|
73
|
+
},
|
|
74
|
+
});
|
|
75
|
+
callbackServer.listen(LOOPBACK_PORT, LOOPBACK_HOST);
|
|
76
|
+
});
|
|
77
|
+
};
|
|
78
|
+
function html(title, body, success) {
|
|
79
|
+
const bg = success ? "#ecfdf5" : "#fef2f2";
|
|
80
|
+
const border = success ? "#10b981" : "#ef4444";
|
|
81
|
+
const color = success ? "#065f46" : "#991b1b";
|
|
82
|
+
const logoSvg = `<svg width="120" height="24" viewBox="0 0 213 42" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M18.139 41.4181H1.58758C0.877981 41.4181 0.302734 40.8443 0.302734 40.1347V16.4957C0.302734 15.3182 1.73285 14.7794 2.48612 15.6845C7.8891 22.1765 15.4029 32.6359 19.2489 39.5848C19.7114 40.4205 19.0941 41.4181 18.139 41.4181Z" fill="#0A0E1C"/><path d="M34.9934 41.4181H23.8233C23.3366 41.4181 22.8936 41.144 22.6686 40.7125C18.5795 32.8689 8.1012 17.5927 0.638233 9.39174C0.420845 9.15285 0.302734 8.84629 0.302734 8.5233V1.58783C0.302734 0.878225 0.876486 0.302979 1.58609 0.302979H6.87182C7.19145 0.302979 7.48677 0.406983 7.71702 0.628672C14.4657 7.1264 32.6261 34.0831 35.8013 40.2463C36.1263 40.8771 35.703 41.4181 34.9934 41.4181Z" fill="#0A0E1C"/><path d="M41.4179 22.479C41.4177 26.1486 41.4178 34.7435 41.4178 40.0835C41.4178 41.3801 39.7105 41.8673 39.0235 40.7677C32.9779 31.091 20.3757 11.3903 13.1298 2.51663C12.4214 1.64905 13.0384 0.302979 14.1585 0.302979H25.3523C25.7594 0.302979 26.1363 0.487723 26.3781 0.815243C28.4729 3.65265 38.6422 17.4716 41.2512 21.8598C41.3654 22.052 41.4179 22.2554 41.4179 22.479Z" fill="#0A0E1C"/><path d="M40.133 0.302979H31.6871C30.6461 0.302979 30.0373 1.47597 30.6363 2.32725L39.0823 14.3294C39.8043 15.3554 41.4179 14.8446 41.4179 13.59V1.58783C41.4179 0.878225 40.8426 0.302979 40.133 0.302979Z" fill="#0A0E1C"/><path d="M69.4252 40.871H61.9757L75.539 0.850139H84.1548L97.737 40.871H90.2875L87.0895 31.0026H72.6044L69.4252 40.871ZM74.4856 25.1792H85.2083L79.9974 9.05754H79.6964L74.4856 25.1792Z" fill="#0A0E1C"/><path d="M102.282 40.871V0.850139H109.261V34.7936H126.229V40.871H102.282Z" fill="#0A0E1C"/><path d="M131.757 40.871V0.850139H146.204C155.065 0.850139 159.786 6.45853 159.786 14.0992C159.786 21.7985 155.008 27.3483 146.11 27.3483H138.736V40.871H131.757ZM138.736 21.3882H145.17C150.362 21.3882 152.676 18.3593 152.676 14.0992C152.676 9.83919 150.362 6.90798 145.132 6.90798H138.736V21.3882Z" fill="#0A0E1C"/><path d="M172.298 0.850139V40.871H165.319V0.850139H172.298Z" fill="#0A0E1C"/><path d="M212.303 14.3533H205.267C204.458 9.56561 200.79 6.81027 196.106 6.81027C189.804 6.81027 185.364 11.8324 185.364 20.8606C185.364 30.045 189.842 34.9108 196.087 34.9108C200.696 34.9108 204.383 32.2727 205.267 27.5828L212.303 27.6219C211.231 35.2626 205.154 41.4181 195.993 41.4181C185.835 41.4181 178.348 33.7774 178.348 20.8606C178.348 7.92413 185.929 0.302979 195.993 0.302979C204.534 0.302979 211.118 5.46191 212.303 14.3533Z" fill="#0A0E1C"/></svg>`;
|
|
83
|
+
return `<!DOCTYPE html>
|
|
84
|
+
<html>
|
|
85
|
+
<head>
|
|
86
|
+
<meta charset="utf-8">
|
|
87
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
88
|
+
<title>${title}</title>
|
|
89
|
+
<style>
|
|
90
|
+
* { box-sizing: border-box; }
|
|
91
|
+
body { margin: 0; min-height: 100vh; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2rem; font-family: system-ui, -apple-system, sans-serif; background: #f8fafc; }
|
|
92
|
+
.logo { flex-shrink: 0; }
|
|
93
|
+
.alert { max-width: 360px; padding: 1.25rem 1.5rem; border-radius: 8px; border-left: 4px solid ${border}; background: ${bg}; color: ${color}; }
|
|
94
|
+
.alert h1 { margin: 0 0 0.5rem; font-size: 1.125rem; font-weight: 600; }
|
|
95
|
+
.alert p { margin: 0; font-size: 0.9375rem; line-height: 1.5; opacity: 0.95; }
|
|
96
|
+
</style>
|
|
97
|
+
</head>
|
|
98
|
+
<body>
|
|
99
|
+
<div class="logo" aria-hidden="true">${logoSvg}</div>
|
|
100
|
+
<div class="alert">
|
|
101
|
+
<h1>${title}</h1>
|
|
102
|
+
<p>${body}</p>
|
|
103
|
+
</div>
|
|
104
|
+
</body>
|
|
105
|
+
</html>`;
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../../../src/lib/auth/oauth/server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function getValidAccessToken(): Promise<string | null>;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { credentials } from "../credentials.js";
|
|
2
|
+
import { oauthClient } from "./client.js";
|
|
3
|
+
const EXPIRY_BUFFER_MS = 60_000;
|
|
4
|
+
export async function getValidAccessToken() {
|
|
5
|
+
const creds = credentials.load();
|
|
6
|
+
if (!creds?.access_token)
|
|
7
|
+
return null;
|
|
8
|
+
if (!isExpired(creds))
|
|
9
|
+
return creds.access_token;
|
|
10
|
+
if (!creds.refresh_token)
|
|
11
|
+
return null;
|
|
12
|
+
const newCreds = await refreshTokens();
|
|
13
|
+
return newCreds?.access_token ?? null;
|
|
14
|
+
}
|
|
15
|
+
function isExpired(creds) {
|
|
16
|
+
return Boolean(creds.expires_at && Date.now() >= creds.expires_at - EXPIRY_BUFFER_MS);
|
|
17
|
+
}
|
|
18
|
+
async function refreshTokens() {
|
|
19
|
+
const creds = credentials.load();
|
|
20
|
+
if (!creds?.refresh_token)
|
|
21
|
+
return null;
|
|
22
|
+
const res = await oauthClient.fetchNewTokens(creds.refresh_token);
|
|
23
|
+
if (!res.ok) {
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
const data = (await res.json());
|
|
27
|
+
const newCreds = {
|
|
28
|
+
access_token: data.access_token,
|
|
29
|
+
refresh_token: data.refresh_token ?? creds.refresh_token,
|
|
30
|
+
expires_at: Date.now() + data.expires_in * 1000,
|
|
31
|
+
scopes: data.scope?.split(" "),
|
|
32
|
+
};
|
|
33
|
+
credentials.save(newCreds);
|
|
34
|
+
return newCreds;
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=token.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token.js","sourceRoot":"","sources":["../../../../src/lib/auth/oauth/token.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoB,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAClE,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C,MAAM,gBAAgB,GAAG,MAAM,CAAC;AAEhC,MAAM,CAAC,KAAK,UAAU,mBAAmB;IACvC,MAAM,KAAK,GAAG,WAAW,CAAC,IAAI,EAAE,CAAC;IACjC,IAAI,CAAC,KAAK,EAAE,YAAY;QAAE,OAAO,IAAI,CAAC;IACtC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC,YAAY,CAAC;IACjD,IAAI,CAAC,KAAK,CAAC,aAAa;QAAE,OAAO,IAAI,CAAC;IAEtC,MAAM,QAAQ,GAAG,MAAM,aAAa,EAAE,CAAC;IACvC,OAAO,QAAQ,EAAE,YAAY,IAAI,IAAI,CAAC;AACxC,CAAC;AAED,SAAS,SAAS,CAAC,KAAkB;IACnC,OAAO,OAAO,CAAC,KAAK,CAAC,UAAU,IAAI,IAAI,CAAC,GAAG,EAAE,IAAI,KAAK,CAAC,UAAU,GAAG,gBAAgB,CAAC,CAAC;AACxF,CAAC;AAED,KAAK,UAAU,aAAa;IAC1B,MAAM,KAAK,GAAG,WAAW,CAAC,IAAI,EAAE,CAAC;IACjC,IAAI,CAAC,KAAK,EAAE,aAAa;QAAE,OAAO,IAAI,CAAC;IAEvC,MAAM,GAAG,GAAG,MAAM,WAAW,CAAC,cAAc,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;IAElE,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QACZ,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAK7B,CAAC;IAEF,MAAM,QAAQ,GAAgB;QAC5B,YAAY,EAAE,IAAI,CAAC,YAAY;QAC/B,aAAa,EAAE,IAAI,CAAC,aAAa,IAAI,KAAK,CAAC,aAAa;QACxD,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,UAAU,GAAG,IAAI;QAC/C,MAAM,EAAE,IAAI,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC;KAC/B,CAAC;IACF,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC3B,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export type WhoamiInfo = {
|
|
2
|
+
method: "api_key";
|
|
3
|
+
team: {
|
|
4
|
+
id: string;
|
|
5
|
+
name: string;
|
|
6
|
+
};
|
|
7
|
+
} | {
|
|
8
|
+
method: "oauth";
|
|
9
|
+
email: string;
|
|
10
|
+
name: string;
|
|
11
|
+
} | null;
|
|
12
|
+
export declare function getWhoamiInfo(): Promise<{
|
|
13
|
+
method: string;
|
|
14
|
+
team: {
|
|
15
|
+
id: string;
|
|
16
|
+
name: string;
|
|
17
|
+
createdAt: Date;
|
|
18
|
+
hasStripeAccount: boolean;
|
|
19
|
+
hasActiveSubscription: boolean;
|
|
20
|
+
} | undefined;
|
|
21
|
+
email?: undefined;
|
|
22
|
+
name?: undefined;
|
|
23
|
+
} | {
|
|
24
|
+
method: string;
|
|
25
|
+
email: string;
|
|
26
|
+
name: string;
|
|
27
|
+
team?: undefined;
|
|
28
|
+
} | null>;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { api } from "../../api.js";
|
|
2
|
+
import { oauthClient } from "./oauth/client.js";
|
|
3
|
+
import { getValidAccessToken } from "./oauth/token.js";
|
|
4
|
+
export async function getWhoamiInfo() {
|
|
5
|
+
if (process.env.ALPIC_API_KEY !== undefined) {
|
|
6
|
+
const team = await getApiKeyTeam();
|
|
7
|
+
return {
|
|
8
|
+
method: "api_key",
|
|
9
|
+
team,
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
const token = await getValidAccessToken();
|
|
13
|
+
if (!token)
|
|
14
|
+
return null;
|
|
15
|
+
const userInfo = await fetchOAuthUserInfo(token);
|
|
16
|
+
if (!userInfo)
|
|
17
|
+
return null;
|
|
18
|
+
return {
|
|
19
|
+
method: "oauth",
|
|
20
|
+
email: userInfo.email,
|
|
21
|
+
name: userInfo.name,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
async function fetchOAuthUserInfo(accessToken) {
|
|
25
|
+
const res = await oauthClient.fetchUserInfo(accessToken);
|
|
26
|
+
if (!res.ok)
|
|
27
|
+
return null;
|
|
28
|
+
return (await res.json());
|
|
29
|
+
}
|
|
30
|
+
async function getApiKeyTeam() {
|
|
31
|
+
const teams = await api.teams.list.v1();
|
|
32
|
+
return teams[0];
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=whoami.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"whoami.js","sourceRoot":"","sources":["../../../src/lib/auth/whoami.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AACnC,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAOvD,MAAM,CAAC,KAAK,UAAU,aAAa;IACjC,IAAI,OAAO,CAAC,GAAG,CAAC,aAAa,KAAK,SAAS,EAAE,CAAC;QAC5C,MAAM,IAAI,GAAG,MAAM,aAAa,EAAE,CAAC;QACnC,OAAO;YACL,MAAM,EAAE,SAAS;YACjB,IAAI;SACL,CAAC;IACJ,CAAC;IAED,MAAM,KAAK,GAAG,MAAM,mBAAmB,EAAE,CAAC;IAC1C,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IAExB,MAAM,QAAQ,GAAG,MAAM,kBAAkB,CAAC,KAAK,CAAC,CAAC;IACjD,IAAI,CAAC,QAAQ;QAAE,OAAO,IAAI,CAAC;IAE3B,OAAO;QACL,MAAM,EAAE,OAAO;QACf,KAAK,EAAE,QAAQ,CAAC,KAAK;QACrB,IAAI,EAAE,QAAQ,CAAC,IAAI;KACpB,CAAC;AACJ,CAAC;AAmBD,KAAK,UAAU,kBAAkB,CAAC,WAAmB;IACnD,MAAM,GAAG,GAAG,MAAM,WAAW,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC;IACzD,IAAI,CAAC,GAAG,CAAC,EAAE;QAAE,OAAO,IAAI,CAAC;IACzB,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAkB,CAAC;AAC7C,CAAC;AAED,KAAK,UAAU,aAAa;IAC1B,MAAM,KAAK,GAAG,MAAM,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;IACxC,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ProjectConfig } from "../types.js";
|
|
2
|
+
export declare const config: {
|
|
3
|
+
load: (deployDir: string) => {
|
|
4
|
+
projectId: string;
|
|
5
|
+
teamId: string;
|
|
6
|
+
projectName: string;
|
|
7
|
+
environmentId: string | undefined;
|
|
8
|
+
environmentName: string | undefined;
|
|
9
|
+
} | null;
|
|
10
|
+
save: (config: ProjectConfig, deployDir: string) => void;
|
|
11
|
+
};
|