- Implement PKCE (Proof Key for Code Exchange) with S256 method - Add crypto/pkce module with code verifier and challenge generation - Modify OAuth flow to include code_challenge in authorization requests - Update HandleCallback to validate code_verifier during token exchange - Extend session lifetime from 7 to 30 days - Add comprehensive unit tests for PKCE functions - Maintain backward compatibility with fallback for non-PKCE sessions - Add detailed logging for OAuth flow with PKCE tracking PKCE enhances security by preventing authorization code interception attacks, as recommended by OAuth 2.1 and OIDC standards. feat: add encrypted refresh token storage with automatic cleanup - Add oauth_sessions table for storing encrypted refresh tokens - Implement AES-256-GCM encryption for refresh tokens using cookie secret - Create OAuth session repository with full CRUD operations - Add SessionWorker for automatic cleanup of expired sessions - Configure cleanup to run every 24h for sessions older than 37 days - Modify OAuth flow to store refresh tokens after successful authentication - Track client IP and user agent for session security validation - Link OAuth sessions to user sessions via session ID - Add comprehensive encryption tests with security validations - Integrate SessionWorker into server lifecycle with graceful shutdown This enables persistent OAuth sessions with secure token storage, reducing the need for frequent re-authentication from 7 to 30 days.
7.8 KiB
Embedding & Intégrations
Intégrer Ackify dans vos outils (Notion, Outline, Google Docs, etc.).
Méthodes d'Intégration
1. Lien Direct
Le plus simple :
https://sign.company.com/?doc=policy_2025
Usage :
- Chat (Slack, Teams)
- Wiki
- Documentation
Comportement :
- L'utilisateur clique → Arrive sur la page de signature
- Se connecte via OAuth2
- Signe le document
2. iFrame Embed
Pour intégrer dans une page web :
<iframe src="https://sign.company.com/?doc=policy_2025"
width="600"
height="200"
frameborder="0"
style="border: 1px solid #ddd; border-radius: 6px;">
</iframe>
Rendu :
┌─────────────────────────────────────┐
│ 📄 Security Policy 2025 │
│ 42 confirmations │
│ [Sign this document] │
└─────────────────────────────────────┘
3. oEmbed (Auto-discovery)
Pour les plateformes supportant oEmbed (Notion, Outline, Confluence, etc.).
Comment ça marche
-
Coller l'URL dans votre éditeur :
https://sign.company.com/?doc=policy_2025 -
L'éditeur détecte automatiquement via la balise meta :
<link rel="alternate" type="application/json+oembed" href="https://sign.company.com/oembed?url=..." /> -
L'éditeur appelle
/oembedet reçoit :{ "type": "rich", "version": "1.0", "title": "Security Policy 2025 - 42 confirmations", "provider_name": "Ackify", "html": "<iframe src=\"https://sign.company.com/?doc=policy_2025\" ...>", "height": 200 } -
L'éditeur affiche l'iframe automatiquement
Plateformes Supportées
- ✅ Notion - Paste URL → Auto-embed
- ✅ Outline - Paste URL → Auto-embed
- ✅ Confluence - oEmbed macro
- ✅ AppFlowy - URL unfurling
- ✅ Slack - Link unfurling (Open Graph)
- ✅ Microsoft Teams - Card preview
- ✅ Discord - Rich embed
Open Graph & Twitter Cards
Ackify génère automatiquement des meta tags pour les previews :
<!-- Auto-généré pour /?doc=policy_2025 -->
<meta property="og:title" content="Security Policy 2025 - 42 confirmations" />
<meta property="og:description" content="42 personnes ont confirmé avoir lu le document" />
<meta property="og:url" content="https://sign.company.com/?doc=policy_2025" />
<meta property="og:type" content="website" />
<meta name="twitter:card" content="summary" />
Résultat dans Slack/Teams :
┌─────────────────────────────────────┐
│ 🔐 Ackify │
│ Security Policy 2025 │
│ 42 confirmations │
│ sign.company.com │
└─────────────────────────────────────┘
Intégrations Spécifiques
Notion
-
Coller l'URL dans une page Notion :
https://sign.company.com/?doc=policy_2025 -
Notion détecte automatiquement l'oEmbed
-
Le widget apparaît avec bouton de signature
Alternative : Créer un embed manuel
/embed→ Paste URL
Outline
-
Dans un document Outline, coller :
https://sign.company.com/?doc=policy_2025 -
Outline charge automatiquement le widget
Google Docs
Google Docs ne supporte pas les iframes directement, mais :
-
Option 1 - Lien :
Veuillez signer : https://sign.company.com/?doc=policy_2025 -
Option 2 - Image Badge :
 -
