diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index 29bdf98..fd1d358 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -42,6 +42,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/assets/images/oidc/google.svg b/assets/images/oidc/google.svg
new file mode 100644
index 0000000..9d25a23
--- /dev/null
+++ b/assets/images/oidc/google.svg
@@ -0,0 +1,104 @@
+
diff --git a/assets/images/oidc/microsoft.svg b/assets/images/oidc/microsoft.svg
new file mode 100644
index 0000000..5334aa7
--- /dev/null
+++ b/assets/images/oidc/microsoft.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/ios/Podfile.lock b/ios/Podfile.lock
index 4933b9c..acaa896 100644
--- a/ios/Podfile.lock
+++ b/ios/Podfile.lock
@@ -158,6 +158,8 @@ PODS:
- shared_preferences_foundation (0.0.1):
- Flutter
- FlutterMacOS
+ - sign_in_with_apple (0.0.1):
+ - Flutter
- sqflite_darwin (0.0.4):
- Flutter
- FlutterMacOS
@@ -221,6 +223,7 @@ DEPENDENCIES:
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`)
- record_ios (from `.symlinks/plugins/record_ios/ios`)
- shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`)
+ - sign_in_with_apple (from `.symlinks/plugins/sign_in_with_apple/ios`)
- sqflite_darwin (from `.symlinks/plugins/sqflite_darwin/darwin`)
- sqlite3_flutter_libs (from `.symlinks/plugins/sqlite3_flutter_libs/darwin`)
- super_native_extensions (from `.symlinks/plugins/super_native_extensions/ios`)
@@ -299,6 +302,8 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/record_ios/ios"
shared_preferences_foundation:
:path: ".symlinks/plugins/shared_preferences_foundation/darwin"
+ sign_in_with_apple:
+ :path: ".symlinks/plugins/sign_in_with_apple/ios"
sqflite_darwin:
:path: ".symlinks/plugins/sqflite_darwin/darwin"
sqlite3_flutter_libs:
@@ -353,6 +358,7 @@ SPEC CHECKSUMS:
SAMKeychain: 483e1c9f32984d50ca961e26818a534283b4cd5c
SDWebImage: f29024626962457f3470184232766516dee8dfea
shared_preferences_foundation: 9e1978ff2562383bd5676f64ec4e9aa8fa06a6f7
+ sign_in_with_apple: c5dcc141574c8c54d5ac99dd2163c0c72ad22418
sqflite_darwin: 20b2a3a3b70e43edae938624ce550a3cbf66a3d0
sqlite3: 1d85290c3321153511f6e900ede7a1608718bbd5
sqlite3_flutter_libs: e7fc8c9ea2200ff3271f08f127842131746b70e2
diff --git a/ios/Runner/Runner.entitlements b/ios/Runner/Runner.entitlements
index e14e33c..791a15a 100644
--- a/ios/Runner/Runner.entitlements
+++ b/ios/Runner/Runner.entitlements
@@ -4,6 +4,14 @@
aps-environment
development
+ com.apple.developer.applesignin
+
+ Default
+
+ com.apple.developer.associated-domains
+
+ webcredentials:solian.app
+
com.apple.developer.device-information.user-assigned-device-name
com.apple.developer.usernotifications.communication
diff --git a/lib/screens/auth/login.dart b/lib/screens/auth/login.dart
index 3d0169b..6e1478a 100644
--- a/lib/screens/auth/login.dart
+++ b/lib/screens/auth/login.dart
@@ -11,6 +11,7 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:flutter_otp_text_field/flutter_otp_text_field.dart';
+import 'package:flutter_svg/svg.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:gap/gap.dart';
import 'package:island/models/auth.dart';
@@ -23,6 +24,7 @@ import 'package:island/services/udid.dart';
import 'package:island/widgets/alert.dart';
import 'package:island/widgets/app_scaffold.dart';
import 'package:material_symbols_icons/symbols.dart';
+import 'package:sign_in_with_apple/sign_in_with_apple.dart';
import 'package:styled_widget/styled_widget.dart';
import 'package:url_launcher/url_launcher_string.dart';
@@ -558,6 +560,43 @@ class _LoginLookupScreen extends HookConsumerWidget {
}
}
+ Future withApple() async {
+ final client = ref.watch(apiClientProvider);
+ try {
+ final credential = await SignInWithApple.getAppleIDCredential(
+ scopes: [AppleIDAuthorizationScopes.email],
+ );
+
+ if (context.mounted) showLoadingModal(context);
+
+ final resp = await client.post(
+ '/auth/login/apple/mobile',
+ data: {
+ 'identity_token': credential.identityToken!,
+ 'authorization_code': credential.authorizationCode,
+ },
+ );
+ final token = resp.data['token'];
+ setToken(ref.watch(sharedPreferencesProvider), token);
+ ref.invalidate(tokenProvider);
+ if (!context.mounted) return;
+
+ // Do post login tasks
+ final userNotifier = ref.read(userInfoProvider.notifier);
+ userNotifier.fetchUser().then((_) {
+ final apiClient = ref.read(apiClientProvider);
+ subscribePushNotification(apiClient);
+ final wsNotifier = ref.read(websocketStateProvider.notifier);
+ wsNotifier.connect();
+ if (context.mounted) Navigator.pop(context, true);
+ });
+ } catch (err) {
+ showErrorAlert(err);
+ } finally {
+ if (context.mounted) hideLoadingModal(context);
+ }
+ }
+
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
@@ -586,7 +625,45 @@ class _LoginLookupScreen extends HookConsumerWidget {
onTapOutside: (_) => FocusManager.instance.primaryFocus?.unfocus(),
onSubmitted: isBusy.value ? null : (_) => performNewTicket(),
).padding(horizontal: 7),
- const Gap(12),
+ Row(
+ spacing: 4,
+ crossAxisAlignment: CrossAxisAlignment.center,
+ children: [
+ Text("loginOr").tr().fontSize(11).opacity(0.85),
+ const Gap(8),
+ Spacer(),
+ IconButton.filled(
+ onPressed: () async {},
+ padding: EdgeInsets.zero,
+ icon: SvgPicture.asset(
+ 'assets/images/oidc/google.svg',
+ width: 16,
+ height: 16,
+ ),
+ tooltip: 'Google',
+ ),
+ IconButton.filled(
+ onPressed: () async {},
+ padding: EdgeInsets.zero,
+ icon: SvgPicture.asset(
+ 'assets/images/oidc/microsoft.svg',
+ width: 16,
+ height: 16,
+ ),
+ tooltip: 'Microsoft',
+ ),
+ IconButton.filled(
+ onPressed: withApple,
+ padding: EdgeInsets.zero,
+ icon: SvgPicture.asset(
+ 'assets/images/oidc/apple.svg',
+ width: 16,
+ height: 16,
+ ),
+ tooltip: 'Apple Account',
+ ),
+ ],
+ ).padding(horizontal: 8, top: 8, bottom: 4),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift
index cf37ccd..8824bf0 100644
--- a/macos/Flutter/GeneratedPluginRegistrant.swift
+++ b/macos/Flutter/GeneratedPluginRegistrant.swift
@@ -27,6 +27,7 @@ import pasteboard
import path_provider_foundation
import record_macos
import shared_preferences_foundation
+import sign_in_with_apple
import sqflite_darwin
import sqlite3_flutter_libs
import super_native_extensions
@@ -57,6 +58,7 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
RecordMacOsPlugin.register(with: registry.registrar(forPlugin: "RecordMacOsPlugin"))
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
+ SignInWithApplePlugin.register(with: registry.registrar(forPlugin: "SignInWithApplePlugin"))
SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin"))
Sqlite3FlutterLibsPlugin.register(with: registry.registrar(forPlugin: "Sqlite3FlutterLibsPlugin"))
SuperNativeExtensionsPlugin.register(with: registry.registrar(forPlugin: "SuperNativeExtensionsPlugin"))
diff --git a/macos/Runner/DebugProfile.entitlements b/macos/Runner/DebugProfile.entitlements
index 157dc8e..07f0ebe 100644
--- a/macos/Runner/DebugProfile.entitlements
+++ b/macos/Runner/DebugProfile.entitlements
@@ -2,6 +2,12 @@
+ com.apple.developer.applesignin
+
+ Default
+
+ com.apple.developer.device-information.user-assigned-device-name
+
com.apple.security.app-sandbox
com.apple.security.cs.allow-jit
@@ -18,7 +24,5 @@
com.apple.security.network.server
- com.apple.developer.device-information.user-assigned-device-name
-
diff --git a/macos/Runner/Release.entitlements b/macos/Runner/Release.entitlements
index e29630b..8d4672b 100644
--- a/macos/Runner/Release.entitlements
+++ b/macos/Runner/Release.entitlements
@@ -2,6 +2,12 @@
+ com.apple.developer.applesignin
+
+ Default
+
+ com.apple.developer.device-information.user-assigned-device-name
+
com.apple.security.app-sandbox
com.apple.security.device.audio-input
@@ -16,7 +22,5 @@
com.apple.security.network.server
- com.apple.developer.device-information.user-assigned-device-name
-
diff --git a/pubspec.lock b/pubspec.lock
index 2667b91..ce9c89c 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -892,7 +892,7 @@ packages:
source: hosted
version: "2.6.1"
flutter_svg:
- dependency: transitive
+ dependency: "direct main"
description:
name: flutter_svg
sha256: d44bf546b13025ec7353091516f6881f1d4c633993cb109c3916c3a0159dadf1
@@ -1901,6 +1901,30 @@ packages:
url: "https://pub.dev"
source: hosted
version: "3.0.0"
+ sign_in_with_apple:
+ dependency: "direct main"
+ description:
+ name: sign_in_with_apple
+ sha256: "8bd875c8e8748272749eb6d25b896f768e7e9d60988446d543fe85a37a2392b8"
+ url: "https://pub.dev"
+ source: hosted
+ version: "7.0.1"
+ sign_in_with_apple_platform_interface:
+ dependency: transitive
+ description:
+ name: sign_in_with_apple_platform_interface
+ sha256: "981bca52cf3bb9c3ad7ef44aace2d543e5c468bb713fd8dda4275ff76dfa6659"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.0.0"
+ sign_in_with_apple_web:
+ dependency: transitive
+ description:
+ name: sign_in_with_apple_web
+ sha256: f316400827f52cafcf50d00e1a2e8a0abc534ca1264e856a81c5f06bd5b10fed
+ url: "https://pub.dev"
+ source: hosted
+ version: "3.0.0"
simple_gesture_detector:
dependency: transitive
description:
diff --git a/pubspec.yaml b/pubspec.yaml
index 0d9f8da..ccf7028 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -113,6 +113,8 @@ dependencies:
timezone: ^0.10.1
flutter_timezone: ^4.1.1
fl_chart: ^1.0.0
+ sign_in_with_apple: ^7.0.1
+ flutter_svg: ^2.1.0
dev_dependencies:
flutter_test:
@@ -147,6 +149,9 @@ flutter:
# To add assets to your application, add an assets section, like this:
assets:
- assets/i18n/
+ - assets/images/
+ - assets/images/oidc/
+ - assets/icons/
# An image asset can refer to one or more resolution-specific "variants", see
# https://flutter.dev/to/resolution-aware-images
diff --git a/web/index.html b/web/index.html
index 8c5a739..51e26be 100644
--- a/web/index.html
+++ b/web/index.html
@@ -1,4 +1,4 @@
-
+
+
+
+
@@ -275,4 +283,3 @@
-