| 59 | } |
| 60 | |
| 61 | export const loginAuthenticator = ( |
| 62 | credentialsFile: string, |
| 63 | profileName: string, |
| 64 | clientIdProvider: ClientIdProvider, |
| 65 | userAgent: string, |
| 66 | ): Authenticator => { |
| 67 | let authenticationInfo: AuthenticationInfo | undefined |
| 68 | |
| 69 | const logger = log4js.getLogger('login-authenticator') |
| 70 | logger.trace('constructing a LoginAuthenticator') |
| 71 | |
| 72 | const cliDir = path.dirname(credentialsFile) |
| 73 | mkdirSync(cliDir, { recursive: true }) |
| 74 | |
| 75 | const readCredentialsFile = (): CredentialsFileData => { |
| 76 | try { |
| 77 | return JSON.parse(readFileSync(credentialsFile).toString()) |
| 78 | } catch (err) { |
| 79 | if (err.code !== 'ENOENT') { throw err } |
| 80 | } |
| 81 | |
| 82 | return {} |
| 83 | } |
| 84 | |
| 85 | const clientId = clientIdProvider.clientId |
| 86 | const credentialsFileData = readCredentialsFile() |
| 87 | const profileEnvKey = `${profileName}:${clientIdProvider.baseURL.replace(/https:\/\//, '')}` |
| 88 | if (profileEnvKey in credentialsFileData) { |
| 89 | const authInfo = credentialsFileData[profileEnvKey] |
| 90 | authenticationInfo = { |
| 91 | ...authInfo, |
| 92 | expires: new Date(authInfo.expires), |
| 93 | } |
| 94 | logger.trace(`authentication info from file = ${scrubAuthInfo(authenticationInfo)}`) |
| 95 | } |
| 96 | |
| 97 | const postConfig: AxiosRequestConfig = { |
| 98 | headers: { |
| 99 | /* eslint-disable @typescript-eslint/naming-convention */ |
| 100 | 'Content-Type': 'application/x-www-form-urlencoded', |
| 101 | 'User-Agent': userAgent, |
| 102 | /* eslint-enable @typescript-eslint/naming-convention */ |
| 103 | }, |
| 104 | } |
| 105 | |
| 106 | const sha256 = (data: BinaryLike): Buffer => createHash('sha256').update(data).digest() |
| 107 | |
| 108 | const writeCredentialsFile = (credentialsFileData: CredentialsFileData): void => { |
| 109 | writeFileSync(credentialsFile, JSON.stringify(credentialsFileData, null, 4)) |
| 110 | chmod(credentialsFile, 0o600, error => { |
| 111 | if (error) { |
| 112 | logger.error('failed to set permissions on credentials file', error) |
| 113 | } |
| 114 | }) |
| 115 | } |
| 116 | |
| 117 | // eslint-disable-next-line @typescript-eslint/no-explicit-any |
| 118 | const updateTokenFromResponse = (response: AxiosResponse<any>): void => { |