ci: docker_tag=ext
All checks were successful
build-and-push-ext / build_push (push) Successful in 1m36s

This commit is contained in:
Debian Dev4 2025-09-17 08:11:42 +00:00
parent c2e1da365e
commit 4c011f9ec6
10 changed files with 101 additions and 508 deletions

View File

@ -43,30 +43,28 @@ DEFAULT_STORAGE=https://dev4.4nkweb.com/storage
# Variables d'environnement pour l'application front-end
# NEXT_PUBLIC_4NK_URL=http://demo.4nkweb.com/
NEXT_PUBLIC_4NK_URL=https://dev4.4nkweb.com/
NEXT_PUBLIC_4NK_URL=https://dev4.4nkweb.com
# NEXT_PUBLIC_FRONT_APP_HOST=https://demo.4nkweb.com
NEXT_PUBLIC_FRONT_APP_HOST=https://dev4.4nkweb.com/lecoffre
NEXT_PUBLIC_FRONT_APP_HOST=dev4.4nkweb.com
NEXT_PUBLIC_FRONT_APP_PORT=443
NEXT_PUBLIC_IDNOT_BASE_URL=https://qual-connexion.idnot.fr
NEXT_PUBLIC_IDNOT_AUTHORIZE_ENDPOINT=/IdPOAuth2/authorize/idnot_idp_v1
NEXT_PUBLIC_IDNOT_CLIENT_ID=
NEXT_PUBLIC_BACK_API_PROTOCOL=https
NEXT_PUBLIC_BACK_API_PROTOCOL=https://
NEXT_PUBLIC_BACK_API_HOST=dev4.4nkweb.com
NEXT_PUBLIC_BACK_API_PORT=443
NEXT_PUBLIC_BACK_API_ROOT_URL=/back
NEXT_PUBLIC_BACK_API_VERSION=/v1
NEXT_PUBLIC_BACK_API_VERSION=v1
# NEXT_PUBLIC_ANK_BASE_REDIRECT_URI='http://local.4nkweb.com:3004/authorized-client'
NEXT_PUBLIC_ANK_BASE_REDIRECT_URI='https://dev4.4nkweb.com/lecoffre/authorized-client'
NEXT_PUBLIC_TARGET_ORIGIN = https://dev4.4nkweb.com/lecoffre
NEXT_PUBLIC_ANK_BASE_REDIRECT_URI=https://dev4.4nkweb.com/lecoffre/authorized-client
NEXT_PUBLIC_TARGET_ORIGIN=https://dev4.4nkweb.com/lecoffre
NEXT_PUBLIC_4NK_IFRAME_URL=https://dev4.4nkweb.com
NEXT_PUBLIC_DOCAPOSTE_API_URL=
NEXT_PUBLIC_API_URL=https://dev4.4nkweb.com/back
NEXT_PUBLIC_DEFAULT_VALIDATOR_ID=
NEXT_PUBLIC_DEFAULT_STORAGE_URLS=https://dev4.4nkweb.com/storage
NEXT_PUBLIC_HOTJAR_SITE_ID=
NEXT_PUBLIC_HOTJAR_SITE_ID=0
NEXT_PUBLIC_HOTJAR_VERSION=
# WS

View File

