diff --git a/flutter/assets/auth-apple.svg b/flutter/assets/auth-apple.svg
new file mode 100644
index 000000000..a3c2e871d
--- /dev/null
+++ b/flutter/assets/auth-apple.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/flutter/assets/auth-azure.svg b/flutter/assets/auth-azure.svg
new file mode 100644
index 000000000..0482b22e6
--- /dev/null
+++ b/flutter/assets/auth-azure.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/flutter/assets/auth-default.svg b/flutter/assets/auth-default.svg
new file mode 100644
index 000000000..905c9ca9b
--- /dev/null
+++ b/flutter/assets/auth-default.svg
@@ -0,0 +1,14 @@
+
+
+
diff --git a/flutter/assets/auth-facebook.svg b/flutter/assets/auth-facebook.svg
new file mode 100644
index 000000000..d921a6716
--- /dev/null
+++ b/flutter/assets/auth-facebook.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/flutter/assets/GitHub.svg b/flutter/assets/auth-github.svg
similarity index 100%
rename from flutter/assets/GitHub.svg
rename to flutter/assets/auth-github.svg
diff --git a/flutter/assets/Google.svg b/flutter/assets/auth-google.svg
similarity index 100%
rename from flutter/assets/Google.svg
rename to flutter/assets/auth-google.svg
diff --git a/flutter/assets/Okta.svg b/flutter/assets/auth-okta.svg
similarity index 100%
rename from flutter/assets/Okta.svg
rename to flutter/assets/auth-okta.svg
diff --git a/flutter/lib/common.dart b/flutter/lib/common.dart
index e96f02772..71fbfcdd9 100644
--- a/flutter/lib/common.dart
+++ b/flutter/lib/common.dart
@@ -2314,3 +2314,10 @@ Widget unreadTopRightBuilder(RxInt? count, {Widget? icon}) {
],
);
}
+
+String toCapitalized(String s) {
+ if (s.isEmpty) {
+ return s;
+ }
+ return s.substring(0, 1).toUpperCase() + s.substring(1);
+}
diff --git a/flutter/lib/common/widgets/login.dart b/flutter/lib/common/widgets/login.dart
index 17cc7090c..1eecdc2d5 100644
--- a/flutter/lib/common/widgets/login.dart
+++ b/flutter/lib/common/widgets/login.dart
@@ -13,13 +13,13 @@ import '../../common.dart';
import './dialog.dart';
class _IconOP extends StatelessWidget {
- final String icon;
- final double iconWidth;
+ final String op;
+ final String? icon;
final EdgeInsets margin;
const _IconOP(
{Key? key,
+ required this.op,
required this.icon,
- required this.iconWidth,
this.margin = const EdgeInsets.symmetric(horizontal: 4.0)})
: super(key: key);
@@ -27,10 +27,15 @@ class _IconOP extends StatelessWidget {
Widget build(BuildContext context) {
return Container(
margin: margin,
- child: SvgPicture.asset(
- 'assets/$icon.svg',
- width: iconWidth,
- ),
+ child: icon == null
+ ? SvgPicture.asset(
+ 'assets/auth-${op.toLowerCase()}.svg',
+ width: 20,
+ )
+ : SvgPicture.string(
+ icon!,
+ width: 20,
+ ),
);
}
}
@@ -38,7 +43,7 @@ class _IconOP extends StatelessWidget {
class ButtonOP extends StatelessWidget {
final String op;
final RxString curOP;
- final double iconWidth;
+ final String? icon;
final Color primaryColor;
final double height;
final Function() onTap;
@@ -47,7 +52,7 @@ class ButtonOP extends StatelessWidget {
Key? key,
required this.op,
required this.curOP,
- required this.iconWidth,
+ required this.icon,
required this.primaryColor,
required this.height,
required this.onTap,
@@ -71,15 +76,15 @@ class ButtonOP extends StatelessWidget {
SizedBox(
width: 30,
child: _IconOP(
- icon: op,
- iconWidth: iconWidth,
+ op: op,
+ icon: icon,
margin: EdgeInsets.only(right: 5),
)),
Expanded(
child: FittedBox(
fit: BoxFit.scaleDown,
child: Center(
- child: Text('${translate("Continue with")} $op')))),
+ child: Text('${translate("Continue with")} ${toCapitalized(op)}')))),
],
))),
),
@@ -89,8 +94,8 @@ class ButtonOP extends StatelessWidget {
class ConfigOP {
final String op;
- final double iconWidth;
- ConfigOP({required this.op, required this.iconWidth});
+ final String? icon;
+ ConfigOP({required this.op, required this.icon});
}
class WidgetOP extends StatefulWidget {
@@ -182,7 +187,7 @@ class _WidgetOPState extends State {
ButtonOP(
op: widget.config.op,
curOP: widget.curOP,
- iconWidth: widget.config.iconWidth,
+ icon: widget.config.icon,
primaryColor: str2color(widget.config.op, 0x7f),
height: 36,
onTap: () async {
@@ -380,7 +385,7 @@ Future loginDialog() async {
final loginOptions = [].obs;
Future.delayed(Duration.zero, () async {
- loginOptions.value = await UserModel.queryLoginOptions();
+ loginOptions.value = await UserModel.queryOidcLoginOptions();
});
final res = await gFFI.dialogManager.show((setState, close, context) {
@@ -460,12 +465,8 @@ Future loginDialog() async {
}
thirdAuthWidget() => Obx(() {
- final oidcOptions = loginOptions
- .where((opt) => opt.startsWith(kAuthReqTypeOidc))
- .map((opt) => opt.substring(kAuthReqTypeOidc.length))
- .toList();
return Offstage(
- offstage: oidcOptions.isEmpty,
+ offstage: loginOptions.isEmpty,
child: Column(
children: [
const SizedBox(
@@ -480,12 +481,8 @@ Future loginDialog() async {
height: 8.0,
),
LoginWidgetOP(
- ops: [
- ConfigOP(op: 'GitHub', iconWidth: 20),
- ConfigOP(op: 'Google', iconWidth: 20),
- ConfigOP(op: 'Okta', iconWidth: 38),
- ]
- .where((op) => oidcOptions.contains(op.op.toLowerCase()))
+ ops: loginOptions
+ .map((e) => ConfigOP(op: e['name'], icon: e['icon']))
.toList(),
curOP: curOP,
cbLogin: (Map authBody) {
diff --git a/flutter/lib/models/user_model.dart b/flutter/lib/models/user_model.dart
index 83df2e632..18f409608 100644
--- a/flutter/lib/models/user_model.dart
+++ b/flutter/lib/models/user_model.dart
@@ -163,15 +163,15 @@ class UserModel {
return loginResponse;
}
- static Future> queryLoginOptions() async {
+ static Future> queryOidcLoginOptions() async {
try {
final url = await bind.mainGetApiServer();
if (url.trim().isEmpty) return [];
- final resp = await http.get(Uri.parse('$url/api/login-options'));
+ final resp = await http.get(Uri.parse('$url/api/oidc/login-options'));
return jsonDecode(resp.body);
} catch (e) {
debugPrint(
- "queryLoginOptions: jsonDecode resp body failed: ${e.toString()}");
+ "queryOidcLoginOptions: jsonDecode resp body failed: ${e.toString()}");
return [];
}
}