Add shared authentication and email verification services
Provide reusable models, injectable service contracts, lifecycle-safe providers and explicit dummy implementations for login, signup and verification. Add focused error and async lifecycle tests. Related to #4 and #5.
This commit is contained in:
1 parent
d9318053e8
commit
27424ed886
15 files changed
+708
No files matched your search
@@ -0,0 +1,63 @@
|
||||
# sxchnge_auth
|
||||
|
||||
Shared Flutter authentication providers and service contracts for web and mobile. Private package, version 0.1.0; Flutter 3.47+ / Dart 3.13+.
|
||||
|
||||
## Install and use
|
||||
|
||||
From `frontend/app` (or a sibling `frontend/mobile` app):
|
||||
|
||||
```yaml
|
||||
dependencies:
|
||||
sxchnge_auth:
|
||||
path: ../packages/sxchnge_auth
|
||||
```
|
||||
|
||||
```dart
|
||||
import 'package:sxchnge_auth/sxchnge_auth.dart';
|
||||
|
||||
final login = LoginProvider(const DummyLoginService());
|
||||
login.addListener(() {
|
||||
// Render login.state.status, result, or typed error in your own UI.
|
||||
});
|
||||
await login.login(
|
||||
email: 'demo@example.com',
|
||||
password: 'example-password',
|
||||
locale: 'en',
|
||||
);
|
||||
login.dispose();
|
||||
```
|
||||
|
||||
`SignupProvider` accepts a `SignupService` and exposes `signup(name:, email:, password:, locale:)`. Both providers extend ChangeNotifier and can be installed with `ChangeNotifierProvider`, ListenableBuilder, or another Flutter state binding. The package itself depends only on Flutter foundation; it contains no widgets, routes, localization, web-only code, network client, or storage.
|
||||
|
||||
## Lifecycle and services
|
||||
|
||||
Providers expose immutable `AuthState`: idle, loading, success, or error. They trim email/name, preserve the password verbatim, pass the locale to services, suppress duplicate submissions while loading, and clear old errors before retrying. Reset invalidates older responses and allows a new request; disposal ignores all later completions. Reset does not cancel remote work. Do not treat a provider reset as undoing a production signup.
|
||||
|
||||
Services return `AuthResult` or throw `AuthException` with a typed `AuthError`. Unexpected exceptions are reduced to `unexpected`; raw errors and credentials are not retained in provider state. Credentials exist only as ephemeral request input. Localize error codes in each consuming application.
|
||||
|
||||
`DummyLoginService` and `DummySignupService` default to 600ms latency and simulated success. They do not validate credentials against an account registry, create accounts, issue tokens, open sessions, send requests, or persist data. Configure errors explicitly:
|
||||
|
||||
```dart
|
||||
final service = DummyLoginService(
|
||||
delay: Duration.zero,
|
||||
failure: AuthError.invalidCredentials,
|
||||
);
|
||||
```
|
||||
|
||||
Supported failure codes: `invalidCredentials`, `emailInUse`, `unavailable`, and `unexpected`. Inject another implementation for deterministic retry scenarios or production integration. `AuthResult.isSimulated` distinguishes dummy responses; a successful operation alone must never be treated as an authorization decision. The package does not implement authenticated application/session state yet.
|
||||
|
||||
## Sendico reuse
|
||||
|
||||
Adapted the ChangeNotifier lifecycle, service separation, locale-carrying request, and typed-outcome patterns from Sendico's `pshared/lib/provider/account.dart`, `models/auth/login_outcome.dart`, and `service/authorization/client.dart`. These were patterns rather than directly portable implementations: the originals depend on Sendico account/organization models, device IDs, static API services, token storage, and verification flows. Those dependencies are deliberately absent here. The B2B organization signup contract is not copied into the consumer product.
|
||||
|
||||
When a supported sxchnge BFF contract exists, implement transport DTOs and mappers behind the service interfaces, returning domain results. No dummy DTO/mapping layer is needed without serialized transport. Keep web cookie and mobile credential handling in production platform adapters, not the providers.
|
||||
|
||||
## Validation
|
||||
|
||||
`flutter analyze` and `flutter test` from this directory; `make test-frontend` from the repository root also runs all consuming app and theme tests. Tests cover duplicate submission, request forwarding, typed/unexpected failures, retry, reset races, disposal, and both dummy implementations.
|
||||
|
||||
## Email verification
|
||||
|
||||
`VerificationService` exposes `send(email, locale)` and `confirm(token)` as named-argument methods. Inject an implementation into `VerificationProvider`, shared by web and mobile. The provider exposes immutable `VerificationState` (idle/sending/sent/checking/verified/expired/invalid/error), suppresses concurrent duplicate operations, and ignores completions after reset or disposal. Typed `VerificationException` maps confirmation failures; unknown exceptions become internal errors without exposing exception text. Sending failures always become the general error state.
|
||||
|
||||
`DummyVerificationService` supports `demo-valid`, `demo-expired`, and `demo-internal` confirmation tokens; other tokens are invalid. Configure `delay` and `sendFailure` for tests. Results are explicitly simulated. It performs no network, storage, mail delivery, or account mutation. A production adapter must implement backend validation, delivery, rate limits, and safe token handling; this client provider is not an authorization boundary.
|
||||
Reference in new issue
Block a user