Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
9725f74
feat(ffi): expose the crypto core to mobile through UniFFI
ClaraVnk Aug 25, 2026
b59e40c
feat(ios): SwiftUI app over the UniFFI core
ClaraVnk Aug 25, 2026
ff65dc7
feat(ios): rendre l'app fonctionnelle, ajouter Face ID et l'icône
ClaraVnk Aug 25, 2026
b30d811
test(ios): suite de tests iOS et cible CI
ClaraVnk Aug 25, 2026
bd9043d
feat(ios): coffre hors ligne, générateur, codes TOTP, presse-papiers …
ClaraVnk Aug 26, 2026
b7bf55c
feat(ios): extension de remplissage automatique
ClaraVnk Aug 26, 2026
c69ebca
fix(ios): l'icône reprend la marque de GhostPass, pas celle de ghost-…
ClaraVnk Aug 26, 2026
91e2ca7
fix(ios): l'icône suit la charte ghost-suite
ClaraVnk Aug 26, 2026
de2e78a
fix(ios): teintes d'origine et cadrage centré pour l'icône
ClaraVnk Aug 26, 2026
e2d3db1
fix(ios): l'icône vient du logo officiel, repris de main
ClaraVnk Aug 26, 2026
ea1a21b
Merge remote-tracking branch 'origin/main' into feat/ios-app
ClaraVnk Aug 26, 2026
3b66d5c
ci(ios): mettre le job en sommeil, faute de runner macOS
ClaraVnk Aug 26, 2026
b9cef94
test(server): verrouiller la forme des réponses de l'API
ClaraVnk Aug 26, 2026
b47f6e0
ci(ios): préparer le branchement d'un runner macOS
ClaraVnk Aug 26, 2026
ae6dd35
docs(ci): distinguer le poste prêté de la machine dédiée
ClaraVnk Aug 26, 2026
8d9018f
feat(ios): corbeille — restaurer ou supprimer pour de bon
ClaraVnk Aug 26, 2026
e654112
feat(ios): l'interface adopte le système visuel de la suite
ClaraVnk Aug 26, 2026
a708e17
feat(ios): organiser le coffre en dossiers
ClaraVnk Aug 26, 2026
74f49ce
feat(ios): thème et langue au choix de l'utilisateur
ClaraVnk Aug 26, 2026
5dff751
feat: favoris et santé du coffre
ClaraVnk Aug 26, 2026
61a87f9
feat(ios): historique des mots de passe, actions rapides, alertes rép…
ClaraVnk Aug 26, 2026
f622f4c
feat(ios): récupération de compte par clé
ClaraVnk Aug 26, 2026
fa42f61
feat(ios): import d'un CSV exporté ailleurs
ClaraVnk Aug 26, 2026
c555ba7
feat(ios): icônes des sites et export du coffre
ClaraVnk Aug 26, 2026
6a4835b
ci: dire à voix haute si les tests iOS sont activés
ClaraVnk Aug 26, 2026
ff3396e
ci: exercer le workflow sur les branches de travail
ClaraVnk Aug 26, 2026
29df36c
feat(ios): verrouillage différé et écran masqué en arrière-plan
ClaraVnk Aug 26, 2026
0cc962c
ci: l'interrupteur des tests iOS ne sert plus qu'à couper
ClaraVnk Aug 26, 2026
53d68c6
ci: déclencher un passage après rattachement du runner macOS
ClaraVnk Aug 26, 2026
c58c852
sécu: gitleaks ne doit plus buter sur le vecteur TOTP de la RFC 6238
ClaraVnk Aug 26, 2026
30b31dc
ci: consigner la portée du jeton d'enregistrement et la capacité du r…
ClaraVnk Aug 26, 2026
c75c314
ci: relancer avec les journaux de job conservés côté runner
ClaraVnk Aug 26, 2026
b5ff0ae
ci: le daemon doit avoir cargo dans son PATH, et garder les logs de job
ClaraVnk Aug 26, 2026
00fce96
ci: xcodebuild ne doit pas mourir de SIGPIPE en affichant sa version
ClaraVnk Aug 26, 2026
b7a5070
feat(ffi): exposer les coffres partagés et l'accès d'urgence au bindi…
ClaraVnk Aug 26, 2026
800e4fd
feat(ios): accès d'urgence — confier son coffre à un contact de confi…
ClaraVnk Aug 26, 2026
df2fedf
test(ios): éprouver l'accès d'urgence, et rendre test02 capable d'éch…
ClaraVnk Aug 27, 2026
e3e9721
fix(ios): test02 repose la biométrie qu'il vient d'activer
ClaraVnk Aug 27, 2026
c607d3b
feat(da): GhostPass passe au bleu néon de la suite
ClaraVnk Aug 27, 2026
3cbd325
feat(da): le fantôme iOS passe au bleu, et redevient reproductible
ClaraVnk Aug 27, 2026
4026128
feat(ios): coffres partagés — lire et écrire dans le coffre d'une équipe
ClaraVnk Aug 27, 2026
c0661aa
feat(ios): administration des équipes — membres, collections, groupes…
ClaraVnk Aug 27, 2026
eef3622
test(ios): test01 n'ouvrait plus la feuille de création une fois sur …
ClaraVnk Aug 27, 2026
15f87c9
feat(da): la charte devient reproductible, et le web rejoint la suite
ClaraVnk Aug 27, 2026
4277805
feat(da): la charte couvre les huit produits de la suite
ClaraVnk Aug 27, 2026
ce6a406
ci: consigner que la machine ne porte qu'une suite à la fois
ClaraVnk Aug 27, 2026
40d9e14
test(ios): test04 saute enfin pour sa vraie raison, et la dit
ClaraVnk Aug 27, 2026
b3a524c
fix(web): le thème clair était blanc sur blanc
ClaraVnk Aug 27, 2026
bbe1e43
ci: ne pas tuer par motif ce que le runner partage
ClaraVnk Aug 27, 2026
8fffa9b
ci: option pour afficher le simulateur, et ce qu'elle n'a pas résolu
ClaraVnk Aug 28, 2026
4f3aec9
fix(import): les notes étaient perdues à chaque migration, des deux c…
ClaraVnk Aug 28, 2026
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
89 changes: 88 additions & 1 deletion .gitea/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
name: CI

