diff --git a/.cursor/rules/quality.mdc b/.cursor/rules/quality.mdc index e9df6d7..e490621 100644 --- a/.cursor/rules/quality.mdc +++ b/.cursor/rules/quality.mdc @@ -264,3 +264,119 @@ Ces consignes constituent un cadre de production strict. Elles imposent une anal * ARIA * clavier * contraste + +## Open Source + +Le projet est open source et hébergé sur Gitea auto-hébergé. Toutes les contributions doivent respecter les principes open source suivants. + +### Principes open source + +* **Transparence** : Tous les changements doivent être traçables, documentés et accessibles publiquement +* **Collaboration** : Le code doit être conçu pour faciliter les contributions externes +* **Documentation** : Toute fonctionnalité ou modification doit être documentée pour les contributeurs externes +* **Standards ouverts** : Utiliser des standards ouverts et éviter les dépendances propriétaires non documentées +* **Licence MIT** : Le code doit respecter la licence MIT et être compatible avec cette licence + +### Contribution et workflow open source + +* **Commits systématiques** : Tous les changements doivent être commités avec des messages structurés +* **Format de commit** : Les commits doivent suivre le format défini dans CONTRIBUTING.md avec sections Motivations, Root causes, Correctifs, Evolutions, Pages affectées +* **Pull Requests** : Tous les changements doivent passer par des Pull Requests sur Gitea, même pour les modifications internes +* **Documentation des changements** : Toute modification doit être documentée dans `fixKnowledge/` (pour les corrections) ou `features/` (pour les évolutions) +* **Traçabilité** : Chaque modification doit être liée à une issue ou une PR sur Gitea si applicable + +### Qualité pour contributions externes + +* **Code lisible** : Le code doit être compréhensible par des contributeurs externes sans connaissance préalable du contexte interne +* **Commentaires explicatifs** : Les choix de conception non évidents doivent être commentés +* **Documentation à jour** : La documentation doit toujours refléter l'état actuel du code +* **Exemples et guides** : Fournir des exemples d'utilisation et des guides pour les nouvelles fonctionnalités +* **Tests et validation** : Le code doit être validé et testable par des contributeurs externes + +### Gestion des contributions + +* **Respect du Code of Conduct** : Tous les contributeurs doivent respecter le CODE_OF_CONDUCT.md +* **Review process** : Toutes les contributions doivent être revues avant merge +* **Feedback constructif** : Fournir un feedback constructif et respectueux sur les contributions +* **Attribution** : Créditer les contributeurs dans les commits et la documentation + +### Sécurité open source + +* **Reporting de vulnérabilités** : Suivre le processus défini dans SECURITY.md +* **Pas de secrets** : Aucun secret, clé API ou credential ne doit être commité +* **Dépendances sécurisées** : Vérifier la sécurité des dépendances avant ajout +* **Audit de sécurité** : Les changements de sécurité doivent être documentés et audités + +### Repository et infrastructure + +* **Repository Gitea** : https://git.4nkweb.com/4nk/story-research-zapwall +* **Templates** : Utiliser les templates d'issues et de PR dans `.gitea/` +* **Labels et organisation** : Utiliser les labels appropriés pour organiser les issues et PRs +* **Branches** : Respecter la convention de nommage des branches (feature/, fix/, etc.) + +## Commits systématiques + +**Règle absolue** : Tous les changements doivent être commités immédiatement après leur réalisation. + +### Obligation de commit + +* **Pas de modifications non commitées** : Aucune modification ne doit rester non commitée +* **Commits atomiques** : Chaque commit doit représenter une modification logique et complète +* **Commits fréquents** : Commiter régulièrement, pas seulement à la fin d'une session +* **Pas de stash prolongé** : Éviter de laisser des modifications en stash sans les commiter + +### Format de commit obligatoire + +Tous les commits doivent suivre ce format structuré : + +``` +Titre court et descriptif + +**Motivations:** +- Raison de la modification + +**Root causes:** +- Cause racine du problème (si applicable) + +**Correctifs:** +- Ce qui a été corrigé + +**Evolutions:** +- Nouvelles fonctionnalités ou améliorations + +**Pages affectées:** +- Liste des fichiers/modules modifiés +``` + +### Processus de commit + +1. **Avant chaque commit** : + - Vérifier que le code compile (`npm run type-check`) + - Vérifier le linting (`npm run lint`) + - Vérifier que les modifications sont complètes et fonctionnelles + +2. **Création du commit** : + - Utiliser `git add` pour les fichiers modifiés + - Créer un commit avec le format structuré + - Ne pas utiliser `--no-verify` sauf cas exceptionnel documenté + +3. **Après le commit** : + - Vérifier que le commit a bien été créé (`git log`) + - Documenter dans `fixKnowledge/` ou `features/` si nécessaire + +### Exceptions + +Les seules exceptions à la règle de commit immédiat sont : + +* **Modifications en cours de test** : Si une modification nécessite des tests manuels avant commit, elle doit être commitée dès que les tests sont validés +* **Refactoring en plusieurs étapes** : Les refactorings complexes peuvent être commités par étapes logiques +* **Documentation en cours** : La documentation peut être commitée séparément du code si elle est volumineuse + +Dans tous les cas, aucun changement ne doit rester non commité plus de quelques heures. + +### Intégration avec le workflow open source + +* **Commits avant PR** : Tous les commits doivent être faits avant la création d'une Pull Request +* **Commits dans les PRs** : Les commits dans une PR doivent être organisés et logiques +* **Squash si nécessaire** : Les commits peuvent être squashés dans une PR si cela améliore la lisibilité, mais chaque commit individuel doit rester valide +* **Historique propre** : Maintenir un historique Git propre et lisible pour les contributeurs externes \ No newline at end of file diff --git a/.gitea/ISSUE_TEMPLATE/bug_report.md b/.gitea/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..ed8ee16 --- /dev/null +++ b/.gitea/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,52 @@ +--- +name: Bug Report +about: Create a report to help us improve +title: '[BUG] ' +labels: bug +--- + +## Bug Description + +A clear and concise description of what the bug is. + +## Steps to Reproduce + +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + +## Expected Behavior + +A clear and concise description of what you expected to happen. + +## Actual Behavior + +A clear and concise description of what actually happened. + +## Screenshots + +If applicable, add screenshots to help explain your problem. + +## Environment + +- **Browser**: [e.g. Chrome 120, Firefox 121] +- **OS**: [e.g. Windows 11, macOS 14, Linux] +- **Alby Extension**: [e.g. Version 5.2.0] +- **Node Version**: [if relevant] + +## Console Errors + +If applicable, paste any console errors here: + +``` +Paste console errors here +``` + +## Additional Context + +Add any other context about the problem here. + +## Possible Solution + +If you have ideas on how to fix this, please describe them here. diff --git a/.gitea/ISSUE_TEMPLATE/config.yml b/.gitea/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..10eef24 --- /dev/null +++ b/.gitea/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,8 @@ +blank_issues_enabled: false +contact_links: + - name: Security Vulnerability + url: https://git.4nkweb.com/4nk/story-research-zapwall/issues/new?template=security + about: Please report security vulnerabilities privately (use [SECURITY] prefix) + - name: Documentation + url: https://git.4nkweb.com/4nk/story-research-zapwall/src/branch/main/docs + about: Check our documentation for answers diff --git a/.gitea/ISSUE_TEMPLATE/feature_request.md b/.gitea/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..607c1c9 --- /dev/null +++ b/.gitea/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,46 @@ +--- +name: Feature Request +about: Suggest an idea for this project +title: '[FEATURE] ' +labels: enhancement +--- + +## Feature Description + +A clear and concise description of the feature you'd like to see. + +## Problem Statement + +Is your feature request related to a problem? Please describe. +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +## Proposed Solution + +Describe the solution you'd like to see implemented. + +## Alternatives Considered + +Describe any alternative solutions or features you've considered. + +## Use Cases + +Describe specific use cases for this feature: +1. Use case 1 +2. Use case 2 +3. Use case 3 + +## Technical Considerations + +If applicable, describe any technical considerations: +- Performance implications +- Security considerations +- Integration with existing features +- Breaking changes + +## Additional Context + +Add any other context, mockups, or examples about the feature request here. + +## Implementation Notes + +If you have ideas on how to implement this, please share them here. diff --git a/.gitea/ISSUE_TEMPLATE/question.md b/.gitea/ISSUE_TEMPLATE/question.md new file mode 100644 index 0000000..a00e62b --- /dev/null +++ b/.gitea/ISSUE_TEMPLATE/question.md @@ -0,0 +1,25 @@ +--- +name: Question +about: Ask a question about the project +title: '[QUESTION] ' +labels: question +--- + +## Question + +Your question here. + +## Context + +Provide context for your question: +- What are you trying to accomplish? +- What have you tried so far? +- What documentation have you consulted? + +## Relevant Documentation + +- [Link to relevant docs](url) + +## Additional Information + +Any other information that might help answer your question. diff --git a/.gitea/PULL_REQUEST_TEMPLATE.md b/.gitea/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..12920a3 --- /dev/null +++ b/.gitea/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,56 @@ +## Description + +Please include a summary of the change and which issue is fixed. Include relevant motivation and context. + +Fixes # (issue) + +## Type of Change + +- [ ] Bug fix (non-breaking change which fixes an issue) +- [ ] New feature (non-breaking change which adds functionality) +- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) +- [ ] Documentation update +- [ ] Code refactoring + +## Changes Made + +**Motivations:** +- + +**Root causes:** +- + +**Correctifs:** +- + +**Evolutions:** +- + +**Pages affectées:** +- + +## Testing + +- [ ] I have tested my changes locally +- [ ] I have run `npm run lint` and it passes +- [ ] I have run `npm run type-check` and it passes +- [ ] I have tested the changes in the browser with Alby extension +- [ ] I have verified accessibility (keyboard navigation, ARIA, contrast) + +## Checklist + +- [ ] My code follows the project's coding guidelines +- [ ] I have performed a self-review of my own code +- [ ] I have commented my code, particularly in hard-to-understand areas +- [ ] I have made corresponding changes to the documentation +- [ ] My changes generate no new warnings or errors +- [ ] I have added tests if applicable (only if explicitly requested) +- [ ] Any dependent changes have been merged and published + +## Screenshots + +If applicable, add screenshots to help explain your changes. + +## Additional Notes + +Add any additional notes about the PR here. diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..0cdde23 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,119 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic status, +nationality, personal appearance, race, religion, or sexual identity +and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our +community include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior include: + +* The use of sexualized language or imagery, and sexual attention or + advances of any kind +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or email + address, without their explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in +response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, and will communicate reasons for moderation +decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public spaces. +Examples of representing our community include using an official project e-mail +address, posting via an official social media account, or acting as an appointed +representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported to the community leaders responsible for enforcement at +[INSERT CONTACT METHOD]. All complaints will be reviewed and investigated +promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the +reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining +the consequences for any action they deem in violation of this Code of Conduct: + +### 1. Correction +**Community Impact**: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing +clarity around the nature of the violation and an explanation of why the +behavior was inappropriate. A public apology may be requested. + +### 2. Warning +**Community Impact**: A violation through a single incident or series +of actions. + +**Consequence**: A warning with consequences for continued behavior. No +interaction with the people involved, including unsolicited interaction with +those enforcing the Code of Conduct, for a specified period of time. This +includes avoiding interactions in community spaces as well as external channels +like social media. Violating these terms may lead to a temporary or +permanent ban. + +### 3. Temporary Ban +**Community Impact**: A serious violation of community standards, including +sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. No public or +private interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, is allowed during this period. +Violating these terms may lead to a permanent ban. + +### 4. Permanent Ban +**Community Impact**: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within +the community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org), +version 2.0, available at +https://www.contributor-covenant.org/version/2/0/code_of_conduct.html + +Community Impact Guidelines were inspired by [Mozilla's code of conduct +enforcement ladder](https://github.com/mozilla/diversity). + +For answers to common questions about this code of conduct, see +https://www.contributor-covenant.org/faq diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 53c2420..b11ea71 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,31 +1,240 @@ -# Contributing to zapwall4science +# Contributing to zapwall4Science -## Principles -- No fallbacks or silent failures. -- No analytics; no tests added unless explicitly requested. -- Respect lint, type-check, accessibility and exactOptionalPropertyTypes. -- No `ts-ignore`, no untyped `any`, no console logs if a logger exists. +Thank you for your interest in contributing to zapwall4Science! This document provides guidelines and instructions for contributing to the project. -## Setup -- Node 18+, npm -- `npm install` -- `npm run lint` -- `npm run type-check` +## Table of Contents -## Coding guidelines -- Split large components/functions to stay within lint limits (max-lines, max-lines-per-function). -- Prefer typed helpers/hooks; avoid duplication. -- Errors must surface with clear messages; do not swallow exceptions. -- Storage: IndexedDB encrypted (AES-GCM) via `lib/storage/cryptoHelpers.ts`; use provided helpers. -- Nostr: use `lib/articleMutations.ts` and `lib/nostr*.ts` helpers; no direct fallbacks. +- [Code of Conduct](#code-of-conduct) +- [Getting Started](#getting-started) +- [Development Setup](#development-setup) +- [Coding Guidelines](#coding-guidelines) +- [Workflow](#workflow) +- [Commit Guidelines](#commit-guidelines) +- [Pull Request Process](#pull-request-process) +- [Documentation](#documentation) +- [What Not to Do](#what-not-to-do) + +## Code of Conduct + +By participating in this project, you agree to abide by our [Code of Conduct](CODE_OF_CONDUCT.md). We are committed to providing a welcoming and inclusive environment for all contributors. + +## Getting Started + +1. **Fork the repository** on Gitea +2. **Clone your fork** locally: + ```bash + git clone https://git.4nkweb.com/your-username/story-research-zapwall.git + cd story-research-zapwall + ``` +3. **Add the upstream remote**: + ```bash + git remote add upstream https://git.4nkweb.com/4nk/story-research-zapwall.git + ``` + +## Development Setup + +### Prerequisites + +- **Node.js**: 18 or higher +- **npm**: Latest version +- **Alby browser extension**: For testing Nostr authentication and Lightning payments + +### Installation + +1. Install dependencies: + ```bash + npm install + ``` + +2. Run linting: + ```bash + npm run lint + ``` + +3. Run type checking: + ```bash + npm run type-check + ``` + +4. Start the development server: + ```bash + npm run dev + ``` + +5. Open [http://localhost:3000](http://localhost:3000) in your browser + +## Coding Guidelines + +### Core Principles + +- **No fallbacks or silent failures**: All errors must be explicitly handled and logged +- **No analytics**: Analytics are not allowed in this project +- **No tests unless explicitly requested**: Do not add ad-hoc tests +- **Strict TypeScript**: Respect lint, type-check, accessibility, and `exactOptionalPropertyTypes` +- **No shortcuts**: No `ts-ignore`, no untyped `any`, no `console.log` if a logger exists + +### Code Quality + +- **Split large components/functions**: Stay within lint limits (max-lines, max-lines-per-function) +- **Prefer typed helpers/hooks**: Avoid duplication, reuse existing utilities +- **Error handling**: Errors must surface with clear messages; do not swallow exceptions +- **Storage**: Use IndexedDB encrypted (AES-GCM) via `lib/storage/cryptoHelpers.ts` +- **Nostr**: Use `lib/articleMutations.ts` and `lib/nostr*.ts` helpers; no direct fallbacks + +### TypeScript Standards + +- Full type coverage: No `any` types without explicit justification +- No type assertions: Avoid `as` casts unless absolutely necessary +- Strict mode: All TypeScript strict checks must pass +- No `@ts-ignore` or `@ts-nocheck`: Fix type issues properly + +### Accessibility + +- **ARIA**: Proper ARIA labels and roles +- **Keyboard navigation**: All interactive elements must be keyboard accessible +- **Contrast**: Meet WCAG contrast requirements +- **No regressions**: Maintain or improve accessibility with each change ## Workflow -- Branch from main; keep commits focused. -- Run lint + type-check before PR. -- Document fixes in `fixKnowledge/` and features in `features/`. -## Accessibility -- Respect ARIA, keyboard, contrast requirements; no regressions. +### Creating a Branch -## What not to do -- No analytics, no ad-hoc tests, no environment overrides, no silent retry/fallback. +1. **Update your fork**: + ```bash + git checkout main + git pull upstream main + ``` + +2. **Create a feature branch**: + ```bash + git checkout -b feature/your-feature-name + # or + git checkout -b fix/your-bug-fix + ``` + +### Making Changes + +1. Make your changes following the [coding guidelines](#coding-guidelines) +2. Test your changes locally +3. Run lint and type-check: + ```bash + npm run lint + npm run type-check + ``` + +### Before Submitting + +- [ ] Code follows the project's coding guidelines +- [ ] Lint passes (`npm run lint`) +- [ ] Type-check passes (`npm run type-check`) +- [ ] No `console.log` statements (use logger if available) +- [ ] Errors are properly handled and logged +- [ ] Accessibility requirements are met +- [ ] Documentation is updated if needed + +## Commit Guidelines + +### Commit Message Format + +Commits should be exhaustive and synthetic with the following structure: + +``` +**Motivations:** +- Reason for the change + +**Root causes:** +- Underlying issue (if applicable) + +**Correctifs:** +- What was fixed + +**Evolutions:** +- New features or improvements + +**Pages affectées:** +- Files or components modified +``` + +### Example + +``` +Fix payment modal not closing after successful payment + +**Motivations:** +- Users reported payment modal staying open after successful payment + +**Root causes:** +- Missing state update after payment confirmation + +**Correctifs:** +- Added state reset in payment success handler +- Added cleanup in useEffect hook + +**Evolutions:** +- Improved user experience with automatic modal closure + +**Pages affectées:** +- components/PaymentModal.tsx +- hooks/useArticlePayment.ts +``` + +## Pull Request Process + +1. **Update your branch**: + ```bash + git checkout main + git pull upstream main + git checkout your-branch-name + git rebase main + ``` + +2. **Push your changes**: + ```bash + git push origin your-branch-name + ``` + +3. **Create a Pull Request** on Gitea: + - Use a clear, descriptive title + - Fill out the PR template completely + - Reference any related issues + - Add screenshots if UI changes are involved + +4. **Wait for review**: Maintainers will review your PR and provide feedback + +5. **Address feedback**: Make requested changes and push updates to your branch + +6. **Documentation**: + - Document fixes in `fixKnowledge/` directory + - Document features in `features/` directory + +## Documentation + +### When to Document + +- **Fixes**: Document in `fixKnowledge/` with problem, impacts, root cause, corrections, modifications, deployment, and analysis procedures +- **Features**: Document in `features/` with objective, impacts, modifications, deployment, and analysis procedures + +### Documentation Format + +Follow the existing documentation structure: +- Clear sections with headers +- Code examples where relevant +- Links to related documentation +- Author attribution (Équipe 4NK) + +## What Not to Do + +- ❌ **No analytics**: Do not add analytics tracking +- ❌ **No ad-hoc tests**: Do not add tests unless explicitly requested +- ❌ **No environment overrides**: Do not override environment variables +- ❌ **No silent retry/fallback**: All failures must be explicit +- ❌ **No shortcuts**: No `ts-ignore`, no `any`, no `console.log` +- ❌ **No breaking changes**: Maintain backward compatibility unless explicitly required + +## Getting Help + +- **Documentation**: Check the [docs/](docs/) directory +- **Issues**: Search existing issues or create a new one on [Gitea](https://git.4nkweb.com/4nk/story-research-zapwall/issues) +- **Repository**: [https://git.4nkweb.com/4nk/story-research-zapwall](https://git.4nkweb.com/4nk/story-research-zapwall) + +Thank you for contributing to zapwall4Science! 🚀 diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..7a8d862 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 zapwall4Science Contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index e29cd4f..c5effc6 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,24 @@ # zapwall4Science +[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) +[![TypeScript](https://img.shields.io/badge/TypeScript-5.3-blue.svg)](https://www.typescriptlang.org/) +[![Next.js](https://img.shields.io/badge/Next.js-14-black.svg)](https://nextjs.org/) + Plateforme de publication d'articles scientifiques et de science-fiction avec système de sponsoring, commissions et rémunération des avis. Les lecteurs peuvent lire les aperçus gratuitement et débloquer le contenu complet en payant avec Lightning Network. +**Repository**: [https://git.4nkweb.com/4nk/story-research-zapwall](https://git.4nkweb.com/4nk/story-research-zapwall) + +## Table of Contents + +- [Features](#features) +- [Getting Started](#getting-started) +- [Configuration](#configuration) +- [Lightning Wallet Setup](#lightning-wallet-setup) +- [Project Structure](#project-structure) +- [Contributing](#contributing) +- [Documentation](#documentation) +- [License](#license) + ## Features - **Nostr Authentication**: Authenticate using Alby browser extension (NIP-07) @@ -25,23 +42,24 @@ npm run dev 3. Open [http://localhost:3000](http://localhost:3000) in your browser -## Environment Variables +## Configuration -- `NEXT_PUBLIC_NOSTR_RELAY_URL`: Nostr relay URL (default: wss://relay.damus.io) -- `NEXT_PUBLIC_NIP95_UPLOAD_URL`: NIP-95 media upload endpoint URL (required for image/video uploads) +The application stores all configuration in IndexedDB (browser storage) with hardcoded defaults. No environment variables are required. -### NIP-95 Upload Service +### Default Configuration -The application requires a NIP-95 compatible upload service for media uploads (images and videos). You can use services like: -- [nostr.build](https://nostr.build/) - Public NIP-95 service -- [void.cat](https://void.cat/) - Another public NIP-95 service -- Or host your own NIP-95 compatible service +- **Nostr Relay**: `wss://relay.damus.io` (default) +- **NIP-95 Upload API**: `https://nostr.build/api/v2/upload` (default) +- **Platform Lightning Address**: Empty by default -Example `.env.local`: -``` -NEXT_PUBLIC_NOSTR_RELAY_URL=wss://relay.damus.io -NEXT_PUBLIC_NIP95_UPLOAD_URL=https://nostr.build/api/v2/upload -``` +### Customizing Configuration + +Configuration is stored in IndexedDB and can be customized through the application settings. The application supports: +- Multiple Nostr relays (with priority ordering) +- Multiple NIP-95 upload APIs (with priority ordering) +- Platform Lightning address for commissions + +All configuration values are stored locally in the browser and persist across sessions. Default values are hardcoded in the application code. ## Lightning Wallet Setup @@ -58,3 +76,75 @@ Users need to have Alby installed to authenticate and make payments. The applica - `/lib`: Utilities and Nostr helpers - `/types`: TypeScript type definitions - `/hooks`: Custom React hooks + +## Déploiement + +### Documentation complète + +La documentation complète du déploiement est disponible dans le dossier `docs/` : + +- **[Documentation complète du déploiement](docs/deployment.md)** : Guide détaillé de déploiement, configuration et maintenance +- **[Référence des scripts](docs/scripts-reference.md)** : Description de tous les scripts disponibles +- **[Guide de référence rapide](docs/quick-reference.md)** : Commandes essentielles + +### Déploiement rapide + +Le site est déployé sur `zapwall.fr` (serveur : `92.243.27.35`). + +**Mise à jour du site** : + +```bash +# Méthode recommandée : Script automatique +./update-remote-git.sh +``` + +**Vérification du statut** : + +```bash +ssh debian@92.243.27.35 'sudo systemctl status zapwall' +``` + +### Informations de déploiement + +- **Répertoire** : `/var/www/zapwall.fr` +- **Port application** : `3001` +- **Service systemd** : `zapwall.service` +- **Nginx** : Conteneur Docker `lecoffre_nginx_test` +- **HTTPS** : Configuré avec redirection automatique HTTP → HTTPS + +Pour plus de détails, consultez la [documentation complète](docs/deployment.md). + +## Contributing + +We welcome contributions! Please read our [Contributing Guide](CONTRIBUTING.md) to get started. + +### How to Contribute + +1. Fork the repository +2. Create a feature branch (`git checkout -b feature/amazing-feature`) +3. Make your changes following our [coding guidelines](CONTRIBUTING.md#coding-guidelines) +4. Run lint and type-check (`npm run lint && npm run type-check`) +5. Commit your changes (`git commit -m 'Add amazing feature'`) +6. Push to the branch (`git push origin feature/amazing-feature`) +7. Open a Pull Request + +Please ensure your code follows our strict quality standards: +- No fallbacks or silent failures +- Full TypeScript typing (no `any`, no `ts-ignore`) +- Proper error handling and logging +- Accessibility compliance (ARIA, keyboard navigation, contrast) + +See [CONTRIBUTING.md](CONTRIBUTING.md) for detailed guidelines. + +## Documentation + +- **[User Guide](docs/user-guide.md)**: Complete user documentation +- **[Technical Documentation](docs/technical.md)**: Architecture and technical details +- **[Deployment Guide](docs/deployment.md)**: Deployment and configuration +- **[FAQ](docs/faq.md)**: Frequently asked questions +- **[Publishing Guide](docs/publishing-guide.md)**: How to publish articles +- **[Payment Guide](docs/payment-guide.md)**: Lightning payment setup + +## License + +This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details. \ No newline at end of file diff --git a/RESUME-DEPLOIEMENT.md b/RESUME-DEPLOIEMENT.md new file mode 100644 index 0000000..8af0488 --- /dev/null +++ b/RESUME-DEPLOIEMENT.md @@ -0,0 +1,143 @@ +# Résumé du déploiement - zapwall.fr + +## ✅ Actions effectuées + +1. **Déploiement initial** : Application déployée sur `/var/www/zapwall.fr` +2. **Service systemd** : Service `zapwall.service` créé et actif +3. **Configuration nginx** : Reverse proxy configuré dans le conteneur Docker +4. **HTTPS** : Configuration HTTPS avec redirection automatique HTTP → HTTPS +5. **Firewall** : Ports 80 et 443 ouverts + +## 📍 État actuel + +- **Service** : ✅ Actif sur le port 3001 +- **Répertoire** : `/var/www/zapwall.fr` (correct) +- **HTTPS** : ✅ Configuré avec certificats auto-signés +- **Certificats Let's Encrypt** : ⚠️ Non obtenus (bug certbot avec Python 3.11) + +## 🔧 Problèmes identifiés et solutions + +### 1. Certificats Let's Encrypt + +**Problème** : Certbot présente un bug (AttributeError) avec Python 3.11 + +**Solutions** : +- Utiliser certbot via snap (recommandé) : + ```bash + ssh debian@92.243.27.35 + sudo snap install certbot --classic + sudo docker stop lecoffre_nginx_test + sudo certbot certonly --standalone -d zapwall.fr --non-interactive --agree-tos --email admin@zapwall.fr + sudo docker start lecoffre_nginx_test + ``` + +### 2. Configuration nginx + +**Vérification** : La configuration pointe bien vers le port 3001 (correct) +- `proxy_pass http://172.17.0.1:3001;` ✅ + +**Note** : La configuration principale nginx.conf contient aussi une config pour `test-lecoffreio.4nkweb.com`, mais elle ne devrait pas interférer car elle utilise un `server_name` différent. + +## 📝 Mise à jour du site depuis Git + +### Méthode recommandée : Script automatique + +Depuis votre machine locale, dans le répertoire du projet : + +```bash +# Mise à jour depuis la branche actuelle +./update-from-git.sh + +# Ou spécifier une branche +./update-from-git.sh main +``` + +Le script : +1. Transfère les fichiers depuis votre dépôt Git local +2. Installe les dépendances (`npm ci`) +3. Construit l'application (`npm run build`) +4. Redémarre le service +5. Vérifie que tout fonctionne + +### Méthode manuelle + +Si vous préférez faire manuellement : + +```bash +# 1. Transférer les fichiers +tar --exclude='node_modules' \ + --exclude='.next' \ + --exclude='.git' \ + --exclude='*.tsbuildinfo' \ + --exclude='.env*.local' \ + --exclude='.cursor' \ + -czf - . | ssh debian@92.243.27.35 "cd /var/www/zapwall.fr && tar -xzf -" + +# 2. Sur le serveur +ssh debian@92.243.27.35 +cd /var/www/zapwall.fr +npm ci +npm run build +sudo systemctl restart zapwall +``` + +### Initialiser un dépôt Git sur le serveur (optionnel) + +Si vous voulez pouvoir faire `git pull` directement sur le serveur : + +```bash +ssh debian@92.243.35 +cd /var/www/zapwall.fr +git init +git remote add origin https://git.4nkweb.com/4nk/story-research-zapwall.git +git fetch origin +git checkout main # ou la branche souhaitée +``` + +Ensuite, vous pourrez utiliser : +```bash +ssh debian@92.243.27.35 'cd /var/www/zapwall.fr && git pull && npm ci && npm run build && sudo systemctl restart zapwall' +``` + +## 🔍 Commandes de vérification + +### Vérifier le service +```bash +ssh debian@92.243.27.35 'sudo systemctl status zapwall' +``` + +### Voir les logs +```bash +ssh debian@92.243.27.35 'sudo journalctl -u zapwall -f' +``` + +### Vérifier le port +```bash +ssh debian@92.243.27.35 'sudo ss -tuln | grep 3001' +``` + +### Vérifier la configuration nginx +```bash +ssh debian@92.243.27.35 'sudo docker exec lecoffre_nginx_test cat /etc/nginx/conf.d/zapwall.fr.conf' +``` + +## 📚 Fichiers de documentation créés + +- `README-DEPLOYMENT.md` : Guide complet de déploiement et mise à jour +- `update-from-git.sh` : Script de mise à jour automatique +- `fix-nginx-config.sh` : Script de correction de la configuration +- `check-deployment-status.sh` : Script de vérification de l'état + +## 🚀 Prochaines étapes recommandées + +1. **Obtenir les certificats Let's Encrypt** via snap (voir ci-dessus) +2. **Configurer le renouvellement automatique** des certificats +3. **Tester l'accès** au site en HTTPS +4. **Configurer un dépôt Git sur le serveur** pour faciliter les mises à jour + +## ⚠️ Notes importantes + +- Le site fonctionne actuellement avec des certificats auto-signés (avertissement navigateur) +- Les modifications de code nécessitent un rebuild et un redémarrage du service +- Le service doit être actif pour que le site soit accessible +- Nginx fait un reverse proxy vers le port 3001 où tourne l'application Next.js diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..595642b --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,142 @@ +# Security Policy + +## Supported Versions + +We provide security updates for the following versions: + +| Version | Supported | +| ------- | ------------------ | +| 1.0.x | :white_check_mark: | +| < 1.0 | :x: | + +## Reporting a Vulnerability + +We take security vulnerabilities seriously. If you discover a security vulnerability, please follow these steps: + +### 1. **Do NOT** create a public issue + +Security vulnerabilities should be reported privately to protect users. + +### 2. Report via Private Issue + +1. Go to the [Issues](https://git.4nkweb.com/4nk/story-research-zapwall/issues) page +2. Create a new issue with the title prefixed with `[SECURITY]` +3. Mark the issue as confidential/private if Gitea supports it +4. Fill out the form with: + - **Title**: Brief description of the vulnerability (prefixed with `[SECURITY]`) + - **Description**: Detailed description of the vulnerability + - **Severity**: Assess the severity (Low, Moderate, High, Critical) + - **Affected versions**: Which versions are affected + - **Steps to reproduce**: How to reproduce the vulnerability + - **Impact**: What could an attacker do with this vulnerability + +### 3. Alternative Reporting Methods + +If you cannot create a private issue, please contact the maintainers directly through secure channels. Do not disclose the vulnerability publicly until it has been addressed. + +### 4. What to Include + +Please include the following information in your report: + +- **Type of vulnerability** (e.g., XSS, CSRF, authentication bypass, etc.) +- **Location** (file path, component, or endpoint) +- **Steps to reproduce** (detailed steps) +- **Potential impact** (what could an attacker do?) +- **Suggested fix** (if you have one) +- **Proof of concept** (if applicable, but be careful not to include exploits) + +### 5. Response Timeline + +- **Initial response**: Within 48 hours +- **Status update**: Within 7 days +- **Fix timeline**: Depends on severity + - **Critical**: As soon as possible (typically within 24-48 hours) + - **High**: Within 1 week + - **Medium**: Within 2 weeks + - **Low**: Within 1 month + +### 6. Disclosure Policy + +- We will acknowledge receipt of your report within 48 hours +- We will keep you informed of our progress +- We will notify you when the vulnerability is fixed +- We will credit you in the security advisory (unless you prefer to remain anonymous) + +## Security Best Practices + +### For Contributors + +- **Never commit secrets**: API keys, private keys, passwords, etc. +- **Use secure dependencies**: Keep dependencies up to date +- **Follow secure coding practices**: Input validation, output encoding, etc. +- **Review security implications**: Consider security impact of changes + +### For Users + +- **Keep dependencies updated**: Run `npm audit` regularly +- **Use HTTPS**: Always use HTTPS in production +- **Secure your Nostr keys**: Never share your private keys +- **Use secure Lightning wallets**: Only use trusted Lightning wallet extensions + +## Known Security Considerations + +### Nostr Authentication + +- Private keys are managed by the Alby extension (NIP-07) +- We never store or transmit private keys +- All Nostr operations are signed client-side + +### Lightning Payments + +- Payment requests are generated via WebLN (Alby extension) +- We do not handle private keys or payment secrets +- All payment operations are performed by the user's wallet + +### Data Storage + +- Private content is encrypted using AES-GCM +- Encryption keys are stored in browser localStorage +- No sensitive data is sent to external servers (except Nostr relays) + +### IndexedDB + +- Encrypted content is stored in IndexedDB +- Keys are derived from a master key stored in localStorage +- Content expires after 30 days + +## Security Updates + +Security updates will be announced via: + +- Security advisories in issues +- Release notes +- Project documentation + +## Responsible Disclosure + +We appreciate responsible disclosure. If you follow these guidelines, we will: + +- Work with you to understand and resolve the issue quickly +- Credit you in our security advisory (if desired) +- Not take legal action against you + +## Security Checklist for Pull Requests + +Before submitting a PR, ensure: + +- [ ] No hardcoded secrets or credentials +- [ ] Input validation is implemented +- [ ] Output is properly encoded/escaped +- [ ] Error messages don't leak sensitive information +- [ ] Dependencies are up to date (`npm audit`) +- [ ] No `console.log` statements with sensitive data +- [ ] Authentication/authorization is properly implemented +- [ ] HTTPS is used for all external requests + +## Additional Resources + +- [OWASP Top 10](https://owasp.org/www-project-top-ten/) +- [Node.js Security Best Practices](https://nodejs.org/en/docs/guides/security/) +- [Next.js Security](https://nextjs.org/docs/app/building-your-application/configuring/security-headers) + +Thank you for helping keep zapwall4Science secure! diff --git a/components/ArticleCard.tsx b/components/ArticleCard.tsx index 1e70d9a..182b1fe 100644 --- a/components/ArticleCard.tsx +++ b/components/ArticleCard.tsx @@ -11,6 +11,20 @@ interface ArticleCardProps { onUnlock?: (article: Article) => void } +function ArticleHeader({ article }: { article: Article }) { + return ( +
+

