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

Commit

Permalink
Add owner field support to expo start (#2329)
Browse files Browse the repository at this point in the history
Fixes #2242.
  • Loading branch information
fson authored Jul 3, 2020
1 parent 80b9197 commit 553eb01
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 27 deletions.
62 changes: 35 additions & 27 deletions packages/xdl/src/Project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1991,34 +1991,14 @@ function getManifestHandler(projectRoot: string) {
if (!currentSession || Config.offline) {
manifest.id = `@${ANONYMOUS_USERNAME}/${manifest.slug}-${hostUUID}`;
}
let manifestString = JSON.stringify(manifest);
let manifestString;
if (req.headers['exponent-accept-signature']) {
if (_cachedSignedManifest.manifestString === manifestString) {
manifestString = _cachedSignedManifest.signedManifest;
} else {
if (!currentSession || Config.offline) {
const unsignedManifest = {
manifestString,
signature: 'UNSIGNED',
};
_cachedSignedManifest.manifestString = manifestString;
manifestString = JSON.stringify(unsignedManifest);
_cachedSignedManifest.signedManifest = manifestString;
} else {
let publishInfo = await Exp.getPublishInfoAsync(projectRoot);
const user = await UserManager.ensureLoggedInAsync();

const api = ApiV2.clientForUser(user);
const signedManifest = await api.postAsync('manifest/sign', {
args: publishInfo.args,
manifest,
});

_cachedSignedManifest.manifestString = manifestString;
_cachedSignedManifest.signedManifest = signedManifest.response;
manifestString = signedManifest.response;
}
}
manifestString =
!currentSession || Config.offline
? getUnsignedManifestString(manifest)
: await getSignedManifestStringAsync(manifest, currentSession);
} else {
manifestString = JSON.stringify(manifest);
}
const hostInfo = {
host: hostUUID,
Expand Down Expand Up @@ -2047,6 +2027,34 @@ function getManifestHandler(projectRoot: string) {
};
}

export async function getSignedManifestStringAsync(
manifest: ExpoConfig,
currentSession: { sessionSecret: string }
) {
const manifestString = JSON.stringify(manifest);
if (_cachedSignedManifest.manifestString === manifestString) {
return _cachedSignedManifest.signedManifest;
}
const { response } = await ApiV2.clientForUser(currentSession).postAsync('manifest/sign', {
args: {
remoteUsername: manifest.owner ?? (await UserManager.getCurrentUsernameAsync()),
remotePackageName: manifest.slug,
},
manifest,
});
_cachedSignedManifest.manifestString = manifestString;
_cachedSignedManifest.signedManifest = response;
return response;
}

export function getUnsignedManifestString(manifest: ExpoConfig) {
const unsignedManifest = {
manifestString: JSON.stringify(manifest),
signature: 'UNSIGNED',
};
return JSON.stringify(unsignedManifest);
}

export async function startExpoServerAsync(projectRoot: string): Promise<void> {
_assertValidProjectRoot(projectRoot);
await stopExpoServerAsync(projectRoot);
Expand Down
68 changes: 68 additions & 0 deletions packages/xdl/src/__tests__/Project-test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { ExpoConfig } from '@expo/config';
import axios from 'axios';

import { getSignedManifestStringAsync, getUnsignedManifestString } from '../Project';

jest.mock('axios');

const mockManifest: ExpoConfig = {
name: 'Hello',
slug: 'hello-world',
owner: 'ownername',
version: '1.0.0',
platforms: ['ios'],
};

const mockSignedManifestResponse = JSON.stringify({
manifestString: JSON.stringify(mockManifest),
signature: 'SIGNATURE_HERE',
version: '1.0.0',
});

describe('getSignedManifestStringAsync', () => {
it('calls the server API to sign a manifest', async () => {
const requestFunction = axios.request as jest.MockedFunction<typeof axios.request>;
requestFunction.mockReturnValueOnce(
Promise.resolve({
status: 200,
data: { data: { response: mockSignedManifestResponse } },
})
);
const manifestString = await getSignedManifestStringAsync(mockManifest, {
sessionSecret: 'SECRET',
});
expect(manifestString).toBe(mockSignedManifestResponse);
expect(requestFunction.mock.calls[0][0]).toMatchInlineSnapshot(`
Object {
"data": Object {
"args": Object {
"remotePackageName": "hello-world",
"remoteUsername": "ownername",
},
"manifest": Object {
"name": "Hello",
"owner": "ownername",
"platforms": Array [
"ios",
],
"slug": "hello-world",
"version": "1.0.0",
},
},
"headers": Object {
"Expo-Session": "SECRET",
"Exponent-Client": "xdl",
},
"maxContentLength": 104857600,
"method": "post",
"url": "https://exp.host/--/api/v2/manifest/sign",
}
`);
});
});

describe('getUnsignedManifestString', () => {
it('returns a stringified manifest with the same shape a server-signed manifest', () => {
expect(getUnsignedManifestString(mockManifest)).toMatchSnapshot();
});
});
3 changes: 3 additions & 0 deletions packages/xdl/src/__tests__/__snapshots__/Project-test.ts.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`getUnsignedManifestString returns a stringified manifest with the same shape a server-signed manifest 1`] = `"{\\"manifestString\\":\\"{\\\\\\"name\\\\\\":\\\\\\"Hello\\\\\\",\\\\\\"slug\\\\\\":\\\\\\"hello-world\\\\\\",\\\\\\"owner\\\\\\":\\\\\\"ownername\\\\\\",\\\\\\"version\\\\\\":\\\\\\"1.0.0\\\\\\",\\\\\\"platforms\\\\\\":[\\\\\\"ios\\\\\\"]}\\",\\"signature\\":\\"UNSIGNED\\"}"`;

0 comments on commit 553eb01

Please sign in to comment.