File size: 3,427 Bytes
a5d1c1b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61b1da1
a5d1c1b
 
 
 
 
 
 
 
 
61b1da1
a5d1c1b
 
 
 
 
 
61b1da1
a5d1c1b
 
 
61b1da1
a5d1c1b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
import { authService } from '../services/auth-service.js';
import { projectConfigManager } from '../config/project-config.js';
import { parseRepoUrl } from '../services/sync-service.js';
import { logger } from '../utils/logger.js';
import { outputResult, outputError, OutputOptions } from '../utils/output.js';

export interface AuthLoginOptions extends OutputOptions {
  token?: string;
  useGh?: boolean;
}

export async function handleAuthLogin(options: AuthLoginOptions = {}): Promise<void> {
  try {
    const { token, sourceType } = await authService.promptForAuth(options);
    const userInfo = await authService.validateToken(token);

    authService.saveGlobalToken(token, userInfo.username, sourceType);

    outputResult(
      {
        status: 'authenticated',
        username: userInfo.username,
        sourceType,
        scopes: userInfo.scopes,
      },
      options,
      () => {
        logger.success(`Authenticated as @${userInfo.username} via ${sourceType}`);
        logger.info(`Scopes: ${userInfo.scopes.join(', ') || 'none'}`);
        logger.success(`Token saved securely to global profile (~/.evb/auth.json)`);
      }
    );
  } catch (err: unknown) {
    const message = err instanceof Error ? err.message : String(err);
    outputError(message, 'AUTH_ERROR', options);
  }
}

export async function handleAuthStatus(options: OutputOptions = {}): Promise<void> {
  const workspaceRoot = projectConfigManager.findEvbRoot() || undefined;
  const token = authService.resolveToken(undefined, workspaceRoot);

  if (!token) {
    outputResult(
      {
        authenticated: false,
        message: 'No GitHub token configured. Run evb auth login to authenticate.',
      },
      options,
      () => {
        logger.warn('Not authenticated. Run evb auth login or set GITHUB_TOKEN / EVB_GITHUB_TOKEN.');
      }
    );
    return;
  }

  try {
    const userInfo = await authService.validateToken(token);

    let permission = 'unknown';
    if (workspaceRoot) {
      try {
        const config = projectConfigManager.readConfig(workspaceRoot);
        const { owner, repo } = parseRepoUrl(config.source.repository);
        permission = await authService.getRepoPermission(owner, repo, userInfo.username, token);
      } catch {}
    }

    outputResult(
      {
        authenticated: true,
        username: userInfo.username,
        scopes: userInfo.scopes,
        repositoryPermission: permission,
      },
      options,
      () => {
        logger.success(`Authenticated as @${userInfo.username}`);
        logger.info(`Scopes: ${userInfo.scopes.join(', ') || 'none'}`);
        if (permission !== 'unknown') {
          logger.info(`Repository Access Level: ${permission}`);
        }
      }
    );
  } catch (err: unknown) {
    const message = err instanceof Error ? err.message : String(err);
    outputError(message, 'AUTH_VALIDATION_ERROR', options);
  }
}

export async function handleAuthLogout(options: OutputOptions = {}): Promise<void> {
  try {
    authService.clearGlobalToken();
    outputResult(
      {
        status: 'logged_out',
        message: 'Stored credentials cleared.',
      },
      options,
      () => {
        logger.success('Logged out and cleared stored authentication profile.');
      }
    );
  } catch (err: unknown) {
    const message = err instanceof Error ? err.message : String(err);
    outputError(message, 'LOGOUT_ERROR', options);
  }
}