@ -29,6 +29,18 @@ jobs:
echo "SSH_AUTH_SOCK=$SSH_AUTH_SOCK" >> "$GITHUB_ENV"
echo "SSH_AGENT_PID=$SSH_AGENT_PID" >> "$GITHUB_ENV"
- name: Load .env and export NEXT_PUBLIC_* variables
shell: bash
run: |
set -euo pipefail
if [ -f .env ]; then
set -a
. ./.env
set +a
fi
echo "Environment NEXT_PUBLIC_* available:" || true
env | grep '^NEXT_PUBLIC_' || true
- name: Compute Docker tag from commit message or fallback
id: tag
shell: bash
@ -59,10 +71,19 @@ jobs:
set -euo pipefail
if [ -n "${SSH_AUTH_SOCK:-}" ]; then
buildArgs=()
if [ -n "${{ secrets.NEXT_PUBLIC_4NK_URL || '' }}" ]; then
buildArgs+=(--build-arg NEXT_PUBLIC_4NK_URL="${{ secrets.NEXT_PUBLIC_4NK_URL }}")
fi
docker build --target ext --ssh default "${buildArgs[@]}" -t git.4nkweb.com/4nk/lecoffre-front:${{ steps.tag.outputs.TAG }} -f Dockerfile .
# 1) Ajouter toutes les variables NEXT_PUBLIC_* chargées depuis .env
while IFS='=' read -r key _; do
[ -n "$key" ] || continue
val="${!key:-}"
buildArgs+=(--build-arg "$key=$val")
done < <(env | grep '^NEXT_PUBLIC_' | cut -d= -f1 | sort)
# 2) Fallback/override possibles depuis les secrets CI pour certaines clés critiques
[ -n "${{ secrets.NEXT_PUBLIC_4NK_URL || '' }}" ] && buildArgs+=(--build-arg NEXT_PUBLIC_4NK_URL="${{ secrets.NEXT_PUBLIC_4NK_URL }}")
[ -n "${{ secrets.NEXT_PUBLIC_4NK_IFRAME_URL || '' }}" ] && buildArgs+=(--build-arg NEXT_PUBLIC_4NK_IFRAME_URL="${{ secrets.NEXT_PUBLIC_4NK_IFRAME_URL }}")
docker build --target ext --ssh default "${buildArgs[@]}" \
-t git.4nkweb.com/4nk/lecoffre-front:${{ steps.tag.outputs.TAG }} \
-f Dockerfile .
else
echo "SSH_AUTH_SOCK non défini: l'agent SSH n'est pas disponible. Assurez-vous de définir secrets.SSH_PRIVATE_KEY."
exit 1

View File

@ -53,6 +53,7 @@ ARG NEXT_PUBLIC_DOCAPOSTE_API_URL
ARG NEXT_PUBLIC_HOTJAR_SITE_ID
ARG NEXT_PUBLIC_HOTJAR_VERSION
ARG NEXT_PUBLIC_4NK_URL
ARG NEXT_PUBLIC_4NK_IFRAME_URL
ARG NEXT_PUBLIC_API_URL
ARG NEXT_PUBLIC_DEFAULT_VALIDATOR_ID
ARG NEXT_PUBLIC_DEFAULT_STORAGE_URLS
@ -71,6 +72,7 @@ ENV NEXT_PUBLIC_BACK_API_PROTOCOL=${NEXT_PUBLIC_BACK_API_PROTOCOL} \
NEXT_PUBLIC_HOTJAR_SITE_ID=${NEXT_PUBLIC_HOTJAR_SITE_ID} \
NEXT_PUBLIC_HOTJAR_VERSION=${NEXT_PUBLIC_HOTJAR_VERSION} \
NEXT_PUBLIC_4NK_URL=${NEXT_PUBLIC_4NK_URL} \
NEXT_PUBLIC_4NK_IFRAME_URL=${NEXT_PUBLIC_4NK_IFRAME_URL} \
NEXT_PUBLIC_API_URL=${NEXT_PUBLIC_API_URL} \
NEXT_PUBLIC_DEFAULT_VALIDATOR_ID=${NEXT_PUBLIC_DEFAULT_VALIDATOR_ID} \
NEXT_PUBLIC_DEFAULT_STORAGE_URLS=${NEXT_PUBLIC_DEFAULT_STORAGE_URLS}

View File

@ -7,6 +7,7 @@ Cette documentation décrit le pipeline CI/CD tel quil peut être déduit des
- **Build applicatif**: Next.js (Node 19-alpine) avec dépendance privée `le-coffre-resources` via SSH.
- **Image Docker**: construction multi-étapes, publication vers le registre Docker hébergé sur `git.4nkweb.com` (accès via clés SSH).
- **Déploiement Kubernetes**: namespace `lecoffre`, intégration Vault Agent pour linjection dENV, `ExternalSecret` pour le secret de pull Docker, `Ingress` TLS via cert-manager, ressources de `Deployment`/`Service`.
- **Variables front ajoutées**: `NEXT_PUBLIC_4NK_IFRAME_URL` pour distinguer lURL complète de liframe de son origin (`NEXT_PUBLIC_4NK_URL`).
### Chaîne de build
@ -90,6 +91,7 @@ Notes:
- Règles de nommage des tags dimage et gouvernance de version (`vX.Y.Z`, tags denvironnement).
- Stratégie de déploiement (Helm chart source exact, commandes dapply, gestion multi-env: dev/stg/prod).
- Politique de lint/test avant build (actuellement `--no-lint` au build Next.js).
- Passage des variables `NEXT_PUBLIC_4NK_URL` et `NEXT_PUBLIC_4NK_IFRAME_URL` à létape de build Docker (ARG/ENV) dans la CI.
### Bonnes pratiques recommandées

