Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 45 additions & 9 deletions .github/workflows/cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,62 @@ name: CD

on:
push:
branches: [main]
tags:
- 'v*'

jobs:
# Placeholder for future deployment
deploy:
name: Deploy
runs-on: ubuntu-latest
if: false # Disabled until deployment is configured
build-deploy:
name: Build and deploy
runs-on: self-hosted
environment: demo
permissions: {}
steps:
- uses: actions/checkout@v4
- name: Deployment placeholder
run: echo 'Deployment configuration coming soon'
- uses: actions/checkout@v6

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SUGGESTION — this bumps actions/checkout from @v4 (baseline cd.yml/ci.yml) straight to @v6 in a deploy-only PR. Please confirm v6 is an intended, published major and align it with the version the other workflows use, so CI/CD don't drift on the same action. (Third-party-action SHA-pinning was consciously deferred in #1516 — this is just about not silently jumping two majors here.)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can downgrade actions/checkout but I don't think it's worth. New versions works same way as older and improve CI security


- name: Build web
run: docker build --build-arg VITE_API_BASE_URL=${{ vars.VITE_API_BASE_URL }} -f apps/web/Dockerfile . --tag openlinker-web

- name: Export openlinker-web as tar
run: docker save -o openlinker-web.tar openlinker-web

- name: Build worker
run: docker build -f Dockerfile --target worker . --tag openlinker-worker

- name: Export openlinker-worker as tar
run: docker save -o openlinker-worker.tar openlinker-worker

- name: Build api
run: docker build -f Dockerfile --target production . --tag openlinker-api

- name: Export openlinker-api as tar
run: docker save -o openlinker-api.tar openlinker-api

- name: Build migrate
run: docker build -f Dockerfile --target base . --tag openlinker-migrate

- name: Export openlinker-migrate as tar
run: docker save -o openlinker-migrate.tar openlinker-migrate

- name: Install SSH key
uses: shimataro/ssh-key-action@v2
with:
key: ${{ secrets.SSH_KEY }}
known_hosts: 'just-a-placeholder-so-we-dont-get-errors'

- name: Adding Known Hosts
run: ssh-keyscan -p ${{ secrets.SSH_PORT }} -H ${{ secrets.SSH_HOST }} >> ~/.ssh/known_hosts

- name: Copy images to server
run: rsync -avz -e "ssh -p ${{ secrets.SSH_PORT }}" ./openlinker-{migrate,api,web,worker}.tar ${{ secrets.SSH_HOST }}:${{ secrets.DESTINATION_PATH_IMAGES }}/

- name: Sync prestashop module
run: rsync -avz --delete -e "ssh -p ${{ secrets.SSH_PORT }}" ./apps/prestashop-module/ ${{ secrets.SSH_HOST }}:${{ secrets.DESTINATION_PATH_PRESTA_MODULE }}/

- name: Sync prestashop init scripts
run: rsync -avz --delete -e "ssh -p ${{ secrets.SSH_PORT }}" ./docker/prestashop/ ${{ secrets.SSH_HOST }}:${{ secrets.DESTINATION_PATH_PRESTA_INITSCRIPTS }}/

- name: Sync woocommerce init scripts
run: rsync -avz --delete -e "ssh -p ${{ secrets.SSH_PORT }}" ./docker/woocommerce/ ${{ secrets.SSH_HOST }}:${{ secrets.DESTINATION_PATH_WC_INITSCRIPTS }}/

- name: Deploy
run: ssh -p ${{ secrets.SSH_PORT }} ${{ secrets.SSH_HOST }} "bash ~/deploy.sh"
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,27 @@ describe('aes-cipher', () => {
expect(() => encryptAesCbc('x', key, new Uint8Array(8))).toThrow(KsefSessionCryptoException);
});

it('should throw KsefSessionCryptoException when decrypting with the wrong key', () => {
const ciphertext = encryptAesCbc('secret', key, iv);
it('should never recover the plaintext when decrypting with the wrong key', () => {
// CBC has no key verification: a wrong key usually fails PKCS#7 padding
// validation (throws), but ~0.4% of random keys yield accidentally valid
// padding and return garbage instead. Both outcomes are legal (#1538).
const plaintext = 'secret';
const ciphertext = encryptAesCbc(plaintext, key, iv);
const wrongKey = new Uint8Array(randomBytes(KSEF_AES_KEY_BYTES));
expect(() => decryptAesCbc(ciphertext, wrongKey, iv)).toThrow(KsefSessionCryptoException);
let result: string | undefined;
try {
result = decryptAesCbc(ciphertext, wrongKey, iv);
} catch (err) {
expect(err).toBeInstanceOf(KsefSessionCryptoException);
return;
}
expect(result).not.toBe(plaintext);
});

it('should throw KsefSessionCryptoException when the ciphertext length is not a multiple of the block size', () => {
// decipher.final() always throws on a truncated ciphertext, so this covers
// the wrapping path of decryptAesCbc deterministically.
const truncated = encryptAesCbc('secret', key, iv).slice(0, -1);
expect(() => decryptAesCbc(truncated, key, iv)).toThrow(KsefSessionCryptoException);
});
});
Loading