+59
.vscode/launch.json
···
+16
-1
android/app/build.gradle.kts
···-// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).···
android/app/src/main/res/drawable-hdpi/ic_launcher_foreground.png
This is a binary file and will not be displayed.
android/app/src/main/res/drawable-mdpi/ic_launcher_foreground.png
This is a binary file and will not be displayed.
android/app/src/main/res/drawable-xhdpi/ic_launcher_foreground.png
This is a binary file and will not be displayed.
android/app/src/main/res/drawable-xxhdpi/ic_launcher_foreground.png
This is a binary file and will not be displayed.
android/app/src/main/res/drawable-xxxhdpi/ic_launcher_foreground.png
This is a binary file and will not be displayed.
android/app/src/main/res/mipmap-hdpi/ic_launcher.png
This is a binary file and will not be displayed.
android/app/src/main/res/mipmap-mdpi/ic_launcher.png
This is a binary file and will not be displayed.
android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
This is a binary file and will not be displayed.
android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
This is a binary file and will not be displayed.
android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
This is a binary file and will not be displayed.
assets/logo/lil_dude.png
This is a binary file and will not be displayed.
assets/logo/lil_dude_padded.png
This is a binary file and will not be displayed.
+8
ios/Flutter/Dev-Debug.xcconfig
+8
ios/Flutter/Dev-Release.xcconfig
+8
ios/Flutter/Prod-Debug.xcconfig
+8
ios/Flutter/Prod-Release.xcconfig
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
This is a binary file and will not be displayed.
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
This is a binary file and will not be displayed.
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
This is a binary file and will not be displayed.
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
This is a binary file and will not be displayed.
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
This is a binary file and will not be displayed.
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
This is a binary file and will not be displayed.
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
This is a binary file and will not be displayed.
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
This is a binary file and will not be displayed.
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
This is a binary file and will not be displayed.
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
This is a binary file and will not be displayed.
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@1x.png
This is a binary file and will not be displayed.
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@2x.png
This is a binary file and will not be displayed.
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png
This is a binary file and will not be displayed.
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@2x.png
This is a binary file and will not be displayed.
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
This is a binary file and will not be displayed.
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
This is a binary file and will not be displayed.
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@1x.png
This is a binary file and will not be displayed.
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@2x.png
This is a binary file and will not be displayed.
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
This is a binary file and will not be displayed.
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
This is a binary file and will not be displayed.
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
This is a binary file and will not be displayed.
+47
-14
lib/config/environment_config.dart
·········
+112
lib/models/coves_session.dart
···
+1102
test/services/coves_auth_service_test.mocks.dart
···
+17
-56
lib/config/oauth_config.dart
···
+98
-155
lib/providers/auth_provider.dart
···-/// โ Tokens are stored securely by the package (iOS Keychain / Android EncryptedSharedPreferences)·········
+5
-4
test/services/coves_api_service_test.dart
···············
-158
test/services/vote_service_test.mocks.dart
···
-296
lib/services/oauth_service.dart
···-print('โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ');-print('โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ');
-337
packages/atproto_oauth_flutter/CHUNK3_IMPLEMENTATION_REPORT.md
···-Successfully ported the **atProto Identity Resolution Layer** from TypeScript to Dart with full 1:1 API compatibility. This is the **most critical component for atProto decentralization**, enabling users to host their data on any Personal Data Server (PDS) instead of being locked to bsky.social.-- `/home/bretton/Code/coves_flutter/packages/atproto_oauth_flutter/test/identity_resolver_test.dart`-- `/home/bretton/Code/coves_flutter/packages/atproto_oauth_flutter/example/identity_resolver_example.dart`-- `/home/bretton/Code/coves_flutter/packages/atproto_oauth_flutter/lib/src/identity/README.md`-This implementation enables true atProto decentralization by ensuring apps discover where each user's data lives, rather than hardcoding centralized servers.-**Next Steps:** Integrate this into the OAuth client (Chunk 4+) to complete the full OAuth flow with proper PDS discovery.
-373
packages/atproto_oauth_flutter/CHUNK_5_IMPLEMENTATION.md
···-This chunk implements the session management layer for atproto OAuth in Dart, providing a complete 1:1 port of the TypeScript implementation from `@atproto/oauth-client`.-**Problem**: `OAuthSession` needs `SessionGetter`, but `SessionGetter` returns `Session` objects that are used by `OAuthSession`.-**Solution**: Created `SessionGetterInterface` in `oauth_session.dart` as an abstract interface. `SessionGetter` in `session_getter.dart` will implement this interface in later chunks when all dependencies are available.-| `SessionGetter.getSession(sub, refresh?)` | `SessionGetter.getSession(sub, [refresh])` | Identical API |-| `SessionGetter.addEventListener('updated', ...)` | `SessionGetter.onUpdated.listen(...)` | Stream-based |-| `SessionGetter.addEventListener('deleted', ...)` | `SessionGetter.onDeleted.listen(...)` | Stream-based |-| `session.fetchHandler(pathname, init?)` | `session.fetchHandler(pathname, {method, headers, body})` | Named parameters |-These are intentional - this chunk focuses on the session management *structure*, with concrete implementations following in later chunks.-The code is production-ready structurally and awaits concrete implementations from subsequent chunks.
-102
packages/atproto_oauth_flutter/IMPLEMENTATION_PLAN.md
···-- `src/oauth-authorization-server-metadata-resolver.ts` โ `lib/src/oauth/authorization_server_metadata_resolver.dart`-- `src/oauth-protected-resource-metadata-resolver.ts` โ `lib/src/oauth/protected_resource_metadata_resolver.dart`
-394
packages/atproto_oauth_flutter/IMPLEMENTATION_STATUS.md
···-This is a **complete 1:1 port** of the TypeScript `@atproto/oauth-client` package to Dart/Flutter.
-1238
packages/atproto_oauth_flutter/README.md
···-**Official AT Protocol OAuth client for Flutter** - A complete 1:1 port of the TypeScript `@atproto/oauth-client` package.-`atproto_oauth_flutter` is a complete OAuth 2.0 + OpenID Connect client for the AT Protocol, designed specifically for Flutter applications. It handles the full authentication lifecycle including:-The existing `atproto_oauth` package has a **critical flaw**: it **hardcodes `bsky.social`** as the OAuth provider. This breaks the decentralized nature of the AT Protocol.-**Bottom line:** This is the only Flutter package that properly implements decentralized atProto OAuth.-OAuth requires deep linking to redirect back to your app after authentication. You must configure both platforms:-Then create an `apple-app-site-association` file on your server at `https://example.com/.well-known/apple-app-site-association`.-**For HTTPS universal links**, also create a `assetlinks.json` file at `https://example.com/.well-known/assetlinks.json`.-**โ ๏ธ Important:** If you're using declarative routing packages like `go_router` or `auto_route`, you MUST configure them to ignore OAuth callback deep links. Otherwise, the router will intercept the callback and OAuth will fail with "User canceled login".-When the OAuth server redirects back to your app with the authorization code, your router may try to handle the deep link before `flutter_web_auth_2` can capture it. This causes the OAuth flow to fail.-The key is to **not process URIs with your custom OAuth scheme** - let `flutter_web_auth_2` handle them.-- `responseMode` - How OAuth parameters are returned: `query` (default, URL query string) or `fragment` (URL fragment)-- `allowHttp` - Allow HTTP connections for development (default: `false`, **never use in production**)-- `input` - Handle (e.g., `"alice.bsky.social"`), DID (e.g., `"did:plc:..."`), PDS URL, or auth server URL-- `options` - Additional OAuth parameters (optional, see [AuthorizeOptions](#authorizeoptions))-- `scope` - Requested scope (default: `"atproto"`, recommended: `"atproto transition:generic"`)-**atProto is decentralized.** Users can host their data on any PDS. Your app should work with ALL of them.-3. **Identity Resolution** - DID/handle โ PDS discovery (**critical for decentralization**)-- **Based on:** Official Bluesky [`@atproto/oauth-client`](https://github.com/bluesky-social/atproto/tree/main/packages/oauth/oauth-client)
-220
packages/atproto_oauth_flutter/example/flutter_oauth_example.dart
···
-104
packages/atproto_oauth_flutter/example/identity_resolver_example.dart
···
-104
packages/atproto_oauth_flutter/lib/atproto_oauth_flutter.dart
···
-977
packages/atproto_oauth_flutter/lib/src/client/oauth_client.dart
···
-2
packages/atproto_oauth_flutter/lib/src/constants.dart
-593
packages/atproto_oauth_flutter/lib/src/dpop/fetch_dpop.dart
···
-14
packages/atproto_oauth_flutter/lib/src/errors/auth_method_unsatisfiable_error.dart
···
-10
packages/atproto_oauth_flutter/lib/src/errors/errors.dart
···
-51
packages/atproto_oauth_flutter/lib/src/errors/oauth_callback_error.dart
···
-47
packages/atproto_oauth_flutter/lib/src/errors/oauth_resolver_error.dart
···
-62
packages/atproto_oauth_flutter/lib/src/errors/oauth_response_error.dart
···
-22
packages/atproto_oauth_flutter/lib/src/errors/token_invalid_error.dart
···
-21
packages/atproto_oauth_flutter/lib/src/errors/token_refresh_error.dart
···
-22
packages/atproto_oauth_flutter/lib/src/errors/token_revoked_error.dart
···
-263
packages/atproto_oauth_flutter/lib/src/identity/README.md
···-This module implements the **critical identity resolution functionality** for atProto decentralization. It resolves atProto handles and DIDs to discover where user data is actually stored (their Personal Data Server).-Main interface for resolving identities. Use `AtprotoIdentityResolver` for the standard implementation.
-29
packages/atproto_oauth_flutter/lib/src/identity/constants.dart
···
-156
packages/atproto_oauth_flutter/lib/src/identity/did_document.dart
···
-251
packages/atproto_oauth_flutter/lib/src/identity/did_helpers.dart
···
-257
packages/atproto_oauth_flutter/lib/src/identity/did_resolver.dart
···
-35
packages/atproto_oauth_flutter/lib/src/identity/handle_helpers.dart
···-// Pattern: ([a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?
-202
packages/atproto_oauth_flutter/lib/src/identity/handle_resolver.dart
···
-47
packages/atproto_oauth_flutter/lib/src/identity/identity.dart
···
-366
packages/atproto_oauth_flutter/lib/src/identity/identity_resolver.dart
···
-53
packages/atproto_oauth_flutter/lib/src/identity/identity_resolver_error.dart
···
-248
packages/atproto_oauth_flutter/lib/src/oauth/authorization_server_metadata_resolver.dart
···
-285
packages/atproto_oauth_flutter/lib/src/oauth/client_auth.dart
···-? 'Client authentication method "$method" requires at least one "$fallbackAlg" signing key with a "kid" property'-: 'Authorization server requires "$method" authentication method, but does not support "$fallbackAlg" algorithm.',-'The ATProto OAuth spec requires that client use either "none" or "private_key_jwt" authentication method.' +-? ' You might want to explicitly set "token_endpoint_auth_method" to one of those values in the client metadata document.'
-307
packages/atproto_oauth_flutter/lib/src/oauth/oauth_resolver.dart
···
-519
packages/atproto_oauth_flutter/lib/src/oauth/oauth_server_agent.dart
···-' Cached nonce: ${cachedNonce != null ? "โ ${cachedNonce.substring(0, 20)}..." : "โ not found"}',-/// [endpoint] is the endpoint name (e.g., 'token', 'revocation', 'pushed_authorization_request').
-117
packages/atproto_oauth_flutter/lib/src/oauth/oauth_server_factory.dart
···
-196
packages/atproto_oauth_flutter/lib/src/oauth/protected_resource_metadata_resolver.dart
···-'Unsecure resource metadata URL ($protocol) only allowed in development and test environments',
-213
packages/atproto_oauth_flutter/lib/src/oauth/validate_client_metadata.dart
···
-330
packages/atproto_oauth_flutter/lib/src/platform/README.md
···-The platform layer provides concrete implementations of all the abstract interfaces needed for OAuth to work on Flutter:-โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ-โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ-โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ-โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ-โโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโ-โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ-โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ-โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ-โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ-For most Flutter apps, this is fine. For advanced use cases, implement a platform-specific lock.-Cache TTLs are fixed (1 minute for most caches). Consider making these configurable if your app has different caching requirements.
-435
packages/atproto_oauth_flutter/lib/src/platform/flutter_key.dart
···
-302
packages/atproto_oauth_flutter/lib/src/platform/flutter_oauth_client.dart
···
-141
packages/atproto_oauth_flutter/lib/src/platform/flutter_oauth_router_helper.dart
···-// Extract URI from the state object (works with any router's state object that has a 'uri' property)
-91
packages/atproto_oauth_flutter/lib/src/platform/flutter_runtime.dart
···
-341
packages/atproto_oauth_flutter/lib/src/platform/flutter_stores.dart
···
-280
packages/atproto_oauth_flutter/lib/src/runtime/runtime.dart
···
-167
packages/atproto_oauth_flutter/lib/src/runtime/runtime_implementation.dart
···-/// This ensures that only one execution of the function can run at a time for a given lock name.
-395
packages/atproto_oauth_flutter/lib/src/session/oauth_session.dart
···
-42
packages/atproto_oauth_flutter/lib/src/session/session.dart
···
-644
packages/atproto_oauth_flutter/lib/src/session/session_getter.dart
···
-112
packages/atproto_oauth_flutter/lib/src/session/state_store.dart
···
-352
packages/atproto_oauth_flutter/lib/src/types.dart
···
-195
packages/atproto_oauth_flutter/lib/src/util.dart
···
-100
packages/atproto_oauth_flutter/lib/src/utils/lock.dart
···
-530
packages/atproto_oauth_flutter/pubspec.lock
···
-24
packages/atproto_oauth_flutter/pubspec.yaml
···
-245
packages/atproto_oauth_flutter/test/identity_resolver_test.dart
···
+10
ios/Runner/Runner.entitlements
···+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+11
-4
test/widgets/feed_screen_test.dart
···············
-1
lib/widgets/icons/bluesky_icons.dart
+1
-3
lib/widgets/post_action_bar.dart
···
+15
-18
lib/widgets/post_card.dart
······
+6
-8
lib/widgets/post_card_actions.dart
···
+2
-19
test/services/coves_auth_service_redaction_test.dart
···
+1
test/services/coves_auth_service_singleton_test.dart
···
-1
test/services/coves_auth_service_validation_test.dart
+9
-2
lib/models/comment.dart
···
+41
lib/models/post.dart
············
+20
-51
lib/providers/vote_provider.dart
············
+229
-1
test/providers/feed_provider_test.dart
············
+134
-28
test/providers/vote_provider_test.dart
···················································
+1102
test/services/coves_auth_service_environment_test.mocks.dart
···
+1102
test/services/coves_auth_service_singleton_test.mocks.dart
···
+1102
test/services/coves_auth_service_validation_test.mocks.dart
···
+14
-42
test/services/vote_service_token_refresh_test.dart
······
+6
lib/services/api_exceptions.dart
···
+170
lib/services/comment_service.dart
···
+1
pubspec.yaml
···
+153
lib/services/auth_interceptor.dart
···
+11
lib/main.dart
············
+91
-44
test/providers/comments_provider_test.mocks.dart
···················································
+357
test/services/comment_service_test.dart
···
+806
test/services/comment_service_test.mocks.dart
···
+42
-5
lib/providers/feed_provider.dart
··················
+12
-8
lib/screens/home/search_screen.dart
lib/screens/home/communities_screen.dart
·········
+162
-14
lib/screens/home/feed_screen.dart
············
+24
-13
lib/screens/home/main_shell_screen.dart
············
+117
-67
lib/widgets/comment_card.dart
·········
+3
.gitignore
+1
ios/Flutter/Debug.xcconfig
+1
ios/Flutter/Release.xcconfig
+43
ios/Podfile
···+generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)+raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"+raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"+require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
+4
-4
pubspec.lock
······
+1
-1
ios/Flutter/AppFrameworkInfo.plist
+68
ios/Podfile.lock
···+- shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`)