on:
# Les branches de travail aussi, et pas seulement `main` : pour un événement `push`, la
# forge exécute le workflow *du commit poussé*. Un job ajouté sur une branche s'y exerce
# donc tout de suite, sans dépendre de la façon dont elle résout les workflows d'une
# pull request — depuis la source ou depuis la cible, selon les versions.
push:
branches: [main]
branches: [main, "feat/**", "fix/**"]
pull_request:

# Principe du moindre privilège : lecture seule par défaut. Conservé pour Gitea Actions ; si
Expand Down Expand Up @@ -80,3 +84,86 @@ jobs:
- name: Build
working-directory: apps/web
run: npm run build

# Un job filtré par `if:` disparaît sans un mot du rapport : personne ne remarque que
# les tests iOS n'ont pas tourné. Ce job-ci tourne toujours, sur un runner Linux, et dit
# à voix haute ce que le garde a décidé — et, au passage, si le contexte `vars` est
# seulement disponible sur cette forge (il demande Gitea 1.20).
ios-gate:
name: Tests iOS — activés ?
runs-on: ubuntu-latest
steps:
- name: État du garde
run: |
valeur='${{ vars.MACOS_RUNNER }}'
echo "MACOS_RUNNER = « $valeur »"
if [ "$valeur" = "false" ]; then
echo "::warning::MACOS_RUNNER vaut « false » : les tests iOS sont volontairement écartés."
elif [ -z "$valeur" ]; then
echo "MACOS_RUNNER n'est pas définie pour ce dépôt — le job iOS tourne quand même."
echo "Une variable définie au niveau *utilisateur* ne s'applique pas à un dépôt"
echo "d'organisation : pour la voir ici, il faut la poser sur le dépôt ou sur"
echo "l'organisation (Paramètres du dépôt > Actions > Variables)."
else
echo "Le job iOS est activé et sera dispatché vers un runner étiqueté « macos »."
fi

