bublliodocs
API

Authentication στο REST API

Το JWT API contract για Postman, curl, mobile clients, scripts και debugging του browser login.

Endpoints

MethodEndpointAuthenticationΣκοπός
POST/api/v1/auth/token/ΚανέναΑνταλλαγή username/password με access και refresh tokens
POST/api/v1/auth/token/refresh/Refresh token σε JSONΠεριστροφή refresh token και έκδοση νέου access token
GET/api/v1/auth/me/Access Bearer tokenΕπιστροφή του τρέχοντος χρήστη και των Organizations που βλέπει
GET/PATCH/api/v1/auth/me/profile/Access Bearer tokenΠροβολή ή συμπλήρωση του προσωπικού onboarding profile
GET/PATCH/api/v1/auth/me/settings/Access Bearer tokenΠροβολή ή αλλαγή email και profile settings
GET/api/v1/auth/me/export/Access Bearer tokenΛήψη export των προσωπικών δεδομένων του χρήστη
POST/api/v1/auth/me/delete/Access Bearer tokenΔιαγραφή account μετά από ελέγχους password και ownership
POST/api/v1/auth/me/password/Access Bearer tokenΑλλαγή του τρέχοντος password
POST/api/v1/auth/password-reset/ΚανέναΑίτημα επαναφοράς password με γενική απάντηση
POST/api/v1/auth/password-reset/<uidb64>/<token>/Reset token στο URLΟρισμός νέου password από έγκυρο reset link
POST/api/v1/auth/logout/Access Bearer tokenBlacklist του refresh token που υποβάλλεται
GET/api/v1/setup/ΚανέναΈλεγχος αν είναι διαθέσιμο το first-run setup
POST/api/v1/setup/Server-side setup token σε JSONΔημιουργία πρώτου admin, workspace και προαιρετικού SMTP account
POST/api/v1/setup/smtp-test/Server-side setup token σε JSONΑποστολή δοκιμαστικού email με SMTP settings που δεν έχουν αποθηκευτεί
POST/api/v1/organizations/Installation admin Bearer tokenΔημιουργία shared workspace· διαφορετικός Owner λαμβάνει email invitation
GET/api/v1/organizations/provisioning/Authenticated Bearer tokenΠροβολή των pending handoffs· Installation admins βλέπουν όλα
POST/DELETE/api/v1/organizations/provisioning/<organization_id>/Provisioning creator ή Installation admin Bearer tokenResend invitation Owner ή ακύρωση pending workspace
GET/POST/api/v1/organizations/<organization_id>/invitations/Owner/Admin Bearer tokenΠροβολή invitation history ή αποστολή νέας invitation
DELETE/api/v1/organizations/<organization_id>/invitations/<invitation_id>/Owner/Admin Bearer tokenΑνάκληση invitation και ακύρωση του link
POST/api/v1/organizations/<organization_id>/invitations/<invitation_id>/resend/Owner/Admin Bearer tokenΑνάκληση προηγούμενων links και αποστολή νέας invitation επτά ημερών
GET/api/v1/organizations/<organization_id>/members/Owner/Admin Bearer tokenΠροβολή μελών· απευθείας δημιουργία membership δεν υποστηρίζεται
GET/POST/api/v1/organizations/installation-admin-invitations/Installation admin Bearer tokenΠροβολή IT admins και pending invitations ή πρόσκληση νέου IT admin
GET/api/v1/installation-admin-invitations/<token>/Invitation token στο URLPreview invitation για IT admin
POST/api/v1/installation-admin-invitations/<token>/accept/Invitation token· και Bearer token για υπάρχοντες χρήστεςΑποδοχή μία φορά και ανάθεση ρόλου Installation admin
GET/api/v1/invitations/<token>/Invitation token στο URLPreview έγκυρης invitation
POST/api/v1/invitations/<token>/accept/Invitation token· και Bearer token για υπάρχοντες χρήστεςΑποδοχή μία φορά και σύνδεση στο workspace

Το Django admin στο /admin/ εξακολουθεί να χρησιμοποιεί session authentication. Τα κανονικά REST requests δεν χρησιμοποιούν browser sessions.

First-run setup

Το setup endpoint είναι ξεχωριστό bootstrap flow, όχι δημόσια εγγραφή. Το GET επιστρέφει μόνο { "available": true|false } και δεν αποκαλύπτει το token. Το POST γίνεται δεκτό μόνο αν έχει οριστεί server-side BUBLLIO_SETUP_TOKEN με τουλάχιστον 32 χαρακτήρες, οι πίνακες users και Organizations είναι άδειοι και το setup δεν έχει ολοκληρωθεί.

