Skip to content

Commit

Permalink
issue #2934 fix enterprise CORS issue (#2935)
Browse files Browse the repository at this point in the history
* issue 2934 fix enterprise CORS issue

* fix 0auth login button

* refactored build process

* add manifest tests

* fix 0auth login

Co-authored-by: Tom J <tom@holub.me>
  • Loading branch information
Tom J and Tom J committed Sep 8, 2020
1 parent 5834c1a commit 69ad7cd
Show file tree
Hide file tree
Showing 8 changed files with 132 additions and 96 deletions.
3 changes: 1 addition & 2 deletions build.sh
Expand Up @@ -75,5 +75,4 @@ node ./build/tooling/bundle-content-scripts
cp -r $OUTDIR ./build/chrome-enterprise
cp -r $OUTDIR ./build/chrome-consumer
cp -r $OUTDIR ./build/firefox-consumer
node ./build/tooling/build-manifests
node ./build/tooling/build-types
node ./build/tooling/build-types-and-manifests
5 changes: 2 additions & 3 deletions conf/tsconfig.tooling.json
Expand Up @@ -13,12 +13,11 @@
"outDir": "../build/tooling"
},
"files": [
"../tooling/build-manifests.ts",
"../tooling/build-types-and-manifests.ts",
"../tooling/resolve-modules.ts",
"../tooling/bundle-content-scripts.ts",
"../tooling/fill-values.ts",
"../tooling/tsc-compiler.ts",
"../tooling/build-types.ts"
"../tooling/tsc-compiler.ts"
],
"include": [
"../tooling/tslint-rules/*.ts"
Expand Down
37 changes: 32 additions & 5 deletions test/source/patterns.ts
Expand Up @@ -4,6 +4,10 @@ import * as path from 'path';

import { readFileSync, readdirSync, statSync } from 'fs';

/**
* This test looks for petterns in the source code, as well as in the built product to look for issues.
*/

let errsFound = 0;

const getAllFilesInDir = (dir: string, filePattern: RegExp): string[] => {
Expand All @@ -29,7 +33,7 @@ const hasErrHandledComment = (line: string) => {
return /\/\/ error-handled/.test(line);
};

const validateLine = (line: string, location: string) => {
const validateTypeScriptLine = (line: string, location: string) => {
if (line.match(/\.(innerHTML|outerHTML) ?= ?/) && !hasXssComment(line)) {
console.error(`unchecked xss in ${location}:\n${line}\n`);
errsFound++;
Expand Down Expand Up @@ -60,12 +64,35 @@ const validateLine = (line: string, location: string) => {
}
};

const srcFilePaths = getAllFilesInDir('./extension', /\.ts$/);

for (const srcFilePath of srcFilePaths) {
/**
* lint problems in TS files - the type of issues that we don't have a linter for
*/
for (const srcFilePath of getAllFilesInDir('./extension', /\.ts$/)) {
const lines = readFileSync(srcFilePath).toString().split('\n');
for (let lineIndex = 0; lineIndex < lines.length; lineIndex++) {
validateLine(lines[lineIndex], `${srcFilePath}:${lineIndex + 1}`);
validateTypeScriptLine(lines[lineIndex], `${srcFilePath}:${lineIndex + 1}`);
}
}

/**
* check for problems in manifest file (because dynamically generated)
* https://github.com/FlowCrypt/flowcrypt-browser/issues/2934
*/
const expectedPermissions = ["storage", "tabs", "https://*.google.com/*", "https://www.googleapis.com/*", "https://flowcrypt.com/*", "unlimitedStorage"];
for (const buildType of ['chrome-consumer', 'chrome-enterprise', 'firefox-consumer']) {
const manifest = JSON.parse(readFileSync(`./build/${buildType}/manifest.json`).toString());
for (const expectedPermission of expectedPermissions) {
if (!manifest.permissions.includes(expectedPermission)) {
if (!(expectedPermission === 'unlimitedStorage' && buildType === 'firefox-consumer')) {
console.error(`Missing permission '${expectedPermission}' in ${buildType}/manifest.json`);
errsFound++;
}
}
}
const gmailCs = manifest.content_scripts.find((cs: any) => cs.matches.includes('https://mail.google.com/*'));
if (!gmailCs || !gmailCs.css.length || !gmailCs.js.length) {
console.error(`Missing content_scripts declaration for Gmail in ${buildType}/manifest.json`);
errsFound++;
}
}

Expand Down
7 changes: 4 additions & 3 deletions test/source/tests/page-recipe/oauth-page-recipe.ts
Expand Up @@ -20,7 +20,7 @@ export class OauthPageRecipe extends PageRecipe {
email_confirm_btn: '#identifierNext',
auth0_username: '#username',
auth0_password: '#password',
auth0_login_btn: '._button-login',
auth0_login_btn: 'button', // old: ._button-login
};
try {
await oauthPage.waitAny('#Email, #submit_approve_access, #identifierId, .w6VTHd, #profileIdentifier', { timeout: 45 });
Expand All @@ -47,9 +47,10 @@ export class OauthPageRecipe extends PageRecipe {
}
throw new Error('Oauth page didnt close after login. Should increase timeout or await close event');
}
await oauthPage.waitAny([selectors.approve_button, selectors.auth0_login_btn]);
if (await oauthPage.isElementPresent(selectors.auth0_login_btn)) {
await oauthPage.waitAny([selectors.approve_button, selectors.auth0_username]);
if (await oauthPage.isElementPresent(selectors.auth0_username)) {
await oauthPage.waitAndType(selectors.auth0_username, auth.email);
console.log(oauthPage.target.url());
await oauthPage.waitAndType(selectors.auth0_password, auth.password!);
await oauthPage.waitAndClick(selectors.auth0_login_btn);
await oauthPage.waitForNavigationIfAny();
Expand Down
39 changes: 0 additions & 39 deletions tooling/build-manifests.ts

This file was deleted.

92 changes: 92 additions & 0 deletions tooling/build-types-and-manifests.ts
@@ -0,0 +1,92 @@
import { readFileSync, writeFileSync } from 'fs';
import { execSync as exec } from 'child_process';

// tslint:disable:no-unsafe-any

/**
* This file was originally two files: one that edited manifests, and one that copied build folders and edited mock versions
* These steps somewhat overlap, so the two scripts were joined into one below. However, work was not yet done to assimilate them.
*/

/**
* first, modify appropriate manifests
*/

const DIR = './build';
const version: string = JSON.parse(readFileSync('./package.json').toString()).version;

const addManifest = (toBuildType: string, transform: (manifest: { [k: string]: any }) => void) => {
const manifest = JSON.parse(readFileSync(`${DIR}/generic-extension-wip/manifest.json`).toString());
transform(manifest);
writeFileSync(`${DIR}/${toBuildType}/manifest.json`, JSON.stringify(manifest, undefined, 2));
};

addManifest('chrome-consumer', manifest => {
manifest.version = version;
});

addManifest('firefox-consumer', manifest => {
manifest.version = version;
manifest.applications = { gecko: { id: 'firefox@cryptup.io', update_url: 'https://flowcrypt.com/api/update/firefox', strict_min_version: '60.0' } };
manifest.permissions = manifest.permissions.filter((p: string) => p !== 'unlimitedStorage');
delete manifest.minimum_chrome_version;
});

addManifest('chrome-enterprise', manifest => {
manifest.version = version;
manifest.name = 'FlowCrypt for Enterprise';
manifest.description = 'FlowCrypt Chrome Extension for Enterprise clients (stable)';
// careful - changing this will likely cause all extensions to be disabled in their user's browsers
manifest.permissions = ["storage", "tabs", "https://*.google.com/*", "https://www.googleapis.com/*", "https://flowcrypt.com/*", "unlimitedStorage"];
for (const csDef of manifest.content_scripts) {
csDef.matches = csDef.matches.filter((host: string) => host === 'https://mail.google.com/*');
}
manifest.content_scripts = manifest.content_scripts.filter((csDef: { matches: string[] }) => csDef.matches.length); // remove empty defs
if (!manifest.content_scripts.length) {
throw new Error('Content script defs ended up empty in enterprise manifest');
}
});

/**
* second, build copy and edit enterprise and mock versions
*/

const CHROME_CONSUMER = 'chrome-consumer';
const CHROME_ENTERPRISE = 'chrome-enterprise';
const MOCK_HOST: { [buildType: string]: string } = { 'chrome-consumer': 'http://localhost:8001', 'chrome-enterprise': 'http://google.mock.flowcryptlocal.com:8001' };

const buildDir = (buildType: string) => `./build/${buildType}`;

const edit = (filepath: string, editor: (content: string) => string) => {
writeFileSync(filepath, editor(readFileSync(filepath, { encoding: 'utf-8' })));
};

const makeMockBuild = (buildType: string) => {
const mockBuildType = `${buildType}-mock`;
exec(`cp -r ${buildDir(buildType)} ${buildDir(mockBuildType)}`);
const editor = (code: string) => {
return code
.replace(/const (GOOGLE_API_HOST|GOOGLE_OAUTH_SCREEN_HOST) = [^;]+;/g, `const $1 = '${MOCK_HOST[buildType]}';`)
.replace(/const (BACKEND_API_HOST) = [^;]+;/g, `const $1 = 'http://localhost:8001/api/';`)
.replace(/const (ATTESTER_API_HOST) = [^;]+;/g, `const $1 = 'http://localhost:8001/attester/';`)
.replace(/https:\/\/flowcrypt.com\/api\/help\/error/g, 'http://localhost:8001/api/help/error');
};
edit(`${buildDir(mockBuildType)}/js/common/core/const.js`, editor);
edit(`${buildDir(mockBuildType)}/js/common/platform/catch.js`, editor);
edit(`${buildDir(mockBuildType)}/js/content_scripts/webmail_bundle.js`, editor);
};

const updateEnterpriseBuild = () => {
const constFilepath = `${buildDir(CHROME_ENTERPRISE)}/js/common/core/const.js`;
edit(constFilepath, (code: string) => {
const flavorPattern = /export const FLAVOR = 'consumer';/g;
if (!flavorPattern.test(code)) {
throw new Error(`Expecting to find FLAVOR in ${constFilepath}`);
}
return code.replace(flavorPattern, `export const FLAVOR = 'enterprise';`);
});
};

updateEnterpriseBuild();
makeMockBuild(CHROME_CONSUMER);
makeMockBuild(CHROME_ENTERPRISE);
43 changes: 0 additions & 43 deletions tooling/build-types.ts

This file was deleted.

2 changes: 1 addition & 1 deletion tooling/fill-values.ts
Expand Up @@ -10,7 +10,7 @@ const { compilerOptions: { outDir: targetDirExtension } } = JSON.parse(readFileS
const { compilerOptions: { outDir: targetDirContentScripts } } = JSON.parse(readFileSync('./conf/tsconfig.content_scripts.json').toString());
const { version } = JSON.parse(readFileSync(`./package.json`).toString());

// mock values for a consumer-mock or enterprise-mock test builds are regex-replaced later in `build-types.ts`
// mock values for a consumer-mock or enterprise-mock test builds are regex-replaced later in `build-types-and-manifests.ts`
const replaceables: { needle: RegExp, val: string }[] = [
{ needle: /\[BUILD_REPLACEABLE_VERSION\]/g, val: version },
{ needle: /\[BUILD_REPLACEABLE_FLAVOR\]/g, val: 'consumer' },
Expand Down

0 comments on commit 69ad7cd

Please sign in to comment.