View File

@ -23,6 +23,7 @@ const nextConfig = {
NEXT_PUBLIC_HOTJAR_SITE_ID: process.env.NEXT_PUBLIC_HOTJAR_SITE_ID,
NEXT_PUBLIC_HOTJAR_VERSION: process.env.NEXT_PUBLIC_HOTJAR_VERSION,
NEXT_PUBLIC_4NK_URL: process.env.NEXT_PUBLIC_4NK_URL,
NEXT_PUBLIC_4NK_IFRAME_URL: process.env.NEXT_PUBLIC_4NK_IFRAME_URL,
NEXT_PUBLIC_API_URL: process.env.NEXT_PUBLIC_API_URL,
NEXT_PUBLIC_DEFAULT_VALIDATOR_ID: process.env.NEXT_PUBLIC_DEFAULT_VALIDATOR_ID,
NEXT_PUBLIC_DEFAULT_STORAGE_URLS: process.env.NEXT_PUBLIC_DEFAULT_STORAGE_URLS,
@ -43,6 +44,7 @@ const nextConfig = {
NEXT_PUBLIC_HOTJAR_SITE_ID: process.env.NEXT_PUBLIC_HOTJAR_SITE_ID,
NEXT_PUBLIC_HOTJAR_VERSION: process.env.NEXT_PUBLIC_HOTJAR_VERSION,
NEXT_PUBLIC_4NK_URL: process.env.NEXT_PUBLIC_4NK_URL,
NEXT_PUBLIC_4NK_IFRAME_URL: process.env.NEXT_PUBLIC_4NK_IFRAME_URL,
NEXT_PUBLIC_API_URL: process.env.NEXT_PUBLIC_API_URL,
NEXT_PUBLIC_DEFAULT_VALIDATOR_ID: process.env.NEXT_PUBLIC_DEFAULT_VALIDATOR_ID,
NEXT_PUBLIC_DEFAULT_STORAGE_URLS: process.env.NEXT_PUBLIC_DEFAULT_STORAGE_URLS,
@ -63,6 +65,7 @@ const nextConfig = {
NEXT_PUBLIC_HOTJAR_SITE_ID: process.env.NEXT_PUBLIC_HOTJAR_SITE_ID,
NEXT_PUBLIC_HOTJAR_VERSION: process.env.NEXT_PUBLIC_HOTJAR_VERSION,
NEXT_PUBLIC_4NK_URL: process.env.NEXT_PUBLIC_4NK_URL,
NEXT_PUBLIC_4NK_IFRAME_URL: process.env.NEXT_PUBLIC_4NK_IFRAME_URL,
NEXT_PUBLIC_API_URL: process.env.NEXT_PUBLIC_API_URL,
NEXT_PUBLIC_DEFAULT_VALIDATOR_ID: process.env.NEXT_PUBLIC_DEFAULT_VALIDATOR_ID,
NEXT_PUBLIC_DEFAULT_STORAGE_URLS: process.env.NEXT_PUBLIC_DEFAULT_STORAGE_URLS,

514
package-lock.json generated
View File

@ -1,12 +1,12 @@
{
"name": "lecoffre-front",
"version": "0.1.0",
"version": "0.1.4",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "lecoffre-front",
"version": "0.1.0",
"version": "0.1.4",
"dependencies": {
"@emotion/react": "^11.10.6",
"@emotion/styled": "^11.10.6",
@ -28,7 +28,7 @@
"heroicons": "^2.1.5",
"jszip": "^3.10.1",
"jwt-decode": "^3.1.2",
"le-coffre-resources": "file:../lecoffre-ressources",
"le-coffre-resources": "git+ssh://git@git.4nkweb.com/4nk/lecoffre-ressources.git#v2.167",
"next": "^14.2.3",
"pdf-lib": "^1.17.1",
"prettier": "^2.8.7",
@ -48,493 +48,6 @@
"@types/react-gtm-module": "^2.0.3"
}
},
"../lecoffre-ressources": {
"name": "le-coffre-resources",
"license": "MIT",
"dependencies": {
"class-transformer": "^0.5.1",
"class-validator": "^0.14.0",
"reflect-metadata": "^0.1.13"
},
"devDependencies": {
"@types/node": "^18.16.1",
"@types/reflect-metadata": "^0.1.0",
"prettier": "^2.7.1",
"tslint": "^6.1.2",
"typescript": "~4.6.0"
}
},
"../lecoffre-ressources/node_modules/@babel/code-frame": {
"version": "7.24.7",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/highlight": "^7.24.7",
"picocolors": "^1.0.0"
},
"engines": {
"node": ">=6.9.0"
}
},
"../lecoffre-ressources/node_modules/@babel/helper-validator-identifier": {
"version": "7.24.7",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=6.9.0"
}
},
"../lecoffre-ressources/node_modules/@babel/highlight": {
"version": "7.24.7",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-validator-identifier": "^7.24.7",
"chalk": "^2.4.2",
"js-tokens": "^4.0.0",
"picocolors": "^1.0.0"
},
"engines": {
"node": ">=6.9.0"
}
},
"../lecoffre-ressources/node_modules/@types/node": {
"version": "18.19.50",
"dev": true,
"license": "MIT",
"dependencies": {
"undici-types": "~5.26.4"
}
},
"../lecoffre-ressources/node_modules/@types/reflect-metadata": {
"version": "0.1.0",
"dev": true,
"license": "MIT",
"dependencies": {
"reflect-metadata": "*"
}
},
"../lecoffre-ressources/node_modules/@types/validator": {
"version": "13.12.2",
"license": "MIT"
},
"../lecoffre-ressources/node_modules/ansi-styles": {
"version": "3.2.1",
"dev": true,
"license": "MIT",
"dependencies": {
"color-convert": "^1.9.0"
},
"engines": {
"node": ">=4"
}
},
"../lecoffre-ressources/node_modules/argparse": {
"version": "1.0.10",
"dev": true,
"license": "MIT",
"dependencies": {
"sprintf-js": "~1.0.2"
}
},
"../lecoffre-ressources/node_modules/balanced-match": {
"version": "1.0.2",
"dev": true,
"license": "MIT"
},
"../lecoffre-ressources/node_modules/brace-expansion": {
"version": "1.1.11",
"dev": true,
"license": "MIT",
"dependencies": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
}
},
"../lecoffre-ressources/node_modules/builtin-modules": {
"version": "1.1.1",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"../lecoffre-ressources/node_modules/chalk": {
"version": "2.4.2",
"dev": true,
"license": "MIT",
"dependencies": {
"ansi-styles": "^3.2.1",
"escape-string-regexp": "^1.0.5",
"supports-color": "^5.3.0"
},
"engines": {
"node": ">=4"
}
},
"../lecoffre-ressources/node_modules/class-transformer": {
"version": "0.5.1",
"license": "MIT"
},
"../lecoffre-ressources/node_modules/class-validator": {
"version": "0.14.1",
"license": "MIT",
"dependencies": {
"@types/validator": "^13.11.8",
"libphonenumber-js": "^1.10.53",
"validator": "^13.9.0"
}
},
"../lecoffre-ressources/node_modules/color-convert": {
"version": "1.9.3",
"dev": true,
"license": "MIT",
"dependencies": {
"color-name": "1.1.3"
}
},
"../lecoffre-ressources/node_modules/color-name": {
"version": "1.1.3",
"dev": true,
"license": "MIT"
},
"../lecoffre-ressources/node_modules/commander": {
"version": "2.20.3",
"dev": true,
"license": "MIT"
},
"../lecoffre-ressources/node_modules/concat-map": {
"version": "0.0.1",
"dev": true,
"license": "MIT"
},
"../lecoffre-ressources/node_modules/diff": {
"version": "4.0.2",
"dev": true,
"license": "BSD-3-Clause",
"engines": {
"node": ">=0.3.1"
}
},
"../lecoffre-ressources/node_modules/escape-string-regexp": {
"version": "1.0.5",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=0.8.0"
}
},
"../lecoffre-ressources/node_modules/esprima": {
"version": "4.0.1",
"dev": true,
"license": "BSD-2-Clause",
"bin": {
"esparse": "bin/esparse.js",
"esvalidate": "bin/esvalidate.js"
},
"engines": {
"node": ">=4"
}
},
"../lecoffre-ressources/node_modules/fs.realpath": {
"version": "1.0.0",
"dev": true,
"license": "ISC"
},
"../lecoffre-ressources/node_modules/function-bind": {
"version": "1.1.2",
"dev": true,
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"../lecoffre-ressources/node_modules/glob": {
"version": "7.2.3",
"dev": true,
"license": "ISC",
"dependencies": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
"inherits": "2",
"minimatch": "^3.1.1",
"once": "^1.3.0",
"path-is-absolute": "^1.0.0"
},
"engines": {
"node": "*"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"../lecoffre-ressources/node_modules/has-flag": {
"version": "3.0.0",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=4"
}
},
"../lecoffre-ressources/node_modules/hasown": {
"version": "2.0.2",
"dev": true,
"license": "MIT",
"dependencies": {
"function-bind": "^1.1.2"
},
"engines": {
"node": ">= 0.4"
}
},
"../lecoffre-ressources/node_modules/inflight": {
"version": "1.0.6",
"dev": true,
"license": "ISC",
"dependencies": {
"once": "^1.3.0",
"wrappy": "1"
}
},
"../lecoffre-ressources/node_modules/inherits": {
"version": "2.0.4",
"dev": true,
"license": "ISC"
},
"../lecoffre-ressources/node_modules/is-core-module": {
"version": "2.15.1",
"dev": true,
"license": "MIT",
"dependencies": {
"hasown": "^2.0.2"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"../lecoffre-ressources/node_modules/js-tokens": {
"version": "4.0.0",
"dev": true,
"license": "MIT"
},
"../lecoffre-ressources/node_modules/js-yaml": {
"version": "3.14.1",
"dev": true,
"license": "MIT",
"dependencies": {
"argparse": "^1.0.7",
"esprima": "^4.0.0"
},
"bin": {
"js-yaml": "bin/js-yaml.js"
}
},
"../lecoffre-ressources/node_modules/libphonenumber-js": {
"version": "1.11.8",
"license": "MIT"
},
"../lecoffre-ressources/node_modules/minimatch": {
"version": "3.1.2",
"dev": true,
"license": "ISC",
"dependencies": {
"brace-expansion": "^1.1.7"
},
"engines": {
"node": "*"
}
},
"../lecoffre-ressources/node_modules/minimist": {
"version": "1.2.8",
"dev": true,
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"../lecoffre-ressources/node_modules/mkdirp": {
"version": "0.5.6",
"dev": true,
"license": "MIT",
"dependencies": {
"minimist": "^1.2.6"
},
"bin": {
"mkdirp": "bin/cmd.js"
}
},
"../lecoffre-ressources/node_modules/once": {
"version": "1.4.0",
"dev": true,
"license": "ISC",
"dependencies": {
"wrappy": "1"
}
},
"../lecoffre-ressources/node_modules/path-is-absolute": {
"version": "1.0.1",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"../lecoffre-ressources/node_modules/path-parse": {
"version": "1.0.7",
"dev": true,
"license": "MIT"
},
"../lecoffre-ressources/node_modules/picocolors": {
"version": "1.1.0",
"dev": true,
"license": "ISC"
},
"../lecoffre-ressources/node_modules/prettier": {
"version": "2.8.8",
"dev": true,
"license": "MIT",
"bin": {
"prettier": "bin-prettier.js"
},
"engines": {
"node": ">=10.13.0"
},
"funding": {
"url": "https://github.com/prettier/prettier?sponsor=1"
}
},
"../lecoffre-ressources/node_modules/reflect-metadata": {
"version": "0.1.14",
"license": "Apache-2.0"
},
"../lecoffre-ressources/node_modules/resolve": {
"version": "1.22.8",
"dev": true,
"license": "MIT",
"dependencies": {
"is-core-module": "^2.13.0",
"path-parse": "^1.0.7",
"supports-preserve-symlinks-flag": "^1.0.0"
},
"bin": {
"resolve": "bin/resolve"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"../lecoffre-ressources/node_modules/semver": {
"version": "5.7.2",
"dev": true,
"license": "ISC",
"bin": {
"semver": "bin/semver"
}
},
"../lecoffre-ressources/node_modules/sprintf-js": {
"version": "1.0.3",
"dev": true,
"license": "BSD-3-Clause"
},
"../lecoffre-ressources/node_modules/supports-color": {
"version": "5.5.0",
"dev": true,
"license": "MIT",
"dependencies": {
"has-flag": "^3.0.0"
},
"engines": {
"node": ">=4"
}
},
"../lecoffre-ressources/node_modules/supports-preserve-symlinks-flag": {
"version": "1.0.0",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"../lecoffre-ressources/node_modules/tslib": {
"version": "1.14.1",
"dev": true,
"license": "0BSD"
},
"../lecoffre-ressources/node_modules/tslint": {
"version": "6.1.3",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@babel/code-frame": "^7.0.0",
"builtin-modules": "^1.1.1",
"chalk": "^2.3.0",
"commander": "^2.12.1",
"diff": "^4.0.1",
"glob": "^7.1.1",
"js-yaml": "^3.13.1",
"minimatch": "^3.0.4",
"mkdirp": "^0.5.3",
"resolve": "^1.3.2",
"semver": "^5.3.0",
"tslib": "^1.13.0",
"tsutils": "^2.29.0"
},
"bin": {
"tslint": "bin/tslint"
},
"engines": {
"node": ">=4.8.0"
},
"peerDependencies": {
"typescript": ">=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >=3.0.0-dev || >= 3.1.0-dev || >= 3.2.0-dev || >= 4.0.0-dev"
}
},
"../lecoffre-ressources/node_modules/tsutils": {
"version": "2.29.0",
"dev": true,
"license": "MIT",
"dependencies": {
"tslib": "^1.8.1"
},
"peerDependencies": {
"typescript": ">=2.1.0 || >=2.1.0-dev || >=2.2.0-dev || >=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >= 3.0.0-dev || >= 3.1.0-dev"
}
},
"../lecoffre-ressources/node_modules/typescript": {
"version": "4.6.4",
"dev": true,
"license": "Apache-2.0",
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
},
"engines": {
"node": ">=4.2.0"
}
},
"../lecoffre-ressources/node_modules/undici-types": {
"version": "5.26.5",
"dev": true,
"license": "MIT"
},
"../lecoffre-ressources/node_modules/validator": {
"version": "13.12.0",
"license": "MIT",
"engines": {
"node": ">= 0.10"
}
},
"../lecoffre-ressources/node_modules/wrappy": {
"version": "1.0.2",
"dev": true,
"license": "ISC"
},
"node_modules/@babel/code-frame": {
"version": "7.27.1",
"license": "MIT",
@ -2091,6 +1604,12 @@
"version": "1.1.4",
"license": "ISC"
},
"node_modules/class-transformer": {
"version": "0.5.1",
"resolved": "https://registry.npmjs.org/class-transformer/-/class-transformer-0.5.1.tgz",
"integrity": "sha512-SQa1Ws6hUbfC98vKGxZH3KFY0Y1lm5Zm0SY8XX9zbK7FJCyVEac3ATW0RIpwzW+oOfmHE5PMPufDG9hCfoEOMw==",
"license": "MIT"
},
"node_modules/class-validator": {
"version": "0.14.2",
"license": "MIT",
@ -3938,8 +3457,13 @@
}
},
"node_modules/le-coffre-resources": {
"resolved": "../lecoffre-ressources",
"link": true
"resolved": "git+ssh://git@git.4nkweb.com/4nk/lecoffre-ressources.git#2684918e1b3a18a3746218f452e75e0a6153544c",
"license": "MIT",
"dependencies": {
"class-transformer": "^0.5.1",
"class-validator": "^0.14.0",
"reflect-metadata": "^0.1.13"
}
},
"node_modules/levn": {
"version": "0.4.1",
@ -4727,6 +4251,12 @@
"url": "https://paulmillr.com/funding/"
}
},
"node_modules/reflect-metadata": {
"version": "0.1.14",
"resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.14.tgz",
"integrity": "sha512-ZhYeb6nRaXCfhnndflDK8qI6ZQ/YcWZCISRAWICW9XYqMUwjZM9Z0DveWX/ABN01oxSHwVxKQmxeYZSsm0jh5A==",
"license": "Apache-2.0"
},
"node_modules/reflect.getprototypeof": {
"version": "1.0.10",
"license": "MIT",

View File

@ -37,6 +37,7 @@ type AppPropsWithLayout = AppProps & {
hotjarSiteId: number;
hotjarVersion: number;
_4nkUrl: string;
_4nkIframeUrl?: string;
apiUrl: string;
};
@ -94,6 +95,17 @@ const MyApp = (({
})();
IframeReference.setTargetOrigin(targetOrigin);
// Configure full iframe URL if provided (falls back to origin)
const iframeUrl = (() => {
const candidate = (publicRuntimeConfig as any).NEXT_PUBLIC_4NK_IFRAME_URL ?? _4nkUrl;
try {
return new URL(candidate).toString();
} catch {
return targetOrigin;
}
})();
IframeReference.setIframeUrl(iframeUrl);
useEffect(() => {
const isAuthenticated = User.getInstance().isAuthenticated();
setIsConnected(isAuthenticated);
@ -153,6 +165,7 @@ MyApp.getInitialProps = async () => {
hotjarSiteId: publicRuntimeConfig.NEXT_PUBLIC_HOTJAR_SITE_ID,
hotjarVersion: publicRuntimeConfig.NEXT_PUBLIC_HOTJAR_VERSION,
_4nkUrl: publicRuntimeConfig.NEXT_PUBLIC_4NK_URL,
_4nkIframeUrl: publicRuntimeConfig.NEXT_PUBLIC_4NK_IFRAME_URL,
apiUrl: publicRuntimeConfig.NEXT_PUBLIC_API_URL,
};
};

View File

@ -17,7 +17,7 @@ function Iframe({ showIframe = false }: IframeProps) {
return (
<iframe
ref={iframeRef}
src={IframeReference.getTargetOrigin()}
src={IframeReference.getIframeUrl()}
style={{
display: showIframe ? 'block' : 'none',
width: '400px',

View File

@ -1,5 +1,6 @@
export default class IframeReference {
private static targetOrigin: string | null = null;
private static iframeUrl: string | null = null;
private static iframe: HTMLIFrameElement | null = null;
private constructor() { }
@ -25,6 +26,28 @@ export default class IframeReference {
return this.targetOrigin;
}
public static setIframeUrl(iframeUrl: string): void {
if (this.iframeUrl) {
console.debug("iframeUrl is already set");
return;
}
try {
// Validate and normalize URL
const url = new URL(iframeUrl);
this.iframeUrl = url.toString();
} catch {
throw new Error(`Invalid iframeUrl: ${iframeUrl}`);
}
}
public static getIframeUrl(): string {
if (!this.iframeUrl) {
throw new Error("iframeUrl is not set");
}
return this.iframeUrl;
}
public static setIframe(iframe: HTMLIFrameElement | null): void {
if (iframe !== null && !(iframe instanceof HTMLIFrameElement)) {
throw new Error("setIframe expects an HTMLIFrameElement or null");

View File

@ -17,13 +17,14 @@ Ce document liste les scénarios de test pour valider la chaîne CI/CD décrite
- Construire limage avec le forward SSH.
- Valider la taille, les couches, lutilisateur non-root, et lexécution `npm run start`.
- Pousser limage taguée (ex. `vX.Y.Z`) sur `rg.fr-par.scw.cloud/lecoffre/front` et vérifier la présence.
- Pousser limage taguée (ex. `ext`) vers le registry `git.4nkweb.com` et vérifier la présence.
### Tests Kubernetes
- Appliquer les manifests/Helm sur un environnement de test.
- Valider la création de l`ExternalSecret` et du `imagePullSecret`.
- Vérifier que le `Deployment` démarre, que Vault injecte les variables, et que le `Service` et `Ingress` sont fonctionnels.
- Vérifier que `NEXT_PUBLIC_4NK_URL` (origin) et `NEXT_PUBLIC_4NK_IFRAME_URL` (URL complète) sont bien injectées au build (présentes dans `/lecoffre-front/.next/standalone/.env` ou via `next.config.js`) et cohérentes avec liframe réellement servie.
### Observabilité et rollback