()
| 18 | * clipboard and browser integration don't work. |
| 19 | */ |
| 20 | export async function runPlainLogin(): Promise<void> { |
| 21 | const fingerprintId = await getFingerprintId() |
| 22 | |
| 23 | console.log() |
| 24 | console.log(bold(IS_FREEBUFF ? 'Freebuff Login' : 'Codebuff Login')) |
| 25 | console.log() |
| 26 | console.log('Generating login URL...') |
| 27 | |
| 28 | let loginData |
| 29 | try { |
| 30 | loginData = await generateLoginUrl( |
| 31 | { logger }, |
| 32 | { baseUrl: LOGIN_WEBSITE_URL, fingerprintId }, |
| 33 | ) |
| 34 | } catch (error) { |
| 35 | console.error( |
| 36 | red( |
| 37 | `Failed to generate login URL: ${ |
| 38 | error instanceof Error ? error.message : String(error) |
| 39 | }`, |
| 40 | ), |
| 41 | ) |
| 42 | process.exit(1) |
| 43 | } |
| 44 | |
| 45 | console.log() |
| 46 | console.log('Open this URL in your browser to log in:') |
| 47 | console.log() |
| 48 | console.log(cyan(loginData.loginUrl)) |
| 49 | console.log() |
| 50 | console.log(yellow('Please open the URL above manually to complete login.')) |
| 51 | console.log() |
| 52 | console.log('Waiting for login...') |
| 53 | |
| 54 | const sleep = (ms: number) => |
| 55 | new Promise<void>((resolve) => { |
| 56 | setTimeout(resolve, ms) |
| 57 | }) |
| 58 | |
| 59 | const result = await pollLoginStatus( |
| 60 | { sleep, logger }, |
| 61 | { |
| 62 | baseUrl: LOGIN_WEBSITE_URL, |
| 63 | fingerprintId, |
| 64 | fingerprintHash: loginData.fingerprintHash, |
| 65 | expiresAt: loginData.expiresAt, |
| 66 | }, |
| 67 | ) |
| 68 | |
| 69 | if (result.status === 'success') { |
| 70 | const user = result.user as User |
| 71 | saveUserCredentials(user) |
| 72 | console.log() |
| 73 | console.log(green(`✓ Logged in as ${user.name} (${user.email})`)) |
| 74 | console.log() |
| 75 | const cliName = IS_FREEBUFF ? 'freebuff' : 'codebuff' |
| 76 | console.log('You can now run ' + cyan(cliName) + ' to start.') |
| 77 | process.exit(0) |
no test coverage detected