ios:
name: App iOS (SwiftUI + UniFFI)
# Xcode et le simulateur n'existent que sur macOS : ce job réclame un runner de cette
# famille, étiqueté `macos` (voir tools/ci/README.md pour en brancher un).
#
# L'interrupteur est *à l'arrêt explicite*, et c'est le fruit d'une leçon. Un runner
# self-hosted est une machine réelle : éteinte, elle laisse le job en file d'attente et
# la pull request sans verdict — Gitea n'échoue pas, il attend. On avait donc écrit
# `== 'true'`, pour ne rien lancer par défaut.
#
# Sauf qu'une variable qui ne se résout pas — posée au niveau utilisateur alors que le
# dépôt appartient à une organisation, par exemple — rend une chaîne vide, et le job
# disparaît sans un mot : on croit avoir une CI iOS, on n'en a pas. Une file d'attente
# se voit ; une absence, non. Entre les deux, on préfère celle qui se voit.
#
# `MACOS_RUNNER` (Paramètres du **dépôt** ou de l'**organisation** > Actions >
# Variables) reste donc l'interrupteur, mais il ne sert qu'à *couper* : à `false` le
# job est écarté, dans tous les autres cas il tourne.
if: vars.MACOS_RUNNER != 'false'
runs-on: macos
# Le cœur crypto et son binding doivent déjà être verts : sans eux, l'app n'a rien
# à lier, et un échec ici ne dirait pas où le problème se trouve.
needs: crypto
steps:
- uses: actions/checkout@v4
# Pas d'action d'installation ici : sur une machine self-hosted, Xcode, rustup,
# xcodegen et Node sont ceux du poste. On vérifie qu'ils répondent plutôt que de
# les réinstaller à chaque exécution — et l'absence de l'un doit se lire d'un coup
# d'œil, pas se deviner trente lignes plus bas.
- name: Prérequis du poste
run: |
set -e
for outil in xcodebuild xcrun xcodegen cargo node npm; do
command -v "$outil" >/dev/null || { echo "::error::$outil introuvable sur ce runner"; exit 1; }
done
# `| head -1` ferait sortir xcodebuild en 141 (SIGPIPE) dès qu'il écrit la
# deuxième ligne : le shell des steps tourne en `-e -o pipefail`, et l'étape
# échouerait *après* avoir réussi. `sed -n 1p` lit tout le flux, lui.
xcodebuild -version | sed -n 1p
- name: Cibles Rust pour iOS
run: rustup target add aarch64-apple-ios aarch64-apple-ios-sim x86_64-apple-ios
- name: Dépendances du serveur de test
working-directory: apps/server
run: npm ci
# Construit l'XCFramework et les bindings, monte un serveur GhostPass local, amorce
# un coffre de test (registre gp:folders compris), déroule les suites, coupe le
# serveur pour éprouver le hors-ligne, puis remplit un formulaire dans Safari.
- name: Tests iOS
run: ./tools/ios/run-ios-tests.sh
# Un échec ne laisse qu'un nom de test : les rapports portent les captures d'écran
# et le journal du serveur, seuls moyens de comprendre sans reproduire localement.
- name: Rapports de test
if: failure()
uses: actions/upload-artifact@v4
with:
name: ios-test-results
path: apps/ios/TestResults/
retention-days: 7

11 changes: 11 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,14 @@ dist/
CLAUDE.md
.claude/


# iOS : tout ceci est produit par tools/ios/build-xcframework.sh ou par XcodeGen.
apps/ios/Ghostpass.xcodeproj/
apps/ios/Generated/
apps/ios/Headers/
apps/ios/GhostpassCrypto.xcframework/

# Rapports de tests iOS (conservés en cas d'échec, régénérables)
apps/ios/TestResults/
apps/ios/.build/
__pycache__/
9 changes: 9 additions & 0 deletions .gitleaks.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,12 @@ paths = [
'''(^|/)Cargo\.lock$''',
'''(^|/)package-lock\.json$''',
]

# Vecteur de test de la RFC 6238 (base32 de « 12345678901234567890 », doublé pour atteindre
# 160 bits) : il est publié dans la norme et sert à vérifier que notre TOTP calcule les codes
# attendus. `generic-api-key` le prend pour une clé à cause de son entropie. On autorise la
# valeur elle-même, et non le fichier entier : un vrai secret collé dans les tests iOS doit
# continuer à faire échouer le scan.
regexes = [
'''GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ''',
]
Loading