Το request περιλαμβάνει setup_token, username, email, password, organization_name και organization_slug. Το προαιρετικό smtp μπορεί να περιλαμβάνει τα πεδία του email account, μαζί με το password του. Η ρύθμιση SMTP απαιτεί έγκυρο server-side BUBLLIO_EMAIL_ENCRYPTION_KEYS. Σε επιτυχία επιστρέφεται 201 και το setup κλείνει οριστικά για τη συγκεκριμένη database. Υπάρχει rate limit στα setup POST requests. Για την πλήρη διαδικασία, δείτε το Getting Started.

Οι απλοί χρήστες δεν μπορούν να δημιουργήσουν personal ή shared workspaces. Τα υπάρχοντα personal workspaces παραμένουν απομονωμένα· η δημιουργία νέου workspace προορίζεται για Installation admins.

Το SMTP test request περιλαμβάνει setup_token, recipient (έγκυρη διεύθυνση email) και το ίδιο smtp object που δέχεται το setup. Ανοίγει σύνδεση SMTP, κάνει authentication και στέλνει ένα δοκιμαστικό μήνυμα. Δεν αποθηκεύει email account και δεν ολοκληρώνει το setup. Η απάντηση 200 σημαίνει ότι ο SMTP server αποδέχτηκε το μήνυμα, όχι ότι παραδόθηκε στα εισερχόμενα του παραλήπτη. Αποτυχία δικτύου ή authentication επιστρέφει γενικό 502, χωρίς να αποκαλύπτει credentials. Το endpoint απενεργοποιείται μόλις ολοκληρωθεί το setup.

Εγγραφή μόνο με invitation

Δεν υπάρχει γενικό public signup endpoint. Owner ή Admin δημιουργεί invitation κάτω από το URL του Organization με { "email": "person@example.com", "role": "member" }. Το owner δεν μπορεί να ανατεθεί μέσω της συνηθισμένης invitation· οι αρχικές προσκλήσεις Owner γίνονται από το provisioning flow. Μόνο Owner μπορεί να προσκαλέσει admin. Για την αποστολή απαιτείται το ενεργό default SMTP account του Organization ή το fallback SMTP της εγκατάστασης. Το link λήγει σε επτά ημέρες. Ορίστε το BUBLLIO_APP_URL στο public origin του React app, ώστε τα links να δείχνουν στη σωστή εγκατάσταση.

Ο παραλήπτης ανοίγει το link για να δει το workspace και τον ρόλο της invitation. Νέος χρήστης στέλνει username και password στο accept/· ο server ορίζει το invited email και επιστρέφει JWT tokens μαζί με organization_id. Υπάρχων χρήστης συνδέεται και στέλνει κενό JSON body με το Bearer token του. Το email του account πρέπει να ταιριάζει με την invitation. Η αποδοχή δημιουργεί membership μόνο στο συγκεκριμένο workspace και καταναλώνει το link· επανάληψη ή λήξη επιστρέφει 404.

Ένα συνηθισμένο workspace membership δεν επιτρέπει τη δημιουργία άλλου Organization. Μόνο Installation admin δημιουργεί workspace. Αν το owner_email ανήκει σε άλλο άτομο, το workspace μένει κρυφό μέχρι να αποδεχτεί ο Owner· τότε αφαιρείται και το προσωρινό membership του Installation admin. Για το handoff και την ανάκτηση workspace, δείτε τον οδηγό ρόλων.

Το invitation history έχει ένα από τα status pending, accepted, expired ή revoked. Η λήξη υπολογίζεται από το expires_at, χωρίς background job. Τα resend και revoke actions περιορίζονται στο αντίστοιχο Organization· οι Admins δεν διαχειρίζονται invitations για τον ρόλο Admin.

Οι invitations για IT admins χρησιμοποιούν το fallback SMTP της εγκατάστασης και το ξεχωριστό browser route /installation-admin-invite/<token>. Υπάρχων χρήστης συνδέεται με το invited email· νέος χρήστης συμπληρώνει στοιχεία εγγραφής. Με την αποδοχή αποκτά Django superuser/staff status, χωρίς workspace membership. Δώστε αυτό το προνόμιο μόνο σε έμπιστους operators, καθώς το Django /admin/ παρέχει ευρεία πρόσβαση εκτός του κανονικού tenant-scoped API.

Κατά την εγγραφή, νέοι προσκεκλημένοι χρήστες συμπληρώνουν display name και προαιρετικά first/last name, ημερομηνία γέννησης, timezone και locale. Υπάρχοντες χρήστες μπορούν να συμπληρώσουν ή να ενημερώσουν το profile τους μέσω /api/v1/auth/me/profile/. Τα account settings στο /api/v1/auth/me/settings/ καλύπτουν αλλαγές email και profile· το /api/v1/auth/me/password/ αλλάζει το password μετά από authentication. Τα password reset requests επιστρέφουν την ίδια γενική απάντηση είτε υπάρχει το email είτε όχι. Τα reset links χρησιμοποιούνται μία φορά και λήγουν όταν αλλάξει το password.

