MCPcopy Create free account
hub / github.com/freecodexyz/free-code / saveApiKey

Function saveApiKey

src/utils/auth.ts:1095–1161  ·  view source on GitHub ↗
(apiKey: string)

Source from the content-addressed store, hash-verified

1093}
1094
1095export async function saveApiKey(apiKey: string): Promise<void> {
1096 if (!isValidApiKey(apiKey)) {
1097 throw new Error(
1098 'Invalid API key format. API key must contain only alphanumeric characters, dashes, and underscores.',
1099 )
1100 }
1101
1102 // Store as primary API key
1103 await maybeRemoveApiKeyFromMacOSKeychain()
1104 let savedToKeychain = false
1105 if (process.platform === 'darwin') {
1106 try {
1107 // TODO: migrate to SecureStorage
1108 const storageServiceName = getMacOsKeychainStorageServiceName()
1109 const username = getUsername()
1110
1111 // Convert to hexadecimal to avoid any escaping issues
1112 const hexValue = Buffer.from(apiKey, 'utf-8').toString('hex')
1113
1114 // Use security's interactive mode (-i) with -X (hexadecimal) option
1115 // This ensures credentials never appear in process command-line arguments
1116 // Process monitors only see "security -i", not the password
1117 const command = `add-generic-password -U -a "${username}" -s "${storageServiceName}" -X "${hexValue}"\n`
1118
1119 await execa('security', ['-i'], {
1120 input: command,
1121 reject: false,
1122 })
1123
1124 logEvent('tengu_api_key_saved_to_keychain', {})
1125 savedToKeychain = true
1126 } catch (e) {
1127 logError(e)
1128 logEvent('tengu_api_key_keychain_error', {
1129 error: errorMessage(
1130 e,
1131 ) as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS,
1132 })
1133 logEvent('tengu_api_key_saved_to_config', {})
1134 }
1135 } else {
1136 logEvent('tengu_api_key_saved_to_config', {})
1137 }
1138
1139 const normalizedKey = normalizeApiKeyForConfig(apiKey)
1140
1141 // Save config with all updates
1142 saveGlobalConfig(current => {
1143 const approved = current.customApiKeyResponses?.approved ?? []
1144 return {
1145 ...current,
1146 // Only save to config if keychain save failed or not on darwin
1147 primaryApiKey: savedToKeychain ? current.primaryApiKey : apiKey,
1148 customApiKeyResponses: {
1149 ...current.customApiKeyResponses,
1150 approved: approved.includes(normalizedKey)
1151 ? approved
1152 : [...approved, normalizedKey],

Callers 1

createAndStoreApiKeyFunction · 0.85

Calls 12

isValidApiKeyFunction · 0.85
logEventFunction · 0.85
normalizeApiKeyForConfigFunction · 0.85
saveGlobalConfigFunction · 0.85
logErrorFunction · 0.70
errorMessageFunction · 0.70
toStringMethod · 0.65
getUsernameFunction · 0.50
clearMethod · 0.45

Tested by

no test coverage detected