Outlook-plugin endpoints

Volledige API-surface voor de Outlook-plugin: zowel de OAuth/sessie-endpoints (publiek bereikbaar) als de plugin-API (JWT-beschermd). Voor de achterliggende architectuur, zie Explanation: Outlook-plugin.

OAuth- en sessie-endpoints

Onder /exact/outlook/*. Bereikbaar zonder backend-auth; bescherming via forceOutlookTenant-middleware of publicRateLimit().

Methode Pad Auth Doel
GET /exact/outlook/auth-url forceOutlookTenant Geeft de Exact OAuth-URL terug die de plugin in een Office-dialog opent. State: <tenantUuid>:outlook[:base64url(email)].
GET /exact/callback publiek OAuth-callback waar Exact naar terugredirect na inloggen. Wisselt code in voor tokens, upsert in OutlookExactToken, issue plugin-JWT, geeft die als postMessage aan de Office-dialog.
POST /exact/outlook/session/refresh JWT (recovery-grace) + publicRateLimit() Levert een vers JWT zolang het oude JWT signed is en server-side de koppeling niet revoked is. Accepteert tot 60 dagen verlopen JWTs.
POST /exact/outlook/session/recover publiek + rate-limit Email-based recovery: krijgt { email } in body, geeft een vers JWT als er server-side een geldige OutlookExactToken op die mailbox bekend is.
POST /exact/outlook/session/revoke JWT (mag verlopen) + rate-limit Markeert het OutlookExactToken-doc als revoked. Idempotent — ook zonder geldig JWT antwoordt 200.

Request/response shapes

POST /exact/outlook/session/refresh

Authorization: Bearer <oude-jwt>
Body: {}

200 OK:
{ "success": true, "data": { "jwt": "<nieuwe-jwt>", "expiresAt": <ms-epoch> } }

401:
{ "success": false, "code": "PLUGIN_SESSION_INVALID", "message": "Plugin sessie verlopen of ongeldig." }
{ "success": false, "code": "EXACT_REAUTH_REQUIRED", "message": "Koppel Exact Online opnieuw." }

POST /exact/outlook/session/recover

Body: { "email": "user@example.com" }

200 OK:
{ "success": true, "data": { "jwt": "<jwt>", "expiresAt": <ms-epoch> } }

400:
{ "success": false, "code": "INVALID_EMAIL", "message": "Ongeldig emailadres." }

401:
{ "success": false, "code": "EXACT_REAUTH_REQUIRED", "message": "Koppel Exact Online opnieuw." }

POST /exact/outlook/session/revoke

Authorization: Bearer <jwt>  (optioneel)
Body: {}

200 OK altijd (idempotent):
{ "success": true }

Plugin-API endpoints

Onder /outlook-plugin/*. Beschermd door:

  • requirePluginSession middleware (verifieert JWT, vist access_token uit vault, zet op req.pluginSession)
  • exactCallContextMiddleware (zet tenant-context voor logs en error-tracking)
  • publicRateLimit() (per-IP rate-limit)

Elke call verwacht Authorization: Bearer <jwt> in de header.

Plugin-pagina

Methode Pad Doel
GET /outlook-plugin/ Rendert de plugin-HTML met i18n, CSS-href en JS-href. Cache-Control: no-store.

Contact-flow

Methode Pad Doel
GET /outlook-plugin/contact?email=<email>&outlookItemId=<id> Zoekt het Exact-contact bij dit emailadres. Returnt { contact, division, registration, salesLink, excluded, matchedContacts }.
GET /outlook-plugin/contacts/status?emails=<csv> Bulk-status voor het Adresboek (heeft contact in Exact ja/nee + excluded ja/nee).
GET /outlook-plugin/contacts/search?q=<query> Live-search op naam of email.
GET /outlook-plugin/contacts/:id/details Volledige contact-details voor het Adresboek-detailscherm.
POST /outlook-plugin/save Maakt of update een contact in Exact. Body via SaveContactBodySchema.
POST /outlook-plugin/contact/exclude Markeert een emailadres als “niet relevant voor koppelen”.
DELETE /outlook-plugin/contact/exclude Reset de exclude-vlag.

Organisaties

Methode Pad Doel
GET /outlook-plugin/organizations?search=<text> Zoek-organisaties op naam (debounced live-search).
POST /outlook-plugin/create-organization Quick-create organisatie in Exact (POST Accounts).

Tijdregistraties

Methode Pad Doel
GET /outlook-plugin/work-types Lijst van urensoorten.
GET /outlook-plugin/cost-types Lijst van kostensoorten.
GET /outlook-plugin/projects?accountId=<id> Projecten gekoppeld aan een account.
POST /outlook-plugin/register-time Boekt een TimeTransaction in Exact.
PUT /outlook-plugin/update-time Update bestaande TimeTransaction.
DELETE /outlook-plugin/delete-time?outlookItemId=<id> Verwijdert TimeTransaction.

CRM / Sales

Methode Pad Doel
GET /outlook-plugin/quotations?accountId=<id> Offertes gekoppeld aan account.
GET /outlook-plugin/sales-orders?accountId=<id> Verkooporders.
GET /outlook-plugin/purchase-orders?accountId=<id> Inkooporders.
GET /outlook-plugin/opportunities?accountId=<id> Verkoopkansen.
GET /outlook-plugin/opportunity-stages Mogelijke stage-waarden.
POST /outlook-plugin/opportunities Maakt nieuwe Opportunity aan.
PUT /outlook-plugin/opportunities/:id/stage Update Opportunity-stage.
POST /outlook-plugin/activities Logt een activiteit (Note of Task) onder een Opportunity.
GET /outlook-plugin/opportunities/:opportunityId/activities Lijst activiteiten per Opportunity.
PUT /outlook-plugin/activities/by-id/:activityId Update een specifieke activiteit (op type-gebaseerde polymorfe API).
DELETE /outlook-plugin/activities/by-id/:activityId Verwijdert een activiteit.

Archiveren

Methode Pad Doel
GET /outlook-plugin/document-types Lijst van document-types in Exact (sortable per beschrijving).
POST /outlook-plugin/archive-email Archiveert email + bijlagen als Document in Exact. Body bevat emailData (metadata + HTML body) + attachments (base64). Server genereert PDF uit de email, bundelt alle uploads in één Document met automatische rollback bij gedeeltelijke fouten.

Sessie-uitloggen

Methode Pad Doel
POST /outlook-plugin/logout Server-side endpoint voor toekomstige session-invalidation. Vandaag is logout client-side (clearSession + revoke + disconnect); dit endpoint blijft voor symmetrie.

Foutcodes (in response-body)

De plugin-flow gebruikt twee herkenbare error-codes in de 401-body zodat de client-side fetchWithAuth weet wanneer de sessie écht weg moet.

Code Wanneer Client-actie
PLUGIN_SESSION_INVALID JWT mist, is gemanipuleerd, of voorbij de recovery-grace clearSession() + showLoginSection()
EXACT_REAUTH_REQUIRED OutlookExactToken-doc revoked of voorbij de failure-threshold clearSession() + showLoginSection()
INVALID_EMAIL Recovery-call zonder of met ongeldig emailadres client toont login (geen recovery mogelijk)

Andere 4xx-codes vallen onder generieke error-handling.

Gerelateerd