Skip to content

Commit b526938

Browse files
committed
chore: wip
1 parent 6713f3d commit b526938

File tree

4 files changed

+87
-29
lines changed

4 files changed

+87
-29
lines changed

src/config.ts

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,29 @@
11
import { resolve } from 'node:path'
22
import { loadConfig } from 'c12'
3-
import type { CertOptions } from './types'
3+
import type { TlsOptions } from './types'
44

5-
// Get loaded config
65
const { config } = await loadConfig({
76
name: 'tls',
87
})
98

10-
export async function resolveConfig(options?: CertOptions): Promise<CertOptions> {
11-
const def: CertOptions = {
12-
hostCertCN: 'Stacks tlsx RootCA',
13-
domain: 'stacks.localhost',
14-
rootCAObject: {
15-
certificate: '',
16-
privateKey: '',
9+
export async function resolveConfig(options?: TlsOptions): Promise<TlsOptions> {
10+
const def: TlsOptions = {
11+
ssl: {
12+
hostCertCN: 'Stacks tlsx RootCA',
13+
domain: 'stacks.localhost',
14+
rootCAObject: {
15+
certificate: '',
16+
privateKey: '',
17+
},
18+
altNameIPs: ['127.0.0.1'],
19+
altNameURIs: ['localhost'],
20+
validityDays: 1,
21+
organizationName: 'Stacks.js',
22+
countryName: 'US',
23+
stateName: 'California',
24+
localityName: 'Playa Vista',
25+
commonName: 'stacks.localhost',
1726
},
18-
altNameIPs: ['127.0.0.1'],
19-
altNameURIs: ['localhost'],
20-
validityDays: 1,
21-
organizationName: 'Stacks.js',
22-
countryName: 'US',
23-
stateName: 'California',
24-
localityName: 'Playa Vista',
25-
commonName: 'stacks.localhost',
2627
}
2728

2829
let { config } = await loadConfig({

src/keys.ts

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import path from 'node:path'
44
import { log, runCommand } from '@stacksjs/cli'
55
import forge, { pki, tls } from 'node-forge'
66
import { config, resolveConfig } from './config'
7-
import type { AddCertOptions, CertOptions } from './types'
7+
import type { AddCertOptions, CertOptions, GenerateCertReturn } from './types'
88

99
/**
1010
* Generate a random serial number for the Certificate
@@ -107,13 +107,6 @@ export async function createRootCA(): Promise<GenerateCertReturn> {
107107
}
108108
}
109109

110-
type GenerateCertReturn = {
111-
certificate: string
112-
privateKey: string
113-
notBefore: Date
114-
notAfter: Date
115-
}
116-
117110
/**
118111
* Generate a new Host Certificate
119112
* @param options - The options for generating the certificate

src/types.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ export type DeepPartial<T> = {
44

55
export interface TlsOptions {
66
ssl: {
7+
hostCertCN: string
8+
domain: string
9+
rootCAObject: { certificate: string; privateKey: string }
710
altNameIPs: string[]
811
altNameURIs: string[]
912
commonName: string
@@ -29,7 +32,7 @@ export interface CertOptions {
2932
commonName?: string
3033
}
3134

32-
export type CertDetails = {
35+
export interface CertDetails {
3336
subject: any
3437
issuer: any
3538
validFrom: Date
@@ -41,4 +44,11 @@ export interface AddCertOptions {
4144
customCertPath?: string
4245
}
4346

47+
export interface GenerateCertReturn {
48+
certificate: string
49+
privateKey: string
50+
notBefore: Date
51+
notAfter: Date
52+
}
53+
4454
export type TlsConfig = DeepPartial<TlsOptions>

test/tlsx.test.ts

Lines changed: 57 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,61 @@
11
import { describe, expect, it } from 'bun:test'
2+
import { createRootCA, generateCert, isCertExpired, isCertValidForDomain, parseCertDetails } from '../src'
3+
import type { CertOptions } from '../src/types'
24

3-
describe('should', () => {
4-
it('exported', () => {
5-
expect(1).toEqual(1)
5+
describe('@stacksjs/tlsx', () => {
6+
it('should create a Root CA certificate', async () => {
7+
const rootCA = await createRootCA()
8+
expect(rootCA).toHaveProperty('certificate')
9+
expect(rootCA).toHaveProperty('privateKey')
10+
expect(rootCA).toHaveProperty('notBefore')
11+
expect(rootCA).toHaveProperty('notAfter')
12+
})
13+
14+
it('should generate a host certificate', async () => {
15+
const rootCA = await createRootCA()
16+
const options: CertOptions = {
17+
hostCertCN: 'localhost',
18+
domain: 'localhost',
19+
rootCAObject: {
20+
certificate: rootCA.certificate,
21+
privateKey: rootCA.privateKey,
22+
},
23+
}
24+
const hostCert = await generateCert(options)
25+
expect(hostCert).toHaveProperty('certificate')
26+
expect(hostCert).toHaveProperty('privateKey')
27+
expect(hostCert).toHaveProperty('notBefore')
28+
expect(hostCert).toHaveProperty('notAfter')
29+
})
30+
31+
it('should validate a certificate for a domain', async () => {
32+
const rootCA = await createRootCA()
33+
const options: CertOptions = {
34+
hostCertCN: 'localhost',
35+
domain: 'localhost',
36+
rootCAObject: {
37+
certificate: rootCA.certificate,
38+
privateKey: rootCA.privateKey,
39+
},
40+
}
41+
const hostCert = await generateCert(options)
42+
const isValid = isCertValidForDomain(hostCert.certificate, 'localhost')
43+
expect(isValid).toBe(true)
44+
})
45+
46+
it('should parse certificate details', async () => {
47+
const rootCA = await createRootCA()
48+
const certDetails = parseCertDetails(rootCA.certificate)
49+
expect(certDetails).toHaveProperty('subject')
50+
expect(certDetails).toHaveProperty('issuer')
51+
expect(certDetails).toHaveProperty('validFrom')
52+
expect(certDetails).toHaveProperty('validTo')
53+
expect(certDetails).toHaveProperty('serialNumber')
54+
})
55+
56+
it('should check if a certificate is expired', async () => {
57+
const rootCA = await createRootCA()
58+
const isExpired = isCertExpired(rootCA.certificate)
59+
expect(isExpired).toBe(false)
660
})
761
})

0 commit comments

Comments
 (0)