diff --git a/packages/expo-cli/src/appleApi/authenticate.ts b/packages/expo-cli/src/appleApi/authenticate.ts index 75a42c7f8f..b73cd1b2d0 100644 --- a/packages/expo-cli/src/appleApi/authenticate.ts +++ b/packages/expo-cli/src/appleApi/authenticate.ts @@ -73,10 +73,12 @@ async function _requestAppleIdCreds(options: Options): Promise } function _getAppleIdFromParams({ appleId, appleIdPassword }: Options): AppleCredentials | null { - const passedAppleIdPassword = appleIdPassword || process.env.EXPO_APPLE_PASSWORD; + const passedAppleIdPassword = appleId + ? appleIdPassword || process.env.EXPO_APPLE_PASSWORD + : undefined; // none of the apple id params were set, assume user has no intention of passing it in - if (!appleId && !passedAppleIdPassword) { + if (!appleId) { return null; } diff --git a/packages/expo-cli/src/commands/build/BaseBuilder.ts b/packages/expo-cli/src/commands/build/BaseBuilder.ts index 4f86babd89..ff3d215374 100644 --- a/packages/expo-cli/src/commands/build/BaseBuilder.ts +++ b/packages/expo-cli/src/commands/build/BaseBuilder.ts @@ -17,8 +17,6 @@ const secondsToMilliseconds = (seconds: number): number => seconds * 1000; export default class BaseBuilder { protected projectConfig: ProjectConfig; manifest: ExpoConfig; - private user?: User; - private loadedUser: boolean = false; async getUserAsync(): Promise { return await UserManager.ensureLoggedInAsync(); diff --git a/packages/expo-cli/src/commands/build/index.ts b/packages/expo-cli/src/commands/build/index.ts index b8d955bfa8..6bed44462b 100644 --- a/packages/expo-cli/src/commands/build/index.ts +++ b/packages/expo-cli/src/commands/build/index.ts @@ -104,7 +104,11 @@ export default function (program: Command) { return; } } - + if (options.skipCredentialsCheck && options.clearCredentials) { + throw new CommandError( + "--skip-credentials-check and --clear-credentials can't be used together" + ); + } if (options.publicUrl && !UrlUtils.isHttps(options.publicUrl)) { throw new CommandError('INVALID_PUBLIC_URL', '--public-url must be a valid HTTPS URL.'); } diff --git a/packages/expo-cli/src/commands/build/ios/IOSBuilder.ts b/packages/expo-cli/src/commands/build/ios/IOSBuilder.ts index e63842ab85..4ce5e7bae1 100644 --- a/packages/expo-cli/src/commands/build/ios/IOSBuilder.ts +++ b/packages/expo-cli/src/commands/build/ios/IOSBuilder.ts @@ -49,8 +49,6 @@ interface AppLookupParams { } class IOSBuilder extends BaseBuilder { - appleCtx?: apple.AppleCtx; - async run(): Promise { // This gets run after all other validation to prevent users from having to answer this question multiple times. this.options.type = await utils.askBuildType(this.options.type!, { @@ -71,14 +69,6 @@ class IOSBuilder extends BaseBuilder { this.maybeWarnDamagedSimulator(); } - async getAppleCtx(): Promise { - if (!this.appleCtx) { - await apple.setup(); - this.appleCtx = await apple.authenticate(this.options); - } - return this.appleCtx; - } - // Try to get the user to provide Apple credentials upfront // We will be able to do full validation of their iOS creds this way async bestEffortAppleCtx(ctx: Context): Promise { @@ -88,7 +78,7 @@ class IOSBuilder extends BaseBuilder { } if (this.options.appleId) { // skip prompts and auto authenticate if flags are passed - return await ctx.ensureAppleCtx(this.options); + return await ctx.ensureAppleCtx(); } const nonInteractive = this.options.parent && this.options.parent.nonInteractive; @@ -104,7 +94,7 @@ class IOSBuilder extends BaseBuilder { }, ]); if (confirm) { - return await ctx.ensureAppleCtx(this.options); + return await ctx.ensureAppleCtx(); } else { log( chalk.green( @@ -151,15 +141,14 @@ class IOSBuilder extends BaseBuilder { bundleIdentifier, }; const context = new Context(); - await context.init(this.projectDir); - - await this.clearAndRevokeCredentialsIfRequested(context, appLookupParams); + await context.init(this.projectDir, this.options); if (this.options.skipCredentialsCheck) { log('Skipping credentials check...'); return; } await this.bestEffortAppleCtx(context); + await this.clearAndRevokeCredentialsIfRequested(context, appLookupParams); try { await this.produceCredentials(context, appLookupParams); diff --git a/packages/expo-cli/src/commands/client/index.ts b/packages/expo-cli/src/commands/client/index.ts index 95721f4f52..58a9937562 100644 --- a/packages/expo-cli/src/commands/client/index.ts +++ b/packages/expo-cli/src/commands/client/index.ts @@ -83,8 +83,8 @@ export default function (program: Command) { const user = await UserManager.getCurrentUserAsync(); const context = new Context(); - await context.init(projectDir, { allowAnonymous: true }); - await context.ensureAppleCtx(options); + await context.init(projectDir, { ...options, allowAnonymous: true }); + await context.ensureAppleCtx(); const appleContext = context.appleCtx; if (user) { await context.ios.getAllCredentials(user.username); // initialize credentials diff --git a/packages/expo-cli/src/credentials/context.ts b/packages/expo-cli/src/credentials/context.ts index bc9682eff3..67d001ca3c 100644 --- a/packages/expo-cli/src/credentials/context.ts +++ b/packages/expo-cli/src/credentials/context.ts @@ -1,5 +1,6 @@ import { ExpoConfig, getConfig } from '@expo/config'; import { ApiV2, Doctor, User, UserManager } from '@expo/xdl'; +import pick from 'lodash/pick'; import { AppleCtx, authenticate } from '../appleApi'; import log from '../log'; @@ -10,14 +11,15 @@ export interface IView { open(ctx: Context): Promise; } -type AppleCtxOptions = { +interface AppleCtxOptions { appleId?: string; appleIdPassword?: string; -}; + teamId?: string; +} -type CtxOptions = { +interface CtxOptions extends AppleCtxOptions { allowAnonymous?: boolean; -}; +} export class Context { _hasProjectContext: boolean = false; @@ -27,6 +29,7 @@ export class Context { _apiClient?: ApiV2; _iosApiClient?: IosApi; _androidApiClient?: AndroidApi; + _appleCtxOptions?: AppleCtxOptions; _appleCtx?: AppleCtx; get user(): User { @@ -67,9 +70,9 @@ export class Context { return !!this._appleCtx; } - async ensureAppleCtx(options: AppleCtxOptions = {}) { + async ensureAppleCtx() { if (!this._appleCtx) { - this._appleCtx = await authenticate(options); + this._appleCtx = await authenticate(this._appleCtxOptions); } } @@ -93,6 +96,7 @@ export class Context { this._apiClient = ApiV2.clientForUser(this.user); this._iosApiClient = new IosApi(this.api); this._androidApiClient = new AndroidApi(this.api); + this._appleCtxOptions = pick(options, ['appleId', 'appleIdPassword', 'teamId']); // Check if we are in project context by looking for a manifest const status = await Doctor.validateWithoutNetworkAsync(projectDir);