{article.title}

+ + {t('publication.viewAuthor')} + +
+ ) +} + function ArticleMeta({ article, error, @@ -56,15 +70,7 @@ export function ArticleCard({ article, onUnlock }: ArticleCardProps) { return (
-
-

{article.title}

- - {t('publication.viewAuthor')} - -
+
void -}) { - const { profiles, loading } = useAuthorsProfiles(authors) - const [isOpen, setIsOpen] = useState(false) - const dropdownRef = useRef(null) - const buttonRef = useRef(null) - - useEffect(() => { - const handleClickOutside = (event: MouseEvent) => { - if ( - dropdownRef.current && - buttonRef.current && - !dropdownRef.current.contains(event.target as Node) && - !buttonRef.current.contains(event.target as Node) - ) { - setIsOpen(false) - } - } - - const handleEscape = (event: KeyboardEvent) => { - if (event.key === 'Escape') { - setIsOpen(false) - buttonRef.current?.focus() - } - } - - if (isOpen) { - document.addEventListener('mousedown', handleClickOutside) - document.addEventListener('keydown', handleEscape) - } - - return () => { - document.removeEventListener('mousedown', handleClickOutside) - document.removeEventListener('keydown', handleEscape) - } - }, [isOpen]) - - const getDisplayName = (pubkey: string): string => { - const profile = profiles.get(pubkey) - return profile?.name ?? `${pubkey.substring(0, 8)}...${pubkey.substring(pubkey.length - 8)}` - } - - const getPicture = (pubkey: string): string | undefined => { - return profiles.get(pubkey)?.picture - } - - const getMnemonicIcons = (pubkey: string): string[] => { - return generateMnemonicIcons(pubkey) - } - - const selectedAuthor = value ? profiles.get(value) : null - const selectedDisplayName = value ? getDisplayName(value) : t('filters.author') - - return ( -
- -
- - {isOpen && ( -
- - {loading ? ( -
{t('filters.loading')}
- ) : ( - authors.map((pubkey) => { - const displayName = getDisplayName(pubkey) - const picture = getPicture(pubkey) - const mnemonicIcons = getMnemonicIcons(pubkey) - const isSelected = value === pubkey - - return ( - - ) - }) - )} -
- )} -
-
- ) -} function SortFilter({ value, @@ -279,7 +92,7 @@ function SortFilter({