forked from efforting.tech/gitea.efforting.tech
77 lines
2.4 KiB
JavaScript
77 lines
2.4 KiB
JavaScript
/**
|
|
* Step 01 — Generate a named SSH key pair
|
|
*
|
|
* Generates an ed25519 key pair and stores it in the secrets directory:
|
|
*
|
|
* <secrets_base>/git-ssh/<user>/public/<key_name>
|
|
* <secrets_base>/git-ssh/<user>/private/<key_name>
|
|
*
|
|
* The private key is written with mode 0600.
|
|
* The public key can be registered as a read-only deploy key in Gitea.
|
|
*/
|
|
|
|
import { execFile as exec_file } from 'node:child_process'
|
|
import { mkdirSync, mkdtempSync, chmodSync, existsSync, readFileSync, renameSync, rmSync } from 'node:fs'
|
|
import * as path from 'node:path'
|
|
import * as os from 'node:os'
|
|
import { promisify } from 'node:util'
|
|
import { fileURLToPath } from 'node:url'
|
|
import yaml from 'js-yaml'
|
|
|
|
const exec = promisify(exec_file)
|
|
const HERE = path.dirname(fileURLToPath(import.meta.url))
|
|
const CONFIG = yaml.load(readFileSync(path.join(HERE, '..', 'config.yml'), 'utf8'))
|
|
|
|
async function run(cmd, args = []) {
|
|
console.log(`$ ${cmd} ${args.join(' ')}`)
|
|
const { stdout, stderr } = await exec(cmd, args)
|
|
if (stdout) { process.stdout.write(stdout) }
|
|
if (stderr) { process.stderr.write(stderr) }
|
|
return stdout.trim()
|
|
}
|
|
|
|
async function main() {
|
|
const { secrets_base, user, key_name } = CONFIG
|
|
|
|
const public_dir = path.join(secrets_base, 'git-ssh', user, 'public')
|
|
const private_dir = path.join(secrets_base, 'git-ssh', user, 'private')
|
|
const public_path = path.join(public_dir, key_name)
|
|
const private_path = path.join(private_dir, key_name)
|
|
|
|
if (existsSync(private_path) || existsSync(public_path)) {
|
|
console.error(`Key "${key_name}" already exists for user "${user}". Aborting.`)
|
|
process.exit(1)
|
|
}
|
|
|
|
mkdirSync(public_dir, { recursive: true })
|
|
mkdirSync(private_dir, { recursive: true, mode: 0o700 })
|
|
|
|
// Generate into a secure temp directory, then move into place
|
|
const tmp_dir = mkdtempSync(path.join(os.tmpdir(), 'ci-keygen-'))
|
|
const tmp_path = path.join(tmp_dir, 'key')
|
|
|
|
try {
|
|
await run('ssh-keygen', [
|
|
'-t', 'ed25519',
|
|
'-N', '', // no passphrase
|
|
'-C', `ci/${user}/${key_name}`,
|
|
'-f', tmp_path,
|
|
])
|
|
|
|
renameSync(`${tmp_path}.pub`, public_path)
|
|
renameSync(tmp_path, private_path)
|
|
chmodSync(private_path, 0o600)
|
|
} finally {
|
|
rmSync(tmp_dir, { recursive: true, force: true })
|
|
}
|
|
|
|
console.log(`\nKey "${key_name}" generated for user "${user}".`)
|
|
console.log(`\nPublic key (add as read-only deploy key in Gitea):\n`)
|
|
console.log(readFileSync(public_path, 'utf8'))
|
|
}
|
|
|
|
main().catch(err => {
|
|
console.error(err)
|
|
process.exit(1)
|
|
})
|