Certificate and token generation fixes
Summary: A few things need to be done which are on this change: - Certificate generation should execute as an atomic operation, hence, it needs to be synchronised. - Do not generate client token as part of certificate generation. This causes a deadlock now. - Add more logs for troubleshooting Reviewed By: aigoncharov Differential Revision: D49269624 fbshipit-source-id: 071a8e5b895198730b7d914cc4622837e9094e2f
This commit is contained in:
committed by
Facebook GitHub Bot
parent
cf599f9c3c
commit
2b4c631652
@@ -21,6 +21,7 @@ import {isTest} from 'flipper-common';
|
|||||||
import {flipperDataFolder} from '../../utils/paths';
|
import {flipperDataFolder} from '../../utils/paths';
|
||||||
import * as jwt from 'jsonwebtoken';
|
import * as jwt from 'jsonwebtoken';
|
||||||
import {getFlipperServerConfig} from '../../FlipperServerConfig';
|
import {getFlipperServerConfig} from '../../FlipperServerConfig';
|
||||||
|
import {Mutex} from 'async-mutex';
|
||||||
|
|
||||||
const tmpFile = promisify(tmp.file) as (
|
const tmpFile = promisify(tmp.file) as (
|
||||||
options?: FileOptions,
|
options?: FileOptions,
|
||||||
@@ -152,7 +153,9 @@ const certificateSetup = async () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const mutex = new Mutex();
|
||||||
const ensureServerCertExists = async (): Promise<void> => {
|
const ensureServerCertExists = async (): Promise<void> => {
|
||||||
|
return mutex.runExclusive(async () => {
|
||||||
const allExist = await Promise.all([
|
const allExist = await Promise.all([
|
||||||
fs.pathExists(serverKey),
|
fs.pathExists(serverKey),
|
||||||
fs.pathExists(serverCert),
|
fs.pathExists(serverCert),
|
||||||
@@ -161,23 +164,19 @@ const ensureServerCertExists = async (): Promise<void> => {
|
|||||||
|
|
||||||
if (!allExist) {
|
if (!allExist) {
|
||||||
console.info('No certificates were found, generating new ones');
|
console.info('No certificates were found, generating new ones');
|
||||||
|
|
||||||
await generateServerCertificate();
|
await generateServerCertificate();
|
||||||
await generateAuthToken();
|
} else {
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
console.info('Checking for certificates validity');
|
console.info('Checking for certificates validity');
|
||||||
await checkCertIsValid(serverCert);
|
await checkCertIsValid(serverCert);
|
||||||
console.info('Checking certificate was issued by current CA');
|
console.info('Checking certificate was issued by current CA');
|
||||||
await verifyServerCertWasIssuedByCA();
|
await verifyServerCertWasIssuedByCA();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.warn('Not all certs are valid, generating new ones', e);
|
console.warn('Not all certificates are valid, generating new ones', e);
|
||||||
await generateServerCertificate();
|
await generateServerCertificate();
|
||||||
await generateAuthToken();
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const generateServerCertificate = async (): Promise<void> => {
|
const generateServerCertificate = async (): Promise<void> => {
|
||||||
@@ -309,6 +308,9 @@ const exportTokenToManifest = async (
|
|||||||
|
|
||||||
export const generateAuthToken = async () => {
|
export const generateAuthToken = async () => {
|
||||||
console.info('Generate client authentication token');
|
console.info('Generate client authentication token');
|
||||||
|
|
||||||
|
await ensureServerCertExists();
|
||||||
|
|
||||||
const config = getFlipperServerConfig();
|
const config = getFlipperServerConfig();
|
||||||
|
|
||||||
const privateKey = await fs.readFile(serverKey);
|
const privateKey = await fs.readFile(serverKey);
|
||||||
|
|||||||
@@ -235,6 +235,9 @@ async function start() {
|
|||||||
`[flipper-server][bootstrap] FlipperServer created (${serverCreatedMS} ms)`,
|
`[flipper-server][bootstrap] FlipperServer created (${serverCreatedMS} ms)`,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// At this point, the HTTP server is ready and configuration is set.
|
||||||
|
await launch();
|
||||||
|
|
||||||
const t6 = performance.now();
|
const t6 = performance.now();
|
||||||
const launchedMS = t6 - t5;
|
const launchedMS = t6 - t5;
|
||||||
|
|
||||||
@@ -263,9 +266,6 @@ async function start() {
|
|||||||
}
|
}
|
||||||
await flipperServer.connect();
|
await flipperServer.connect();
|
||||||
|
|
||||||
// At this point, the HTTP server is ready and configuration is set.
|
|
||||||
await launch();
|
|
||||||
|
|
||||||
const t8 = performance.now();
|
const t8 = performance.now();
|
||||||
const appServerStartedMS = t8 - t7;
|
const appServerStartedMS = t8 - t7;
|
||||||
console.info(
|
console.info(
|
||||||
@@ -309,6 +309,8 @@ async function launch() {
|
|||||||
console.info('[flipper-server] Launch UI');
|
console.info('[flipper-server] Launch UI');
|
||||||
const token = await getAuthToken();
|
const token = await getAuthToken();
|
||||||
|
|
||||||
|
console.info('[flipper-server] Token is available: ' + token !== undefined);
|
||||||
|
|
||||||
const searchParams = new URLSearchParams({token: token ?? ''});
|
const searchParams = new URLSearchParams({token: token ?? ''});
|
||||||
const url = new URL(`http://localhost:${argv.port}?${searchParams}`);
|
const url = new URL(`http://localhost:${argv.port}?${searchParams}`);
|
||||||
|
|
||||||
|
|||||||
@@ -41,6 +41,8 @@ async function start() {
|
|||||||
token = manifest.token;
|
token = manifest.token;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.info('Token is available: ' + token !== undefined && token?.length);
|
||||||
|
|
||||||
const openPlugin = params.get('open-plugin');
|
const openPlugin = params.get('open-plugin');
|
||||||
if (openPlugin) {
|
if (openPlugin) {
|
||||||
function removePrefix(input: string, prefix: string): string {
|
function removePrefix(input: string, prefix: string): string {
|
||||||
|
|||||||
Reference in New Issue
Block a user