ci: set private key from env (#6239)
This commit is contained in:
2
.github/actions/deploy/deploy.mjs
vendored
2
.github/actions/deploy/deploy.mjs
vendored
@@ -111,7 +111,7 @@ const createHelmCommand = ({ isDryRun }) => {
|
|||||||
`--set-string graphql.app.oauth.google.clientSecret="${AFFINE_GOOGLE_CLIENT_SECRET}"`,
|
`--set-string graphql.app.oauth.google.clientSecret="${AFFINE_GOOGLE_CLIENT_SECRET}"`,
|
||||||
`--set-string graphql.app.payment.stripe.apiKey="${STRIPE_API_KEY}"`,
|
`--set-string graphql.app.payment.stripe.apiKey="${STRIPE_API_KEY}"`,
|
||||||
`--set-string graphql.app.payment.stripe.webhookKey="${STRIPE_WEBHOOK_KEY}"`,
|
`--set-string graphql.app.payment.stripe.webhookKey="${STRIPE_WEBHOOK_KEY}"`,
|
||||||
`--set graphql.app.experimental.enableJwstCodec=${isInternal}`,
|
`--set graphql.app.experimental.enableJwstCodec=${namespace === 'dev'}`,
|
||||||
`--set graphql.app.features.earlyAccessPreview=false`,
|
`--set graphql.app.features.earlyAccessPreview=false`,
|
||||||
`--set graphql.app.features.syncClientVersionCheck=true`,
|
`--set graphql.app.features.syncClientVersionCheck=true`,
|
||||||
`--set sync.replicaCount=${syncReplicaCount}`,
|
`--set sync.replicaCount=${syncReplicaCount}`,
|
||||||
|
|||||||
@@ -61,18 +61,3 @@ Create the name of the service account to use
|
|||||||
{{- default "default" .Values.serviceAccount.name }}
|
{{- default "default" .Values.serviceAccount.name }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
|
|
||||||
{{- define "jwt.key" -}}
|
|
||||||
{{- $secret := lookup "v1" "Secret" .Release.Namespace .Values.app.jwt.secretName -}}
|
|
||||||
{{- if and $secret $secret.data.private -}}
|
|
||||||
{{/*
|
|
||||||
Reusing existing secret data
|
|
||||||
*/}}
|
|
||||||
key: {{ $secret.data.private }}
|
|
||||||
{{- else -}}
|
|
||||||
{{/*
|
|
||||||
Generate new data
|
|
||||||
*/}}
|
|
||||||
key: {{ genPrivateKey "ecdsa" | b64enc }}
|
|
||||||
{{- end -}}
|
|
||||||
{{- end -}}
|
|
||||||
|
|||||||
@@ -28,10 +28,10 @@ spec:
|
|||||||
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
|
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
|
||||||
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
||||||
env:
|
env:
|
||||||
- name: AUTH_PRIVATE_KEY
|
- name: AFFINE_PRIVATE_KEY
|
||||||
valueFrom:
|
valueFrom:
|
||||||
secretKeyRef:
|
secretKeyRef:
|
||||||
name: "{{ .Values.app.jwt.secretName }}"
|
name: "{{ .Values.global.secret.secretName }}"
|
||||||
key: key
|
key: key
|
||||||
- name: NODE_ENV
|
- name: NODE_ENV
|
||||||
value: "{{ .Values.env }}"
|
value: "{{ .Values.env }}"
|
||||||
@@ -45,8 +45,6 @@ spec:
|
|||||||
value: "graphql"
|
value: "graphql"
|
||||||
- name: AFFINE_ENV
|
- name: AFFINE_ENV
|
||||||
value: "{{ .Release.Namespace }}"
|
value: "{{ .Release.Namespace }}"
|
||||||
- name: NEXTAUTH_URL
|
|
||||||
value: "{{ .Values.global.ingress.host }}"
|
|
||||||
- name: DATABASE_PASSWORD
|
- name: DATABASE_PASSWORD
|
||||||
valueFrom:
|
valueFrom:
|
||||||
secretKeyRef:
|
secretKeyRef:
|
||||||
|
|||||||
@@ -1,7 +0,0 @@
|
|||||||
apiVersion: v1
|
|
||||||
kind: Secret
|
|
||||||
metadata:
|
|
||||||
name: "{{ .Values.app.jwt.secretName }}"
|
|
||||||
type: Opaque
|
|
||||||
data:
|
|
||||||
{{- ( include "jwt.key" . ) | indent 2 -}}
|
|
||||||
18
.github/helm/affine/charts/graphql/templates/secret.yaml
vendored
Normal file
18
.github/helm/affine/charts/graphql/templates/secret.yaml
vendored
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
{{- $privateKey := default (genPrivateKey "ecdsa") .Values.global.secret.privateKey | b64enc | quote }}
|
||||||
|
|
||||||
|
{{- if not .Values.global.secret.privateKey }}
|
||||||
|
{{- $existingKey := (lookup "v1" "Secret" .Release.Namespace .Values.global.secret.secretName) }}
|
||||||
|
{{- if $existingKey }}
|
||||||
|
{{- $privateKey = index $existingKey.data "key" }}
|
||||||
|
{{- end -}}
|
||||||
|
{{- end -}}
|
||||||
|
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: {{ .Values.global.secret.secretName }}
|
||||||
|
annotations:
|
||||||
|
"helm.sh/resource-policy": "keep"
|
||||||
|
type: Opaque
|
||||||
|
data:
|
||||||
|
key: {{ $privateKey }}
|
||||||
@@ -19,10 +19,6 @@ app:
|
|||||||
https: true
|
https: true
|
||||||
doc:
|
doc:
|
||||||
mergeInterval: "3000"
|
mergeInterval: "3000"
|
||||||
jwt:
|
|
||||||
secretName: jwt-private-key
|
|
||||||
# base64 encoded ecdsa private key
|
|
||||||
privateKey: ''
|
|
||||||
captcha:
|
captcha:
|
||||||
enable: false
|
enable: false
|
||||||
secretName: captcha
|
secretName: captcha
|
||||||
|
|||||||
@@ -32,6 +32,11 @@ spec:
|
|||||||
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
|
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
|
||||||
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
||||||
env:
|
env:
|
||||||
|
- name: AFFINE_PRIVATE_KEY
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: "{{ .Values.global.secret.secretName }}"
|
||||||
|
key: key
|
||||||
- name: NODE_ENV
|
- name: NODE_ENV
|
||||||
value: "{{ .Values.env }}"
|
value: "{{ .Values.env }}"
|
||||||
- name: NO_COLOR
|
- name: NO_COLOR
|
||||||
@@ -40,8 +45,6 @@ spec:
|
|||||||
value: "affine"
|
value: "affine"
|
||||||
- name: SERVER_FLAVOR
|
- name: SERVER_FLAVOR
|
||||||
value: "sync"
|
value: "sync"
|
||||||
- name: NEXTAUTH_URL
|
|
||||||
value: "{{ .Values.global.ingress.host }}"
|
|
||||||
- name: AFFINE_ENV
|
- name: AFFINE_ENV
|
||||||
value: "{{ .Release.Namespace }}"
|
value: "{{ .Release.Namespace }}"
|
||||||
- name: DATABASE_PASSWORD
|
- name: DATABASE_PASSWORD
|
||||||
|
|||||||
1
.github/helm/affine/charts/sync/values.yaml
vendored
1
.github/helm/affine/charts/sync/values.yaml
vendored
@@ -12,7 +12,6 @@ env: 'production'
|
|||||||
app:
|
app:
|
||||||
# AFFINE_SERVER_HOST
|
# AFFINE_SERVER_HOST
|
||||||
host: '0.0.0.0'
|
host: '0.0.0.0'
|
||||||
|
|
||||||
serviceAccount:
|
serviceAccount:
|
||||||
create: true
|
create: true
|
||||||
annotations: {}
|
annotations: {}
|
||||||
|
|||||||
3
.github/helm/affine/values.yaml
vendored
3
.github/helm/affine/values.yaml
vendored
@@ -4,6 +4,9 @@ global:
|
|||||||
className: ''
|
className: ''
|
||||||
host: affine.pro
|
host: affine.pro
|
||||||
tls: []
|
tls: []
|
||||||
|
secret:
|
||||||
|
secretName: 'server-private-key'
|
||||||
|
privateKey: ''
|
||||||
database:
|
database:
|
||||||
user: 'postgres'
|
user: 'postgres'
|
||||||
url: 'pg-postgresql'
|
url: 'pg-postgresql'
|
||||||
|
|||||||
@@ -55,7 +55,6 @@ When logging in via email, you will see the mail arriving at localhost:8025 in a
|
|||||||
|
|
||||||
```
|
```
|
||||||
DATABASE_URL="postgresql://affine:affine@localhost:5432/affine"
|
DATABASE_URL="postgresql://affine:affine@localhost:5432/affine"
|
||||||
NEXTAUTH_URL="http://localhost:8080"
|
|
||||||
MAILER_SENDER="noreply@toeverything.info"
|
MAILER_SENDER="noreply@toeverything.info"
|
||||||
MAILER_USER="auth"
|
MAILER_USER="auth"
|
||||||
MAILER_PASSWORD="auth"
|
MAILER_PASSWORD="auth"
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
import { execSync } from 'node:child_process';
|
import { execSync } from 'node:child_process';
|
||||||
|
import { generateKeyPairSync } from 'node:crypto';
|
||||||
import fs from 'node:fs';
|
import fs from 'node:fs';
|
||||||
import path from 'node:path';
|
import path from 'node:path';
|
||||||
|
|
||||||
|
import { parse } from 'dotenv';
|
||||||
|
|
||||||
const SELF_HOST_CONFIG_DIR = '/root/.affine/config';
|
const SELF_HOST_CONFIG_DIR = '/root/.affine/config';
|
||||||
/**
|
/**
|
||||||
* @type {Array<{ from: string; to?: string, modifier?: (content: string): string }>}
|
* @type {Array<{ from: string; to?: string, modifier?: (content: string): string }>}
|
||||||
@@ -36,6 +39,26 @@ function prepare() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// make the default .env
|
||||||
|
if (to === '.env') {
|
||||||
|
const dotenvFile = fs.readFileSync(targetFilePath, 'utf-8');
|
||||||
|
const envs = parse(dotenvFile);
|
||||||
|
// generate a new private key
|
||||||
|
if (!envs.AFFINE_PRIVATE_KEY) {
|
||||||
|
const privateKey = generateKeyPairSync('ec', {
|
||||||
|
namedCurve: 'prime256v1',
|
||||||
|
}).privateKey.export({
|
||||||
|
type: 'sec1',
|
||||||
|
format: 'pem',
|
||||||
|
});
|
||||||
|
|
||||||
|
fs.writeFileSync(
|
||||||
|
targetFilePath,
|
||||||
|
`AFFINE_PRIVATE_KEY=${privateKey}\n` + dotenvFile
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,9 +25,10 @@ AwEHoUQDQgAEF3U/0wIeJ3jRKXeFKqQyBKlr9F7xaAUScRrAuSP33rajm3cdfihI
|
|||||||
const ONE_DAY_IN_SEC = 60 * 60 * 24;
|
const ONE_DAY_IN_SEC = 60 * 60 * 24;
|
||||||
|
|
||||||
const keyPair = (function () {
|
const keyPair = (function () {
|
||||||
const AUTH_PRIVATE_KEY = process.env.AUTH_PRIVATE_KEY ?? examplePrivateKey;
|
const AFFINE_PRIVATE_KEY =
|
||||||
|
process.env.AFFINE_PRIVATE_KEY ?? examplePrivateKey;
|
||||||
const privateKey = createPrivateKey({
|
const privateKey = createPrivateKey({
|
||||||
key: Buffer.from(AUTH_PRIVATE_KEY),
|
key: Buffer.from(AFFINE_PRIVATE_KEY),
|
||||||
format: 'pem',
|
format: 'pem',
|
||||||
type: 'sec1',
|
type: 'sec1',
|
||||||
})
|
})
|
||||||
@@ -37,7 +38,7 @@ const keyPair = (function () {
|
|||||||
})
|
})
|
||||||
.toString('utf8');
|
.toString('utf8');
|
||||||
const publicKey = createPublicKey({
|
const publicKey = createPublicKey({
|
||||||
key: Buffer.from(AUTH_PRIVATE_KEY),
|
key: Buffer.from(AFFINE_PRIVATE_KEY),
|
||||||
format: 'pem',
|
format: 'pem',
|
||||||
type: 'spki',
|
type: 'spki',
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -52,7 +52,6 @@ const config: PlaywrightTestConfig = {
|
|||||||
DEBUG: 'affine:*',
|
DEBUG: 'affine:*',
|
||||||
FORCE_COLOR: 'true',
|
FORCE_COLOR: 'true',
|
||||||
DEBUG_COLORS: 'true',
|
DEBUG_COLORS: 'true',
|
||||||
NEXTAUTH_URL: 'http://localhost:8080',
|
|
||||||
MAILER_HOST: '0.0.0.0',
|
MAILER_HOST: '0.0.0.0',
|
||||||
MAILER_PORT: '1025',
|
MAILER_PORT: '1025',
|
||||||
MAILER_SENDER: 'noreply@toeverything.info',
|
MAILER_SENDER: 'noreply@toeverything.info',
|
||||||
|
|||||||
@@ -47,7 +47,6 @@ const config: PlaywrightTestConfig = {
|
|||||||
DEBUG: 'affine:*',
|
DEBUG: 'affine:*',
|
||||||
FORCE_COLOR: 'true',
|
FORCE_COLOR: 'true',
|
||||||
DEBUG_COLORS: 'true',
|
DEBUG_COLORS: 'true',
|
||||||
NEXTAUTH_URL: 'http://localhost:8080',
|
|
||||||
MAILER_SENDER: 'noreply@toeverything.info',
|
MAILER_SENDER: 'noreply@toeverything.info',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user