@commit451/salamander 1.0.8 → 1.1.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/dist/commands/runner-selection.d.ts.map +1 -1
- package/dist/commands/runner-selection.js +1 -5
- package/dist/commands/runner-selection.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -9
- package/dist/index.js.map +1 -1
- package/dist/services/api.d.ts +7 -0
- package/dist/services/api.d.ts.map +1 -1
- package/dist/services/api.js +6 -0
- package/dist/services/api.js.map +1 -1
- package/dist/services/auth.d.ts +4 -6
- package/dist/services/auth.d.ts.map +1 -1
- package/dist/services/auth.js +85 -202
- package/dist/services/auth.js.map +1 -1
- package/dist/services/command-listener.d.ts.map +1 -1
- package/dist/services/command-listener.js +45 -12
- package/dist/services/command-listener.js.map +1 -1
- package/dist/services/crypto.d.ts +52 -0
- package/dist/services/crypto.d.ts.map +1 -0
- package/dist/services/crypto.js +104 -0
- package/dist/services/crypto.js.map +1 -0
- package/dist/services/key-manager.d.ts +45 -0
- package/dist/services/key-manager.d.ts.map +1 -0
- package/dist/services/key-manager.js +123 -0
- package/dist/services/key-manager.js.map +1 -0
- package/dist/services/multi-device-key-manager.d.ts +56 -0
- package/dist/services/multi-device-key-manager.d.ts.map +1 -0
- package/dist/services/multi-device-key-manager.js +159 -0
- package/dist/services/multi-device-key-manager.js.map +1 -0
- package/dist/services/runner.d.ts +3 -3
- package/dist/services/runner.d.ts.map +1 -1
- package/dist/services/runner.js +23 -26
- package/dist/services/runner.js.map +1 -1
- package/dist/services/user.d.ts.map +1 -1
- package/dist/services/user.js +0 -3
- package/dist/services/user.js.map +1 -1
- package/dist/types/runner.d.ts +0 -18
- package/dist/types/runner.d.ts.map +1 -1
- package/dist/utils/encryption.d.ts +29 -0
- package/dist/utils/encryption.d.ts.map +1 -0
- package/dist/utils/encryption.js +64 -0
- package/dist/utils/encryption.js.map +1 -0
- package/dist/utils/storage.d.ts +4 -8
- package/dist/utils/storage.d.ts.map +1 -1
- package/dist/utils/storage.js +5 -13
- package/dist/utils/storage.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runner-selection.d.ts","sourceRoot":"","sources":["../../src/commands/runner-selection.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"runner-selection.d.ts","sourceRoot":"","sources":["../../src/commands/runner-selection.ts"],"names":[],"mappings":"AASA,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC,CAuEzD"}
|
|
@@ -69,14 +69,10 @@ export async function runnerSelectionFlow() {
|
|
|
69
69
|
}
|
|
70
70
|
}
|
|
71
71
|
catch (error) {
|
|
72
|
-
console.error(chalk.red('❌ Error loading runners:'), error.message);
|
|
73
72
|
process.exit(1);
|
|
74
73
|
}
|
|
75
74
|
}
|
|
76
75
|
function formatRunnerChoice(runner) {
|
|
77
|
-
|
|
78
|
-
? ` • ${runner.lastMessage.substring(0, 50)}${runner.lastMessage.length > 50 ? '...' : ''}`
|
|
79
|
-
: '';
|
|
80
|
-
return `🤖 ${chalk.bold(runner.name)} ${chalk.gray(`[${runner.runnerType}]`)}${chalk.dim(lastMessage)}`;
|
|
76
|
+
return `🤖 ${chalk.bold(runner.name)} ${chalk.dim(`(${runner.directory})`)}`;
|
|
81
77
|
}
|
|
82
78
|
//# sourceMappingURL=runner-selection.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runner-selection.js","sourceRoot":"","sources":["../../src/commands/runner-selection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,MAAM,EAAC,MAAM,mBAAmB,CAAC;AACzC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAC,aAAa,EAAC,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAC,eAAe,EAAC,MAAM,iCAAiC,CAAC;AAChE,OAAO,EAAC,gBAAgB,EAAC,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAC,gBAAgB,EAAC,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"runner-selection.js","sourceRoot":"","sources":["../../src/commands/runner-selection.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AA2IA,MAAM,CAAC,OAAO,UAAU,IAAI,SAE3B"}
|
package/dist/index.js
CHANGED
|
@@ -10,7 +10,6 @@ import { runnerSelectionFlow } from './commands/runner-selection.js';
|
|
|
10
10
|
import { createRunnerFlow } from './commands/create-runner.js';
|
|
11
11
|
import { deleteRunnerFlow } from './commands/delete-runner.js';
|
|
12
12
|
import { isVersionOutdated } from './utils/version.js';
|
|
13
|
-
import { generateDeviceId } from './utils/device.js';
|
|
14
13
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
15
14
|
const packageJsonPath = join(__dirname, '..', 'package.json');
|
|
16
15
|
const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf8'));
|
|
@@ -39,20 +38,25 @@ program
|
|
|
39
38
|
await initializeAndRun(deleteRunnerFlow);
|
|
40
39
|
});
|
|
41
40
|
program
|
|
42
|
-
.command('
|
|
43
|
-
.description('Sign
|
|
41
|
+
.command('login')
|
|
42
|
+
.description('Sign in to Salamander')
|
|
44
43
|
.action(async () => {
|
|
45
44
|
try {
|
|
46
45
|
await AuthService.initialize();
|
|
47
46
|
if (AuthService.isAuthenticated) {
|
|
48
|
-
|
|
47
|
+
const userEmail = AuthService.user?.email || 'Unknown user';
|
|
48
|
+
console.log(chalk.green(`✅ Already signed in as: ${userEmail}`));
|
|
49
49
|
}
|
|
50
50
|
else {
|
|
51
|
-
|
|
51
|
+
const success = await AuthService.loginFlow();
|
|
52
|
+
if (!success) {
|
|
53
|
+
console.log(chalk.red('Authentication failed or cancelled.'));
|
|
54
|
+
process.exit(1);
|
|
55
|
+
}
|
|
52
56
|
}
|
|
53
57
|
}
|
|
54
58
|
catch (error) {
|
|
55
|
-
console.error(chalk.red('❌ Error during
|
|
59
|
+
console.error(chalk.red('❌ Error during login:'), error.message);
|
|
56
60
|
process.exit(1);
|
|
57
61
|
}
|
|
58
62
|
});
|
|
@@ -84,9 +88,6 @@ async function initializeAndRun(action) {
|
|
|
84
88
|
// Fetch global configuration first
|
|
85
89
|
await ConfigService.fetchConfig();
|
|
86
90
|
console.log(chalk.gray('✓ Global config loaded'));
|
|
87
|
-
// Print machine ID for debugging
|
|
88
|
-
const machineId = generateDeviceId();
|
|
89
|
-
console.log(chalk.gray(`🖥️ Machine ID: ${machineId}`));
|
|
90
91
|
// Check if app is disabled
|
|
91
92
|
if (ConfigService.isAppDisabled()) {
|
|
92
93
|
console.log(chalk.red('❌ Salamander CLI is currently disabled. Please try again later.'));
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAC,OAAO,EAAC,MAAM,WAAW,CAAC;AAClC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAC,YAAY,EAAC,MAAM,IAAI,CAAC;AAChC,OAAO,EAAC,aAAa,EAAC,MAAM,KAAK,CAAC;AAClC,OAAO,EAAC,OAAO,EAAE,IAAI,EAAC,MAAM,MAAM,CAAC;AACnC,OAAO,EAAC,WAAW,EAAC,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAC,aAAa,EAAC,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAAC,mBAAmB,EAAC,MAAM,gCAAgC,CAAC;AACnE,OAAO,EAAC,gBAAgB,EAAC,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAC,gBAAgB,EAAC,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAC,iBAAiB,EAAC,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/services/api.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ interface CreateRunnerRequest {
|
|
|
3
3
|
machineId: string;
|
|
4
4
|
machineName: string;
|
|
5
5
|
name: string;
|
|
6
|
+
encryptionVerification?: string;
|
|
6
7
|
}
|
|
7
8
|
interface UpdateRunnerRequest {
|
|
8
9
|
name?: string;
|
|
@@ -10,10 +11,16 @@ interface UpdateRunnerRequest {
|
|
|
10
11
|
updateLastUsed?: boolean | null;
|
|
11
12
|
lastMessage?: string;
|
|
12
13
|
}
|
|
14
|
+
export interface CreateMessageRequest {
|
|
15
|
+
content: string;
|
|
16
|
+
type: string;
|
|
17
|
+
senderName: string;
|
|
18
|
+
}
|
|
13
19
|
export declare class ApiService {
|
|
14
20
|
private static getAuthToken;
|
|
15
21
|
private static makeRequest;
|
|
16
22
|
static createRunner(request: CreateRunnerRequest): Promise<any>;
|
|
23
|
+
static createRunnerMessage(runnerId: string, request: CreateMessageRequest): Promise<any>;
|
|
17
24
|
static updateRunner(runnerId: string, request: UpdateRunnerRequest): Promise<any>;
|
|
18
25
|
static deleteRunner(runnerId: string): Promise<void>;
|
|
19
26
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/services/api.ts"],"names":[],"mappings":"AAeA,UAAU,mBAAmB;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/services/api.ts"],"names":[],"mappings":"AAeA,UAAU,mBAAmB;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,sBAAsB,CAAC,EAAE,MAAM,CAAC;CACnC;AAED,UAAU,mBAAmB;IACzB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,mBAAmB,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IACrC,cAAc,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAChC,WAAW,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,oBAAoB;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;CACtB;AAED,qBAAa,UAAU;mBACE,YAAY;mBAUZ,WAAW;WAwCnB,YAAY,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,GAAG,CAAC;WAOxD,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,GAAG,CAAC;WAOlF,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,GAAG,CAAC;WAO1E,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAK7D"}
|
package/dist/services/api.js
CHANGED
|
@@ -53,6 +53,12 @@ export class ApiService {
|
|
|
53
53
|
body: JSON.stringify(request),
|
|
54
54
|
});
|
|
55
55
|
}
|
|
56
|
+
static async createRunnerMessage(runnerId, request) {
|
|
57
|
+
return await this.makeRequest(`/runner/${runnerId}/message`, {
|
|
58
|
+
method: 'POST',
|
|
59
|
+
body: JSON.stringify(request),
|
|
60
|
+
});
|
|
61
|
+
}
|
|
56
62
|
static async updateRunner(runnerId, request) {
|
|
57
63
|
return await this.makeRequest(`/runner/${runnerId}`, {
|
|
58
64
|
method: 'PATCH',
|
package/dist/services/api.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/services/api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,WAAW,EAAC,MAAM,WAAW,CAAC;AAEtC,MAAM,YAAY,GAAG,iCAAiC,CAAC;AAEvD,MAAM,QAAS,SAAQ,KAAK;IAGb;IACA;IAHX,YACI,OAAe,EACR,MAAc,EACd,QAAc;QAErB,KAAK,CAAC,OAAO,CAAC,CAAC;QAHR,WAAM,GAAN,MAAM,CAAQ;QACd,aAAQ,GAAR,QAAQ,CAAM;QAGrB,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC;IAC3B,CAAC;CACJ;
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/services/api.ts"],"names":[],"mappings":"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"}
|
package/dist/services/auth.d.ts
CHANGED
|
@@ -1,19 +1,17 @@
|
|
|
1
1
|
import { User } from 'firebase/auth';
|
|
2
2
|
export declare class AuthService {
|
|
3
3
|
private static currentUser;
|
|
4
|
-
private static customUserInfo;
|
|
5
4
|
private static authStateInitialized;
|
|
6
5
|
private static authStateReady;
|
|
7
|
-
private static readonly
|
|
6
|
+
private static readonly WEB_APP_URL;
|
|
7
|
+
private static generateAuthResponseHTML;
|
|
8
8
|
private static openBrowser;
|
|
9
|
-
private static
|
|
10
|
-
private static exchangeCodeForTokens;
|
|
11
|
-
private static refreshToken;
|
|
9
|
+
private static startLocalServerForToken;
|
|
12
10
|
static initialize(): Promise<void>;
|
|
13
11
|
static get isAuthenticated(): boolean;
|
|
14
12
|
static get user(): User | null;
|
|
15
13
|
static get userId(): string | null;
|
|
16
14
|
static loginFlow(): Promise<boolean>;
|
|
17
|
-
static
|
|
15
|
+
private static webAuthFlow;
|
|
18
16
|
}
|
|
19
17
|
//# sourceMappingURL=auth.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/services/auth.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/services/auth.ts"],"names":[],"mappings":"AAMA,OAAO,EAAqD,IAAI,EAAC,MAAM,eAAe,CAAC;AAOvF,qBAAa,WAAW;IACpB,OAAO,CAAC,MAAM,CAAC,WAAW,CAAqB;IAC/C,OAAO,CAAC,MAAM,CAAC,oBAAoB,CAAkB;IACrD,OAAO,CAAC,MAAM,CAAC,cAAc,CAA8B;IAE3D,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,WAAW,CAA8B;IAEjE,OAAO,CAAC,MAAM,CAAC,wBAAwB;mBAyClB,WAAW;mBAsBX,wBAAwB;WAiDhC,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAuCxC,MAAM,KAAK,eAAe,IAAI,OAAO,CAEpC;IAED,MAAM,KAAK,IAAI,IAAI,IAAI,GAAG,IAAI,CAE7B;IAED,MAAM,KAAK,MAAM,IAAI,MAAM,GAAG,IAAI,CAEjC;WAEY,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC;mBA8BrB,WAAW;CAoCnC"}
|
package/dist/services/auth.js
CHANGED
|
@@ -4,17 +4,55 @@ import { createServer } from 'http';
|
|
|
4
4
|
import { URL } from 'url';
|
|
5
5
|
import { exec } from 'child_process';
|
|
6
6
|
import { promisify } from 'util';
|
|
7
|
-
import {
|
|
8
|
-
import { getAuth, GoogleAuthProvider, onAuthStateChanged, signInWithCredential } from 'firebase/auth';
|
|
7
|
+
import { getAuth, onAuthStateChanged, signInWithCustomToken } from 'firebase/auth';
|
|
9
8
|
import app from '../config/firebase.js';
|
|
10
9
|
const execAsync = promisify(exec);
|
|
11
10
|
const auth = getAuth(app);
|
|
12
11
|
export class AuthService {
|
|
13
12
|
static currentUser = null;
|
|
14
|
-
static customUserInfo = null;
|
|
15
13
|
static authStateInitialized = false;
|
|
16
14
|
static authStateReady = null;
|
|
17
|
-
static
|
|
15
|
+
static WEB_APP_URL = 'https://salamander.space';
|
|
16
|
+
static generateAuthResponseHTML(isSuccess, title, message) {
|
|
17
|
+
const headingColor = isSuccess ? '#10b981' : '#f87171';
|
|
18
|
+
return `
|
|
19
|
+
<!DOCTYPE html>
|
|
20
|
+
<html>
|
|
21
|
+
<head>
|
|
22
|
+
<title>${title}</title>
|
|
23
|
+
<style>
|
|
24
|
+
body {
|
|
25
|
+
background-color: #111827;
|
|
26
|
+
color: #f9fafb;
|
|
27
|
+
font-family: 'Fira Code', 'JetBrains Mono', monospace;
|
|
28
|
+
text-align: center;
|
|
29
|
+
padding: 50px;
|
|
30
|
+
margin: 0;
|
|
31
|
+
}
|
|
32
|
+
h1 { color: ${headingColor}; }
|
|
33
|
+
.logo {
|
|
34
|
+
width: 48px;
|
|
35
|
+
height: 48px;
|
|
36
|
+
margin: 0 auto 24px;
|
|
37
|
+
background: #ff6b35;
|
|
38
|
+
border-radius: 8px;
|
|
39
|
+
display: flex;
|
|
40
|
+
align-items: center;
|
|
41
|
+
justify-content: center;
|
|
42
|
+
font-size: 24px;
|
|
43
|
+
color: white;
|
|
44
|
+
font-weight: bold;
|
|
45
|
+
}
|
|
46
|
+
</style>
|
|
47
|
+
</head>
|
|
48
|
+
<body>
|
|
49
|
+
<div class="logo">S</div>
|
|
50
|
+
<h1>${title}</h1>
|
|
51
|
+
<p>${message}</p>
|
|
52
|
+
</body>
|
|
53
|
+
</html>
|
|
54
|
+
`;
|
|
55
|
+
}
|
|
18
56
|
static async openBrowser(url) {
|
|
19
57
|
const platform = process.platform;
|
|
20
58
|
let command;
|
|
@@ -23,7 +61,7 @@ export class AuthService {
|
|
|
23
61
|
command = `open "${url}"`;
|
|
24
62
|
break;
|
|
25
63
|
case 'win32':
|
|
26
|
-
command = `start "${url}"`;
|
|
64
|
+
command = `cmd /c start "" "${url}"`;
|
|
27
65
|
break;
|
|
28
66
|
default:
|
|
29
67
|
command = `xdg-open "${url}"`;
|
|
@@ -35,126 +73,48 @@ export class AuthService {
|
|
|
35
73
|
console.log(chalk.yellow(`⚠️ Could not open browser automatically. Please visit: ${url}`));
|
|
36
74
|
}
|
|
37
75
|
}
|
|
38
|
-
static async
|
|
76
|
+
static async startLocalServerForToken() {
|
|
39
77
|
return new Promise((resolve, reject) => {
|
|
40
78
|
const server = createServer();
|
|
41
|
-
let
|
|
42
|
-
let
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
|
|
79
|
+
let tokenResolve;
|
|
80
|
+
let tokenReject;
|
|
81
|
+
const tokenPromise = new Promise((res, rej) => {
|
|
82
|
+
tokenResolve = res;
|
|
83
|
+
tokenReject = rej;
|
|
46
84
|
});
|
|
47
85
|
server.on('request', (req, res) => {
|
|
48
86
|
if (req.url) {
|
|
49
87
|
const url = new URL(req.url, 'http://localhost:8080');
|
|
50
|
-
if (url.pathname === '/
|
|
51
|
-
const
|
|
88
|
+
if (url.pathname === '/auth-callback') {
|
|
89
|
+
const token = url.searchParams.get('token');
|
|
52
90
|
const error = url.searchParams.get('error');
|
|
53
91
|
if (error) {
|
|
54
92
|
res.writeHead(400, { 'Content-Type': 'text/html' });
|
|
55
|
-
res.end('
|
|
56
|
-
|
|
93
|
+
res.end(this.generateAuthResponseHTML(false, 'Authentication Failed', `Error: ${error}<br>You can close this window and try again.`));
|
|
94
|
+
tokenReject(new Error(`Authentication error: ${error}`));
|
|
57
95
|
return;
|
|
58
96
|
}
|
|
59
|
-
if (
|
|
97
|
+
if (token) {
|
|
60
98
|
res.writeHead(200, { 'Content-Type': 'text/html' });
|
|
61
|
-
res.end(
|
|
62
|
-
|
|
63
|
-
<html>
|
|
64
|
-
<head>
|
|
65
|
-
<title>Authentication Successful</title>
|
|
66
|
-
<style>
|
|
67
|
-
body {
|
|
68
|
-
background-color: #000000;
|
|
69
|
-
color: #ffffff;
|
|
70
|
-
font-family: Arial, sans-serif;
|
|
71
|
-
text-align: center;
|
|
72
|
-
padding: 50px;
|
|
73
|
-
margin: 0;
|
|
74
|
-
}
|
|
75
|
-
h1 {
|
|
76
|
-
font-size: 2.5em;
|
|
77
|
-
margin-bottom: 20px;
|
|
78
|
-
}
|
|
79
|
-
p {
|
|
80
|
-
font-size: 1.2em;
|
|
81
|
-
}
|
|
82
|
-
</style>
|
|
83
|
-
</head>
|
|
84
|
-
<body>
|
|
85
|
-
<h1>Authentication Successful!</h1>
|
|
86
|
-
<p>You can close this window and return to the CLI.</p>
|
|
87
|
-
</body>
|
|
88
|
-
</html>
|
|
89
|
-
`);
|
|
90
|
-
authCodeResolve(code);
|
|
99
|
+
res.end(this.generateAuthResponseHTML(true, 'Authentication Successful!', 'You can now close this window and return to the CLI.'));
|
|
100
|
+
tokenResolve(token);
|
|
91
101
|
}
|
|
92
102
|
else {
|
|
93
103
|
res.writeHead(400, { 'Content-Type': 'text/html' });
|
|
94
|
-
res.end('
|
|
95
|
-
|
|
104
|
+
res.end(this.generateAuthResponseHTML(false, 'Authentication Failed', 'No authentication token received.<br>You can close this window and try again.'));
|
|
105
|
+
tokenReject(new Error('No authentication token received'));
|
|
96
106
|
}
|
|
97
107
|
}
|
|
98
108
|
}
|
|
99
109
|
});
|
|
100
110
|
server.listen(8080, 'localhost', () => {
|
|
101
|
-
resolve({ server,
|
|
111
|
+
resolve({ server, tokenPromise });
|
|
102
112
|
});
|
|
103
113
|
server.on('error', (error) => {
|
|
104
114
|
reject(error);
|
|
105
115
|
});
|
|
106
116
|
});
|
|
107
117
|
}
|
|
108
|
-
static async exchangeCodeForTokens(code) {
|
|
109
|
-
const params = new URLSearchParams({
|
|
110
|
-
client_id: this.CLIENT_ID,
|
|
111
|
-
code,
|
|
112
|
-
grant_type: 'authorization_code',
|
|
113
|
-
redirect_uri: 'http://localhost:8080/oauth/callback',
|
|
114
|
-
});
|
|
115
|
-
const response = await fetch('https://oauth2.googleapis.com/token', {
|
|
116
|
-
method: 'POST',
|
|
117
|
-
headers: {
|
|
118
|
-
'Content-Type': 'application/x-www-form-urlencoded',
|
|
119
|
-
},
|
|
120
|
-
body: params.toString(),
|
|
121
|
-
});
|
|
122
|
-
if (!response.ok) {
|
|
123
|
-
const error = await response.text();
|
|
124
|
-
throw new Error(`Token exchange failed: ${error}`);
|
|
125
|
-
}
|
|
126
|
-
return await response.json();
|
|
127
|
-
}
|
|
128
|
-
static async refreshToken(refreshToken) {
|
|
129
|
-
const params = new URLSearchParams({
|
|
130
|
-
grant_type: 'refresh_token',
|
|
131
|
-
refresh_token: refreshToken,
|
|
132
|
-
client_id: this.CLIENT_ID,
|
|
133
|
-
});
|
|
134
|
-
const response = await fetch('https://oauth2.googleapis.com/token', {
|
|
135
|
-
method: 'POST',
|
|
136
|
-
headers: {
|
|
137
|
-
'Content-Type': 'application/x-www-form-urlencoded',
|
|
138
|
-
},
|
|
139
|
-
body: params.toString(),
|
|
140
|
-
});
|
|
141
|
-
if (!response.ok) {
|
|
142
|
-
const errorText = await response.text();
|
|
143
|
-
throw new Error(`Token refresh failed: ${response.status} ${errorText}`);
|
|
144
|
-
}
|
|
145
|
-
const tokens = await response.json();
|
|
146
|
-
// Sign in to Firebase with the new access token
|
|
147
|
-
const credential = GoogleAuthProvider.credential(null, tokens.access_token);
|
|
148
|
-
await signInWithCredential(auth, credential);
|
|
149
|
-
// Update stored tokens with new access token (refresh token may be the same)
|
|
150
|
-
const existingAuth = await loadAuth();
|
|
151
|
-
await saveAuth({
|
|
152
|
-
userId: existingAuth?.userId || '',
|
|
153
|
-
email: existingAuth?.email || '',
|
|
154
|
-
accessToken: tokens.access_token,
|
|
155
|
-
refreshToken: tokens.refresh_token || existingAuth?.refreshToken
|
|
156
|
-
});
|
|
157
|
-
}
|
|
158
118
|
static async initialize() {
|
|
159
119
|
if (this.authStateInitialized) {
|
|
160
120
|
// Wait for auth state to be ready if initialization is in progress
|
|
@@ -168,78 +128,23 @@ export class AuthService {
|
|
|
168
128
|
this.authStateReady = new Promise((resolve) => {
|
|
169
129
|
resolveAuthState = resolve;
|
|
170
130
|
});
|
|
171
|
-
// Try to restore from stored auth
|
|
172
|
-
const storedAuth = await loadAuth();
|
|
173
|
-
let authAttemptMade = false;
|
|
174
|
-
if (storedAuth?.userId && storedAuth.email && storedAuth.accessToken) {
|
|
175
|
-
authAttemptMade = true;
|
|
176
|
-
try {
|
|
177
|
-
// Try to restore Firebase session using stored access token
|
|
178
|
-
const credential = GoogleAuthProvider.credential(null, storedAuth.accessToken);
|
|
179
|
-
await signInWithCredential(auth, credential);
|
|
180
|
-
console.log(chalk.green('✅ Session restored from storage'));
|
|
181
|
-
}
|
|
182
|
-
catch (error) {
|
|
183
|
-
// Token might be expired, try refresh token if available
|
|
184
|
-
if (storedAuth.refreshToken) {
|
|
185
|
-
try {
|
|
186
|
-
await this.refreshToken(storedAuth.refreshToken);
|
|
187
|
-
console.log(chalk.green('✅ Session refreshed from storage'));
|
|
188
|
-
}
|
|
189
|
-
catch (refreshError) {
|
|
190
|
-
console.log(chalk.yellow('⚠️ Stored session expired, please sign in again'));
|
|
191
|
-
await clearAuth();
|
|
192
|
-
authAttemptMade = false;
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
else {
|
|
196
|
-
console.log(chalk.yellow('⚠️ Stored session expired, please sign in again'));
|
|
197
|
-
await clearAuth();
|
|
198
|
-
authAttemptMade = false;
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
131
|
// Set up Firebase Auth state observer
|
|
203
132
|
onAuthStateChanged(auth, async (user) => {
|
|
204
133
|
if (user) {
|
|
205
134
|
this.currentUser = user;
|
|
206
|
-
if (!this.customUserInfo) {
|
|
207
|
-
this.customUserInfo = {
|
|
208
|
-
id: user.uid,
|
|
209
|
-
email: user.email || '',
|
|
210
|
-
name: user.displayName || user.email?.split('@')[0] || ''
|
|
211
|
-
};
|
|
212
|
-
}
|
|
213
|
-
// Only update user info in storage, preserve OAuth tokens if they exist
|
|
214
|
-
const existingAuth = await loadAuth();
|
|
215
|
-
await saveAuth({
|
|
216
|
-
userId: user.uid,
|
|
217
|
-
email: user.email || '',
|
|
218
|
-
accessToken: existingAuth?.accessToken || undefined,
|
|
219
|
-
refreshToken: existingAuth?.refreshToken || undefined
|
|
220
|
-
});
|
|
221
135
|
}
|
|
222
136
|
else {
|
|
223
137
|
// User signed out, clean up
|
|
224
138
|
this.currentUser = null;
|
|
225
|
-
this.customUserInfo = null;
|
|
226
|
-
await clearAuth();
|
|
227
139
|
}
|
|
228
140
|
// Resolve the auth state promise once we know the state
|
|
229
|
-
|
|
230
|
-
resolveAuthState();
|
|
231
|
-
resolveAuthState = null;
|
|
232
|
-
}
|
|
141
|
+
resolveAuthState();
|
|
233
142
|
});
|
|
234
143
|
this.authStateInitialized = true;
|
|
235
|
-
//
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
resolveAuthState();
|
|
240
|
-
}
|
|
241
|
-
}, 100);
|
|
242
|
-
}
|
|
144
|
+
// No session to restore, resolve after a short delay to allow Firebase auth state to settle
|
|
145
|
+
setTimeout(() => {
|
|
146
|
+
resolveAuthState();
|
|
147
|
+
}, 100);
|
|
243
148
|
// Wait for auth state to be determined
|
|
244
149
|
await this.authStateReady;
|
|
245
150
|
}
|
|
@@ -254,7 +159,7 @@ export class AuthService {
|
|
|
254
159
|
}
|
|
255
160
|
static async loginFlow() {
|
|
256
161
|
console.log(chalk.blue('\n🔐 Authentication Required'));
|
|
257
|
-
console.log('Please sign in
|
|
162
|
+
console.log('Please sign in to continue.\n');
|
|
258
163
|
try {
|
|
259
164
|
// Ensure auth state is initialized
|
|
260
165
|
await this.initialize();
|
|
@@ -264,46 +169,36 @@ export class AuthService {
|
|
|
264
169
|
return true;
|
|
265
170
|
}
|
|
266
171
|
const proceed = await input({
|
|
267
|
-
message: 'Press Enter to open
|
|
172
|
+
message: 'Press Enter to open sign-in in your browser, or type "q" to quit:',
|
|
268
173
|
default: '',
|
|
269
174
|
});
|
|
270
175
|
if (proceed.toLowerCase() === 'q') {
|
|
271
176
|
return false;
|
|
272
177
|
}
|
|
273
|
-
|
|
178
|
+
return await this.webAuthFlow();
|
|
179
|
+
}
|
|
180
|
+
catch (error) {
|
|
181
|
+
return false;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
static async webAuthFlow() {
|
|
185
|
+
try {
|
|
186
|
+
console.log(chalk.yellow('🌐 Please complete sign-in in your browser...\n'));
|
|
274
187
|
// Start local server to receive callback
|
|
275
|
-
const { server,
|
|
188
|
+
const { server, tokenPromise } = await this.startLocalServerForToken();
|
|
276
189
|
try {
|
|
277
|
-
// Create
|
|
278
|
-
const
|
|
279
|
-
authUrl
|
|
280
|
-
authUrl.searchParams.set('redirect_uri', 'http://localhost:8080/oauth/callback');
|
|
281
|
-
authUrl.searchParams.set('response_type', 'code');
|
|
282
|
-
authUrl.searchParams.set('scope', 'openid email profile');
|
|
283
|
-
authUrl.searchParams.set('access_type', 'offline');
|
|
284
|
-
authUrl.searchParams.set('prompt', 'consent');
|
|
190
|
+
// Create the auth URL - use main auth page with callback parameter
|
|
191
|
+
const redirectUrl = 'http://localhost:8080/auth-callback';
|
|
192
|
+
const authUrl = `${this.WEB_APP_URL}/#auth?callback=${encodeURIComponent(redirectUrl)}`;
|
|
285
193
|
// Open browser
|
|
286
|
-
await this.openBrowser(authUrl
|
|
287
|
-
console.log('
|
|
194
|
+
await this.openBrowser(authUrl);
|
|
195
|
+
console.log('');
|
|
288
196
|
// Wait for callback
|
|
289
|
-
const
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
console.log('Exchanging authorization code for tokens...');
|
|
293
|
-
const tokens = await this.exchangeCodeForTokens(authCode);
|
|
294
|
-
// Sign in to Firebase Auth using the Google OAuth token
|
|
295
|
-
const credential = GoogleAuthProvider.credential(null, tokens.access_token);
|
|
296
|
-
const userCredential = await signInWithCredential(auth, credential);
|
|
197
|
+
const customToken = await tokenPromise;
|
|
198
|
+
// Sign in to Firebase Auth using the custom token
|
|
199
|
+
const userCredential = await signInWithCustomToken(auth, customToken);
|
|
297
200
|
this.currentUser = userCredential.user;
|
|
298
|
-
|
|
299
|
-
await saveAuth({
|
|
300
|
-
userId: userCredential.user.uid,
|
|
301
|
-
email: userCredential.user.email || '',
|
|
302
|
-
accessToken: tokens.access_token,
|
|
303
|
-
refreshToken: tokens.refresh_token
|
|
304
|
-
});
|
|
305
|
-
console.log(chalk.green(`✅ Welcome ${userCredential.user.displayName || userCredential.user.email}!`));
|
|
306
|
-
console.log(chalk.green('✅ Login successful!'));
|
|
201
|
+
console.log(chalk.green('✅ Login successful!'));
|
|
307
202
|
return true;
|
|
308
203
|
}
|
|
309
204
|
finally {
|
|
@@ -311,20 +206,8 @@ export class AuthService {
|
|
|
311
206
|
}
|
|
312
207
|
}
|
|
313
208
|
catch (error) {
|
|
314
|
-
console.error(chalk.red('❌ Authentication failed:'), error.message);
|
|
315
209
|
return false;
|
|
316
210
|
}
|
|
317
211
|
}
|
|
318
|
-
static async signOut() {
|
|
319
|
-
try {
|
|
320
|
-
await auth.signOut();
|
|
321
|
-
// Firebase auth state observer will handle clearing user state
|
|
322
|
-
console.log(chalk.green('✅ Signed out successfully'));
|
|
323
|
-
}
|
|
324
|
-
catch (error) {
|
|
325
|
-
console.error(chalk.red('❌ Error signing out:'), error.message);
|
|
326
|
-
throw error;
|
|
327
|
-
}
|
|
328
|
-
}
|
|
329
212
|
}
|
|
330
213
|
//# sourceMappingURL=auth.js.map
|