Skip to content

Commit

Permalink
chore(gatsby): Convert get-ssl-cert to typescript (#22447)
Browse files Browse the repository at this point in the history
* chore(gatsby): Convert get-ssl-cert to typescript

* Fix type

* address PR feedback

* fix lint

* fix typecheck

Co-authored-by: Blaine Kasten <[email protected]>
  • Loading branch information
mottox2 and blainekasten authored Jul 17, 2020
1 parent 1807882 commit 8b60a27
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 20 deletions.
8 changes: 6 additions & 2 deletions packages/gatsby/src/commands/develop.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { isCI, slash } from "gatsby-core-utils"
import { createServiceLock } from "gatsby-core-utils/dist/service-lock"
import { UnlockFn } from "gatsby-core-utils/src/service-lock"
import reporter from "gatsby-cli/lib/reporter"
import getSslCert from "../utils/get-ssl-cert"
import { getSslCert } from "../utils/get-ssl-cert"
import { startDevelopProxy } from "../utils/develop-proxy"
import { IProgram, IDebugInfo } from "./types"

Expand Down Expand Up @@ -197,13 +197,17 @@ module.exports = async (program: IProgram): Promise<void> => {
)
}

program.ssl = await getSslCert({
const ssl = await getSslCert({
name: sslHost,
caFile: program[`ca-file`],
certFile: program[`cert-file`],
keyFile: program[`key-file`],
directory: program.directory,
})

if (ssl) {
program.ssl = ssl
}
}

// NOTE(@mxstbr): We need to start the develop proxy before the develop process to ensure
Expand Down
4 changes: 2 additions & 2 deletions packages/gatsby/src/commands/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import { Store, AnyAction } from "redux"
import { IGatsbyState } from "../redux/types"

export interface ICert {
key: string
cert: string
key: Buffer
cert: Buffer
}

export interface IDebugInfo {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,25 +17,34 @@ jest.mock(`devcert`, () => {
}
})

const getDevCert = require(`devcert`).certificateFor
const reporter = require(`gatsby-cli/lib/reporter`)
const getSslCert = require(`../get-ssl-cert`)
import { certificateFor as getDevCert } from "devcert"
import reporter from "gatsby-cli/lib/reporter"
import { getSslCert, IGetSslCertArgs } from "../get-ssl-cert"

describe(`gets ssl certs`, () => {
beforeEach(() => {
// @ts-ignore
reporter.panic.mockClear()
// @ts-ignore
reporter.info.mockClear()
// @ts-ignore
getDevCert.mockClear()
})

describe(`Custom SSL certificate`, () => {
it.each([[{ certFile: `foo` }], [{ keyFile: `bar` }]])(
it.each([
{ name: ``, directory: ``, certFile: `foo` },
{ name: ``, directory: ``, keyFile: `bar` },
])(
`panic if cert and key are not both included`,
args => {
(args: IGetSslCertArgs): void => {
getSslCert(args)

// @ts-ignore
expect(reporter.panic.mock.calls).toMatchSnapshot()
}
)

it(`loads a cert relative to a directory`, () => {
expect(
getSslCert({
Expand All @@ -59,21 +68,25 @@ describe(`gets ssl certs`, () => {
})
describe(`automatic SSL certificate`, () => {
it(`sets up dev cert`, () => {
getSslCert({ name: `mock-cert` })
getSslCert({ name: `mock-cert`, directory: `` })
expect(getDevCert).toBeCalledWith(`mock-cert`, {
getCaPath: true,
skipCertutilInstall: false,
ui: {
getWindowsEncryptionPassword: expect.any(Function),
},
})

// @ts-ignore
expect(reporter.info.mock.calls).toMatchSnapshot()
})
it(`panics if certificate can't be created`, () => {
// @ts-ignore
getDevCert.mockImplementation(() => {
throw new Error(`mock error message`)
})
getSslCert({ name: `mock-cert` })
getSslCert({ name: `mock-cert`, directory: `` })
// @ts-ignore
expect(reporter.panic.mock.calls).toMatchSnapshot()
})
})
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
const report = require(`gatsby-cli/lib/reporter`)
const fs = require(`fs`)
const path = require(`path`)
const os = require(`os`)
const prompts = require(`prompts`)
import report from "gatsby-cli/lib/reporter"
import fs from "fs"
import path from "path"
import os from "os"
import { ICert } from "../commands/types"
import prompts from "prompts"

const absoluteOrDirectory = (directory, filePath) => {
const absoluteOrDirectory = (directory: string, filePath: string): string => {
// Support absolute paths
if (path.isAbsolute(filePath)) {
return filePath
}
return path.join(directory, filePath)
}

const getWindowsEncryptionPassword = async () => {
const getWindowsEncryptionPassword = async (): Promise<string> => {
report.info(
[
`A password is required to access the secure certificate authority key`,
Expand All @@ -33,7 +34,21 @@ const getWindowsEncryptionPassword = async () => {
return results.value
}

module.exports = async ({ name, certFile, keyFile, caFile, directory }) => {
export interface IGetSslCertArgs {
name: string
certFile?: string
keyFile?: string
caFile?: string
directory: string
}

export async function getSslCert({
name,
certFile,
keyFile,
caFile,
directory,
}: IGetSslCertArgs): Promise<ICert | false> {
// check that cert file and key file are both true or both false, if they are both
// false, it defaults to the automatic ssl
if (certFile ? !keyFile : keyFile) {
Expand All @@ -50,7 +65,7 @@ module.exports = async ({ name, certFile, keyFile, caFile, directory }) => {
process.env.NODE_EXTRA_CA_CERTS = caFile
? absoluteOrDirectory(directory, caFile)
: certPath
return await {
return {
key: fs.readFileSync(keyPath),
cert: fs.readFileSync(certPath),
}
Expand Down

0 comments on commit 8b60a27

Please sign in to comment.