Μετά την αρχικοποίηση της εγκατάστασης, οι χρήστες μπορούν ρητά να δημιουργήσουν ένα ιδιωτικό personal workspace. Τα shared/team workspaces είναι ξεχωριστά Organizations και εμφανίζονται μόνο μέσω αποδεκτού membership. Τα personal workspaces δεν μπορούν να προσκαλέσουν ή να προσθέσουν μέλη, ούτε να διαγραφούν. Όταν μια ομάδα χρειάζεται κοινά CRM data, Installation admin δημιουργεί κανονικό workspace ή αναθέτει αυτό το δικαίωμα σε επιλεγμένο account.

Τα account settings περιλαμβάνουν επίσης ροή export προσωπικών δεδομένων και διαγραφής account. Το export περιέχει μόνο account, profile και membership metadata — ποτέ tokens, passwords, SMTP secrets ή CRM data workspace. Για διαγραφή απαιτείται το τρέχον password και η ακριβής επιβεβαίωση DELETE. Owner πρέπει πρώτα να μεταβιβάσει την ιδιοκτησία του workspace.

Login με curl

Δημιουργήστε πρώτα έναν τοπικό χρήστη:

uv run python src/manage.py createsuperuser

Ζητήστε το ζεύγος tokens:

curl -X POST http://127.0.0.1:8000/api/v1/auth/token/ \
  -H 'Content-Type: application/json' \
  -d '{"username":"admin","password":"your-password"}'

Επιτυχής απάντηση:

{
  "refresh": "<long-refresh-token>",
  "access": "<short-lived-access-token>"
}

Μην κάνετε commit καμία από τις δύο τιμές. Το access token χρησιμοποιείται στα API requests· το refresh token χρησιμοποιείται μόνο για έκδοση νέου ζεύγους ή για logout.

Κλήση authenticated endpoint

curl http://127.0.0.1:8000/api/v1/auth/me/ \
  -H "Authorization: Bearer $ACCESS_TOKEN"

Η απάντηση περιλαμβάνει τα Organizations που βλέπει ο χρήστης. Κάθε Organization μπορεί να έχει διαφορετικό current_user_role, καθώς το membership περιορίζεται ανά Organization.

Refresh και rotation

curl -X POST http://127.0.0.1:8000/api/v1/auth/token/refresh/ \
  -H 'Content-Type: application/json' \
  -d '{"refresh":"<refresh-token>"}'

Το refresh rotation είναι ενεργό. Αν η απάντηση περιέχει νέο refresh, ο client πρέπει να αντικαταστήσει το παλιό token. Το παλιό μπαίνει σε blacklist, οπότε η επόμενη ανανέωση θα αποτύχει αν συνεχίσετε να το χρησιμοποιείτε.

Logout

curl -X POST http://127.0.0.1:8000/api/v1/auth/logout/ \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"refresh":"<refresh-token>"}'

Όταν το refresh token μπει σε blacklist, το endpoint επιστρέφει 204 No Content. Ο client πρέπει να καθαρίζει τοπικά τα tokens ακόμη κι αν αποτύχει το network request, ώστε το UI να γίνει αμέσως ιδιωτικό.

Status codes

  • 200: επιτυχές token, refresh ή request τρέχοντος χρήστη.
  • 204: επιτυχές logout.
  • 400: λανθασμένο ή ελλιπές refresh token.
  • 401: authentication που λείπει, έληξε, δεν είναι έγκυρο ή έχει ανακληθεί.
  • 404: ο χρήστης είναι authenticated αλλά δεν έχει πρόσβαση σε tenant ή resource. Έτσι δεν αποκαλύπτεται αν υπάρχει Organization στο οποίο δεν έχει πρόσβαση.

Συμπεριφορά του browser client

Ο επίσημος React client υλοποιεί αυτό το contract στα frontend/src/services/api.ts και frontend/src/features/auth/hooks/useAuth.tsx. Το Axios προσθέτει Bearer header και επαναλαμβάνει μία αποτυχημένη κλήση μετά το refresh. Το Zustand αποθηκεύει τα tokens στο sessionStorage της ίδιας καρτέλας: reload διατηρεί το session, ενώ το logout το καθαρίζει.

Σημειώσεις ασφαλείας

  • Χρησιμοποιείτε HTTPS εκτός local development.
  • Μην αποθηκεύετε JWTs στο source control, σε Postman exports με πραγματικές τιμές, στα logs ή σε μεταβλητές VITE_*.
  • Το starter αποστέλλει το refresh token σε JSON και το αποθηκεύει σε sessionStorage, το οποίο είναι προσβάσιμο από JavaScript. Γι’ αυτό η προστασία από XSS είναι απαραίτητη. Production browser deployment μπορεί να επιλέξει refresh token σε HttpOnly cookie, αλλά χρειάζεται προσεκτική ρύθμιση CSRF και cookies.
  • Το Django επιβάλλει authorization στο API. Frontend route guards και κρυμμένα κουμπιά δεν αποτελούν μηχανισμό ασφαλείας.