Option 3 - Google Sites :
- Créer une page Google Sites
- Insérer l'iframe
- Lier depuis Google Docs
Voir docs/integrations/google-doc/ pour plus de détails.
Confluence
- Éditer une page Confluence
- Insérer macro "oEmbed" ou "HTML Embed"
- Coller :
https://sign.company.com/?doc=policy_2025
Slack
Link Unfurling :
-
Poster l'URL dans un channel :
Hey team, please sign: https://sign.company.com/?doc=policy_2025 -
Slack affiche automatiquement une preview (Open Graph)
Slash Command (futur) :
/ackify sign policy_2025
Microsoft Teams
- Poster l'URL dans une conversation
- Teams affiche une card preview (Open Graph)
Badge PNG
Générer un badge visuel pour README, wiki, etc.
URL du Badge
https://sign.company.com/badge/policy_2025.png
Rendu :
Markdown
[](https://sign.company.com/?doc=policy_2025)
HTML
<a href="https://sign.company.com/?doc=policy_2025">
<img src="https://sign.company.com/badge/policy_2025.png" alt="Signature status">
</a>
API oEmbed
Endpoint
GET /oembed?url=https://sign.company.com/?doc=policy_2025
Response :
{
"type": "rich",
"version": "1.0",
"title": "Document policy_2025 - 42 confirmations",
"provider_name": "Ackify",
"provider_url": "https://sign.company.com",
"html": "<iframe src=\"https://sign.company.com/?doc=policy_2025\" width=\"100%\" height=\"200\" frameborder=\"0\" style=\"border: 1px solid #ddd; border-radius: 6px;\" allowtransparency=\"true\"></iframe>",
"width": null,
"height": 200
}
Paramètres
| Paramètre | Description | Exemple |
|---|---|---|
url |
URL du document (obligatoire) | ?url=https://... |
maxwidth |
Largeur max (optionnel) | ?maxwidth=800 |
maxheight |
Hauteur max (optionnel) | ?maxheight=300 |
Discovery
Toutes les pages incluent la balise de discovery :
<link rel="alternate"
type="application/json+oembed"
href="https://sign.company.com/oembed?url=..."
title="Document title" />
Personnalisation
Thème Dark Mode
Le widget détecte automatiquement le dark mode du navigateur :
@media (prefers-color-scheme: dark) {
/* Thème sombre automatique */
}
Taille Personnalisée
<iframe src="https://sign.company.com/?doc=policy_2025"
width="800"
height="300"
frameborder="0">
</iframe>
Langue
Le widget détecte automatiquement la langue du navigateur :
fr- Françaisen- Englishes- Españolde- Deutschit- Italiano
Sécurité
iFrame Sandboxing
Par défaut, les iframes Ackify autorisent :
allow-same-origin- Cookies OAuth2allow-scripts- Fonctionnalités Vue.jsallow-forms- Soumission de signaturesallow-popups- OAuth redirect
CORS
Ackify configure automatiquement CORS pour :
- Toutes les origines (lecture publique)
- Credentials via
Access-Control-Allow-Credentials
CSP
Content Security Policy headers configurés pour permettre l'embedding :
X-Frame-Options: SAMEORIGIN
Content-Security-Policy: frame-ancestors 'self' https://notion.so https://outline.com
Troubleshooting
L'iframe ne s'affiche pas
Vérifier :
- HTTPS activé (required pour OAuth)
- CSP headers permettent l'embedding
- Pas de bloqueur de contenu (uBlock, Privacy Badger)
oEmbed non détecté
Vérifier :
- La balise
<link rel="alternate" type="application/json+oembed">est présente - L'URL est exacte (avec
?doc=...) - La plateforme supporte oEmbed discovery
Preview Slack vide
Vérifier :
- Open Graph meta tags présents
- URL publiquement accessible
- Pas de redirect infini
Exemples Complets
Voir :
- docs/integrations/google-doc/ - Intégration Google Workspace
- Plus d'exemples à venir...