notarize-options.mjs 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. import { execFile } from 'node:child_process'
  2. import { isEnvFlagEnabled } from '../libs/build-env.mjs'
  3. function getPasswordFromKeychain(account, service) {
  4. return new Promise((resolve, reject) => {
  5. execFile(
  6. 'security',
  7. ['find-generic-password', '-a', account, '-s', service, '-w'],
  8. (error, stdout, stderr) => {
  9. if (error) {
  10. reject(new Error(stderr || error.message))
  11. return
  12. }
  13. resolve(stdout.trim())
  14. },
  15. )
  16. })
  17. }
  18. export async function prepareNotarizeEnv(env = process.env) {
  19. if (isEnvFlagEnabled(env.SKIP_NOTARIZATION) || env.MAKE_FOR === 'dev') {
  20. return env
  21. }
  22. if (!env.APPLE_TEAM_ID && env.TEAM_ID) {
  23. env.APPLE_TEAM_ID = env.TEAM_ID
  24. }
  25. const hasCompleteCredentials =
  26. !!env.APPLE_KEYCHAIN_PROFILE ||
  27. (!!env.APPLE_API_KEY && !!env.APPLE_API_KEY_ID && !!env.APPLE_API_ISSUER) ||
  28. (!!env.APPLE_ID && !!env.APPLE_APP_SPECIFIC_PASSWORD && !!env.APPLE_TEAM_ID)
  29. if (hasCompleteCredentials || !env.APPLE_ID) {
  30. return env
  31. }
  32. try {
  33. env.APPLE_APP_SPECIFIC_PASSWORD = await getPasswordFromKeychain(
  34. env.APPLE_ID,
  35. `Apple Notarize: ${env.APPLE_ID}`,
  36. )
  37. } catch (error) {
  38. console.log(`Legacy notarization keychain lookup skipped: ${error.message}`)
  39. }
  40. return env
  41. }
  42. export function hasNotarizeCredentials(env = process.env) {
  43. return Boolean(
  44. env.APPLE_KEYCHAIN_PROFILE ||
  45. (env.APPLE_API_KEY && env.APPLE_API_KEY_ID && env.APPLE_API_ISSUER) ||
  46. (env.APPLE_ID && env.APPLE_APP_SPECIFIC_PASSWORD && env.APPLE_TEAM_ID),
  47. )
  48. }
  49. export async function getNotarizeOptions(appPath, env = process.env) {
  50. await prepareNotarizeEnv(env)
  51. const {
  52. APPLE_API_KEY: appleApiKey,
  53. APPLE_API_KEY_ID: appleApiKeyId,
  54. APPLE_API_ISSUER: appleApiIssuer,
  55. APPLE_ID: appleId,
  56. APPLE_APP_SPECIFIC_PASSWORD: appleIdPassword,
  57. APPLE_KEYCHAIN: keychain,
  58. APPLE_KEYCHAIN_PROFILE: keychainProfile,
  59. APPLE_TEAM_ID: teamId,
  60. } = env
  61. const tool = 'notarytool'
  62. if (appleId || appleIdPassword) {
  63. if (!appleId) {
  64. throw new Error('APPLE_ID env var needs to be set')
  65. }
  66. if (!appleIdPassword) {
  67. throw new Error('APPLE_APP_SPECIFIC_PASSWORD env var needs to be set')
  68. }
  69. if (!teamId) {
  70. throw new Error('APPLE_TEAM_ID env var needs to be set')
  71. }
  72. return { tool, appPath, appleId, appleIdPassword, teamId }
  73. }
  74. if (appleApiKey || appleApiKeyId || appleApiIssuer) {
  75. if (!appleApiKey || !appleApiKeyId || !appleApiIssuer) {
  76. throw new Error('Env vars APPLE_API_KEY, APPLE_API_KEY_ID and APPLE_API_ISSUER need to be set')
  77. }
  78. return { tool, appPath, appleApiKey, appleApiKeyId, appleApiIssuer }
  79. }
  80. if (keychainProfile) {
  81. return {
  82. tool,
  83. appPath,
  84. keychainProfile,
  85. ...(keychain ? { keychain } : {}),
  86. }
  87. }
  88. return null
  89. }