Skip to content

Commit 856785b

Browse files
rayliverifiedclaude
andcommitted
Google, Apple and email-link sign-in and profile photos in AuthAction
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
1 parent 77c977d commit 856785b

3 files changed

Lines changed: 71 additions & 1 deletion

File tree

‎lib/src/api/models/action/auth_action.dart‎

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,24 @@ enum AuthOperation {
3232
updatePassword,
3333

3434
/// Deletes the signed-in user's account and signs them out.
35-
deleteAccount;
35+
deleteAccount,
36+
37+
/// Signs in with a Google account.
38+
signInWithGoogle,
39+
40+
/// Signs in with an Apple ID.
41+
signInWithApple,
42+
43+
/// Emails [AuthAction.email] a link that signs them in without a password.
44+
sendSignInLink,
45+
46+
/// Finishes signing in from the link [sendSignInLink] sent, when the app
47+
/// was opened from it. Run it when the screen loads.
48+
completeSignInLink,
49+
50+
/// Sets the signed-in user's photo to [AuthAction.photoUrl], e.g. the URL
51+
/// a Cloud Files upload gave.
52+
updatePhoto;
3653

3754
/// A readable name for this operation.
3855
String get label => switch (this) {
@@ -44,7 +61,21 @@ enum AuthOperation {
4461
sendEmailVerification => 'Send Verification Email',
4562
updatePassword => 'Change Password',
4663
deleteAccount => 'Delete Account',
64+
signInWithGoogle => 'Sign In with Google',
65+
signInWithApple => 'Sign In with Apple',
66+
sendSignInLink => 'Email a Sign-In Link',
67+
completeSignInLink => 'Finish Sign-In from Link',
68+
updatePhoto => 'Update Profile Photo',
4769
};
70+
71+
/// Whether this operation signs a user in or creates their account, after
72+
/// which the user's profile document is created when missing.
73+
bool get signsIn =>
74+
this == signIn ||
75+
this == signUp ||
76+
this == signInWithGoogle ||
77+
this == signInWithApple ||
78+
this == completeSignInLink;
4879
}
4980

5081
/// Signs app users in and out with email and password.
@@ -74,6 +105,10 @@ class AuthAction extends ActionModel with Equatable, SerializableMixin {
74105
/// [AuthOperation.updateProfile].
75106
final String displayName;
76107

108+
/// The photo URL, for [AuthOperation.updatePhoto].
109+
@JsonKey(defaultValue: '')
110+
final String photoUrl;
111+
77112
/// A text variable that receives the error message when the operation
78113
/// fails, and is cleared when it succeeds.
79114
final VariableData? errorVariable;
@@ -84,6 +119,7 @@ class AuthAction extends ActionModel with Equatable, SerializableMixin {
84119
this.email = '',
85120
this.password = '',
86121
this.displayName = '',
122+
this.photoUrl = '',
87123
this.errorVariable,
88124
super.nonBlocking,
89125
super.enabled,
@@ -95,12 +131,14 @@ class AuthAction extends ActionModel with Equatable, SerializableMixin {
95131
String? email,
96132
String? password,
97133
String? displayName,
134+
String? photoUrl,
98135
VariableData? errorVariable,
99136
}) => AuthAction(
100137
operation: operation ?? this.operation,
101138
email: email ?? this.email,
102139
password: password ?? this.password,
103140
displayName: displayName ?? this.displayName,
141+
photoUrl: photoUrl ?? this.photoUrl,
104142
errorVariable: errorVariable ?? this.errorVariable,
105143
nonBlocking: nonBlocking,
106144
enabled: enabled,
@@ -112,6 +150,7 @@ class AuthAction extends ActionModel with Equatable, SerializableMixin {
112150
email,
113151
password,
114152
displayName,
153+
photoUrl,
115154
errorVariable,
116155
];
117156

‎lib/src/api/models/action/auth_action.g.dart‎

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎test/auth_action_test.dart‎

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import 'package:codelessly_api/codelessly_api.dart';
2+
import 'package:test/test.dart';
3+
4+
void main() {
5+
test('social and link sign-in, and photo updates, round-trip', () {
6+
for (final AuthOperation operation in AuthOperation.values) {
7+
final AuthAction action = AuthAction(
8+
operation: operation,
9+
email: r'${email}',
10+
photoUrl: r'${result.url}',
11+
);
12+
expect(ActionModel.fromJson(action.toJson()), action);
13+
}
14+
expect(AuthAction().toJson().containsKey('photoUrl'), isFalse);
15+
});
16+
17+
test('operations that sign in', () {
18+
expect(AuthOperation.signInWithGoogle.signsIn, isTrue);
19+
expect(AuthOperation.completeSignInLink.signsIn, isTrue);
20+
expect(AuthOperation.sendSignInLink.signsIn, isFalse);
21+
expect(AuthOperation.updatePhoto.label, 'Update Profile Photo');
22+
});
23+
}

0 commit comments

Comments
 (0)