Authenticatie
Rol: lid, trainer, eigenaar (alle rollen)
De app gebruikt PocketBase e-mail/wachtwoord authenticatie zonder externe OAuth-providers. Bij het opstarten controleert de app of er een geldig token in AsyncStorage staat en vernieuwt dit zo nodig via authRefresh. Op basis van het role-veld in het gebruikersobject bepaalt de app welke tabbladenset wordt getoond.
Loginflow
Stap-voor-stap
- App start — de app leest het opgeslagen token uit AsyncStorage.
- Token aanwezig —
pb.collection('users').authRefresh()wordt aangeroepen. Bij een geldige respons wordt het gebruikersobject bijgewerkt en doorgegeven aan de navigatiecontext. - Token ontbreekt of verlopen — de gebruiker wordt doorgestuurd naar het loginscherm.
- Login — na een succesvolle
authWithPassword-aanroep slaat de app het token en het gebruikersobject op in AsyncStorage. - Routering op rol — de
role-waarde (lid|trainer|eigenaar) bepaalt welke tabbladenset de React Navigation-stack rendert.
Datamodel
Auth-collectie voor alle gebruikers. Beheert authenticatie en profielgegevens.
| Veld | Type | Verplicht | Beschrijving | Beperkingen |
|---|---|---|---|---|
name | text | ✓ | Volledige naam | min 2, max 100 |
role | select | ✓ | Gebruikersrol bepaalt toegang en tabbladen | lid | trainer | eigenaar |
skillLevel | number | — | Speelsterkte op schaal 1–5 | min 1, max 5 |
memberSince | date | — | Datum waarop het lidmaatschap is ingegaan | — |
avatar | file | — | Profielfoto | max 5 MB · JPEG / PNG / HEIC |
Toegangsregels
| Regel | Expressie |
|---|---|
list | @request.auth.id != '' |
view | @request.auth.id != '' |
create | (open — alleen via PocketBase Admin UI) |
update | @request.auth.id = id |
delete | null (uitgeschakeld via API) |
Uitloggen
Bij uitloggen worden het token en de gebruikersgegevens verwijderd uit AsyncStorage en wordt de PocketBase auth-store gewist via pb.authStore.clear(). De gebruiker wordt teruggestuurd naar het loginscherm. Er wordt geen server-side sessie beëindigd — het token vervalt aan de PocketBase-kant op basis van de ingestelde TTL.
AsyncStorage.removeItem('pb_token')AsyncStorage.removeItem('pb_user')pb.authStore.clear()→ navigate('Login')Ontwerpkeuzes
Alleen e-mail, geen OAuth De app is bedoeld voor gesloten clubomgevingen. Accounts worden handmatig aangemaakt via de PocketBase Admin UI door de eigenaar. OAuth zou een zelf-registratiestroom vereisen die niet past bij dit beheermodel.
AsyncStorage voor het token
React Native heeft geen veilige browser-sessionStorage. AsyncStorage biedt persistentie over app-herstarts heen. Voor een productieomgeving met hogere beveiligingseisen zou expo-secure-store (iOS Keychain) een betere keuze zijn, maar AsyncStorage is voldoende voor de huidige clubcontext.
authRefresh bij elke app-start
In plaats van het token lokaal te valideren (JWT-decode) wordt authRefresh aangeroepen om te garanderen dat het token aan de serverzijde nog geldig is. Dit vangt ook gevallen op waarbij een account is geblokkeerd of verwijderd terwijl de gebruiker ingelogd was.
Beveiliging
- Minimaal wachtwoordlengte: 8 tekens (afgedwongen door PocketBase auth-collectie).
- Het token wordt bij elke app-start gevalideerd via
authRefresh— een verlopen of ingetrokken token leidt direct naar het loginscherm. - Account aanmaken via de API is uitgeschakeld (
createRule: null); alleen de PocketBase Admin UI mag gebruikers aanmaken. - Wachtwoord wijzigen is mogelijk via de PocketBase Admin UI of via een toekomstig in-app profiel-scherm.