Skip to content
This repository has been archived by the owner on Jan 18, 2024. It is now read-only.

[expo-cli] turtle-v2 credentials change hasLocal,hasRemote bahviour #2452

Merged
merged 1 commit into from
Aug 12, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ describe('credentialsJson', () => {
it('should throw error when credentials.json is missing', async () => {
const promise = credentialsJson.readAndroidAsync('.');
await expect(promise).rejects.toThrow(
'credentials.json must exist in the project root directory and consist a valid JSON'
'credentials.json must exist in the project root directory and contain a valid JSON'
);
});

Expand Down Expand Up @@ -116,7 +116,7 @@ describe('credentialsJson', () => {
it('should throw error when credentials.json is missing', async () => {
const promise = credentialsJson.readIosAsync('.');
await expect(promise).rejects.toThrow(
'credentials.json must exist in the project root directory and consist a valid JSON'
'credentials.json must exist in the project root directory and contain a valid JSON'
);
});
it('should throw error if ios field is missing', async () => {
Expand Down
25 changes: 14 additions & 11 deletions packages/expo-cli/src/credentials/local/credentialsJson.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,16 +93,7 @@ async function readIosAsync(projectDir: string): Promise<iOSCredentials> {
}

async function readAsync(projectDir: string): Promise<CredentialsJson> {
const credentialsJsonFilePath = path.join(projectDir, 'credentials.json');
let credentialsJSONRaw;
try {
const credentialsJSONContents = await fs.readFile(credentialsJsonFilePath, 'utf8');
credentialsJSONRaw = JSON.parse(credentialsJSONContents);
} catch (err) {
throw new Error(
`credentials.json must exist in the project root directory and consist a valid JSON`
);
}
const credentialsJSONRaw = await readRawAsync(projectDir);

const { value: credentialsJson, error } = CredentialsJsonSchema.validate(credentialsJSONRaw, {
stripUnknown: true,
Expand All @@ -116,7 +107,19 @@ async function readAsync(projectDir: string): Promise<CredentialsJson> {
return credentialsJson;
}

async function readRawAsync(projectDir: string): Promise<any> {
dsokal marked this conversation as resolved.
Show resolved Hide resolved
const credentialsJsonFilePath = path.join(projectDir, 'credentials.json');
try {
const credentialsJSONContents = await fs.readFile(credentialsJsonFilePath, 'utf8');
return JSON.parse(credentialsJSONContents);
} catch (err) {
throw new Error(
`credentials.json must exist in the project root directory and contain a valid JSON`
);
}
}

const getAbsolutePath = (projectDir: string, filePath: string): string =>
path.isAbsolute(filePath) ? filePath : path.join(projectDir, filePath);

export default { readAndroidAsync, readIosAsync, fileExistsAsync };
export default { readAndroidAsync, readIosAsync, readRawAsync, fileExistsAsync };
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { CredentialsSource } from '../../easJson';
import log from '../../log';
import { Context } from '../context';
import { Keystore } from '../credentials';
import { credentialsJson } from '../local';
Expand Down Expand Up @@ -42,9 +43,10 @@ export default class AndroidCredentialsProvider implements CredentialsProvider {
return false;
}
try {
const credentials = await credentialsJson.readAndroidAsync(this.projectDir);
return this.isValidKeystore(credentials.keystore);
const rawCredentialsJson = await credentialsJson.readRawAsync(this.projectDir);
return !!rawCredentialsJson?.android;
} catch (err) {
log.error(err); // malformed json
return false;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ describe('AndroidCredentialsProvider', () => {
const hasLocal = await provider.hasLocalAsync();
expect(hasLocal).toBe(true);
});
it('should return false if there are missing fields', async () => {
it('should return true if there are missing fields', async () => {
vol.fromJSON({
'./credentials.json': JSON.stringify({
android: {
Expand All @@ -107,9 +107,9 @@ describe('AndroidCredentialsProvider', () => {
const provider = new AndroidCredentialsProvider('.', providerOptions);
await provider.initAsync();
const hasLocal = await provider.hasLocalAsync();
expect(hasLocal).toBe(false);
expect(hasLocal).toBe(true);
});
it('should return false if file is missing', async () => {
it('should return true if file is missing', async () => {
vol.fromJSON({
'./credentials.json': JSON.stringify({
android: {
Expand All @@ -125,7 +125,7 @@ describe('AndroidCredentialsProvider', () => {
const provider = new AndroidCredentialsProvider('.', providerOptions);
await provider.initAsync();
const hasLocal = await provider.hasLocalAsync();
expect(hasLocal).toBe(false);
expect(hasLocal).toBe(true);
});
it('should return false if there are no credentials.json file', async () => {
const provider = new AndroidCredentialsProvider('.', providerOptions);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,26 +58,26 @@ describe('iOSCredentialsProvider', () => {
const hasRemote = await provider.hasRemoteAsync();
expect(hasRemote).toBe(true);
});
it('should return false if dist cert is missing', async () => {
it('should return true if dist cert is missing', async () => {
mockGetProvisioningProfile.mockImplementation(() => ({
provisioningProfile: 'profileBase64',
provisioningProfileId: 'id',
}));
const provider = new iOSCredentialsProvider('.', providerOptions);
await provider.initAsync();
const hasRemote = await provider.hasRemoteAsync();
expect(hasRemote).toBe(false);
expect(hasRemote).toBe(true);
});

it('should return false if provisioning profile is missing', async () => {
it('should return true if provisioning profile is missing', async () => {
mockGetDistCert.mockImplementation(() => ({
certP12: 'certbase64',
certPassword: 'fakePassword',
}));
const provider = new iOSCredentialsProvider('.', providerOptions);
await provider.initAsync();
const hasRemote = await provider.hasRemoteAsync();
expect(hasRemote).toBe(false);
expect(hasRemote).toBe(true);
});
it('should return false if there are no credentials', async () => {
const provider = new iOSCredentialsProvider('.', providerOptions);
Expand Down Expand Up @@ -107,7 +107,7 @@ describe('iOSCredentialsProvider', () => {
const hasLocal = await provider.hasLocalAsync();
expect(hasLocal).toBe(true);
});
it('should return false if there are missing fields', async () => {
it('should return true if there are missing fields', async () => {
vol.fromJSON({
'./credentials.json': JSON.stringify({
ios: {
Expand All @@ -124,9 +124,9 @@ describe('iOSCredentialsProvider', () => {
const provider = new iOSCredentialsProvider('.', providerOptions);
await provider.initAsync();
const hasLocal = await provider.hasLocalAsync();
expect(hasLocal).toBe(false);
expect(hasLocal).toBe(true);
});
it('should return false if file is missing', async () => {
it('should return true if file is missing', async () => {
vol.fromJSON({
'./credentials.json': JSON.stringify({
ios: {
Expand All @@ -142,7 +142,7 @@ describe('iOSCredentialsProvider', () => {
const provider = new iOSCredentialsProvider('.', providerOptions);
await provider.initAsync();
const hasLocal = await provider.hasLocalAsync();
expect(hasLocal).toBe(false);
expect(hasLocal).toBe(true);
});
it('should return false if there are no credentials.json file', async () => {
const provider = new iOSCredentialsProvider('.', providerOptions);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { CredentialsSource } from '../../easJson';
import log from '../../log';
import { AppLookupParams } from '../api/IosApi';
import { Context } from '../context';
import { credentialsJson } from '../local';
Expand Down Expand Up @@ -30,17 +31,18 @@ export default class iOSCredentialsProvider implements CredentialsProvider {
public async hasRemoteAsync(): Promise<boolean> {
const distCert = await this.ctx.ios.getDistCert(this.app);
const provisioningProfile = await this.ctx.ios.getProvisioningProfile(this.app);
return !!(distCert && provisioningProfile);
return !!(distCert || provisioningProfile);
}

public async hasLocalAsync(): Promise<boolean> {
if (!(await credentialsJson.fileExistsAsync(this.projectDir))) {
return false;
}
try {
await credentialsJson.readIosAsync(this.projectDir);
return true;
} catch (_) {
const rawCredentialsJson = await credentialsJson.readRawAsync(this.projectDir);
return !!rawCredentialsJson?.ios;
} catch (err) {
log.error(err); // malformed json
return false;
}
}
Expand Down