@@ -12,8 +12,12 @@ class Providers:
12
12
const TWITTER := "twitter"
13
13
14
14
signal signed_up (signed_user )
15
+ signal signed_up_phone (signed_user )
15
16
signal signed_in (signed_user )
16
- signal logged_out ()
17
+ signal signed_in_otp (signed_user )
18
+ signal otp_verified ()
19
+ signal signed_in_anonyous ()
20
+ signal signed_out ()
17
21
signal got_user ()
18
22
signal user_updated (updated_user )
19
23
signal magic_link_sent ()
@@ -25,6 +29,8 @@ signal error(supabase_error)
25
29
const _auth_endpoint : String = "/auth/v1"
26
30
const _provider_endpoint : String = _auth_endpoint + "/authorize"
27
31
const _signin_endpoint : String = _auth_endpoint + "/token?grant_type=password"
32
+ const _signin_otp_endpoint : String = _auth_endpoint + "/otp"
33
+ const _verify_otp_endpoint : String = _auth_endpoint + "/verify"
28
34
const _signup_endpoint : String = _auth_endpoint + "/signup"
29
35
const _refresh_token_endpoint : String = _auth_endpoint + "/token?grant_type=refresh_token"
30
36
const _logout_endpoint : String = _auth_endpoint + "/logout"
@@ -50,11 +56,18 @@ var client : SupabaseUser
50
56
func _init (conf : Dictionary , head : PoolStringArray ) -> void :
51
57
_config = conf
52
58
_header = head
53
- name = "Authentication"
59
+ name = "Authentication"
54
60
61
+ func _check_auth () -> AuthTask :
62
+ printerr ("User already authenticated. Please, logout before authenticating again." )
63
+ var auth_task : AuthTask = AuthTask .new (- 1 , "" , [], {})
64
+ auth_task .emit_signal ("completed" )
65
+ return auth_task
66
+
55
67
56
68
# Allow your users to sign up and create a new account.
57
69
func sign_up (email : String , password : String ) -> AuthTask :
70
+ if _auth != "" : return _check_auth ()
58
71
var payload : Dictionary = {"email" :email , "password" :password }
59
72
var auth_task : AuthTask = AuthTask .new (
60
73
AuthTask .Task .SIGNUP ,
@@ -65,8 +78,23 @@ func sign_up(email : String, password : String) -> AuthTask:
65
78
return auth_task
66
79
67
80
81
+ # Allow your users to sign up and create a new account using phone/password combination.
82
+ # NOTE: the OTP sent to the user must be verified.
83
+ func sign_up_phone (phone : String , password : String ) -> AuthTask :
84
+ if _auth != "" : return _check_auth ()
85
+ var payload : Dictionary = {"phone" :phone , "password" :password }
86
+ var auth_task : AuthTask = AuthTask .new (
87
+ AuthTask .Task .SIGNUPPHONEPASSWORD ,
88
+ _config .supabaseUrl + _signup_endpoint ,
89
+ _header ,
90
+ payload )
91
+ _process_task (auth_task )
92
+ return auth_task
93
+
94
+
68
95
# If an account is created, users can login to your app.
69
96
func sign_in (email : String , password : String = "" ) -> AuthTask :
97
+ if _auth != "" : return _check_auth ()
70
98
var payload : Dictionary = {"email" :email , "password" :password }
71
99
var auth_task : AuthTask = AuthTask .new (
72
100
AuthTask .Task .SIGNIN ,
@@ -77,12 +105,57 @@ func sign_in(email : String, password : String = "") -> AuthTask:
77
105
return auth_task
78
106
79
107
108
+ # If an account is created, users can login to your app using phone/password combination.
109
+ # NOTE: this requires sign_up_phone() and verify_otp() to work
110
+ func sign_in_phone (phone : String , password : String = "" ) -> AuthTask :
111
+ if _auth != "" : return _check_auth ()
112
+ var payload : Dictionary = {"phone" :phone , "password" :password }
113
+ var auth_task : AuthTask = AuthTask .new (
114
+ AuthTask .Task .SIGNIN ,
115
+ _config .supabaseUrl + _signin_endpoint ,
116
+ _header ,
117
+ payload )
118
+ _process_task (auth_task )
119
+ return auth_task
120
+
121
+
122
+ # Sign in using OTP - the user won't need to use a password but the token must be validated.
123
+ # This method always requires to use OTP verification, unlike sign_in_phone()
124
+ func sign_in_otp (phone : String ) -> AuthTask :
125
+ if _auth != "" : return _check_auth ()
126
+ var payload : Dictionary = {"phone" :phone }
127
+ var auth_task : AuthTask = AuthTask .new (
128
+ AuthTask .Task .SIGNINOTP ,
129
+ _config .supabaseUrl + _signin_otp_endpoint ,
130
+ _header ,
131
+ payload )
132
+ _process_task (auth_task )
133
+ return auth_task
134
+
135
+
136
+ # Verify the OTP token sent to a user as an SMS
137
+ func verify_otp (phone : String , token : String ) -> AuthTask :
138
+ if _auth != "" : return _check_auth ()
139
+ var payload : Dictionary = {phone = phone , token = token , type = "sms" }
140
+ var auth_task : AuthTask = AuthTask .new (
141
+ AuthTask .Task .VERIFYOTP ,
142
+ _config .supabaseUrl + _verify_otp_endpoint ,
143
+ _header ,
144
+ payload )
145
+ _process_task (auth_task )
146
+ return auth_task
147
+
148
+
149
+
80
150
# Sign in as an anonymous user
81
151
func sign_in_anonymous () -> void :
152
+ if _auth != "" : return
82
153
_auth = _config .supabaseKey
83
154
_bearer [0 ] = _bearer [0 ] % _auth
84
- emit_signal ("signed_in" , null )
155
+ emit_signal ("signed_in" )
156
+
85
157
158
+ # [ CURRENTLY UNSUPPORTED ]
86
159
# Sign in with a Provider
87
160
# @provider = Providers.PROVIDER
88
161
func sign_in_with_provider (provider : String , grab_from_browser : bool = true , port : int = 3000 ) -> void :
@@ -114,6 +187,7 @@ func send_magic_link(email : String) -> AuthTask:
114
187
_process_task (auth_task )
115
188
return auth_task
116
189
190
+
117
191
# Get the JSON object for the logged in user.
118
192
func user (user_access_token : String = _auth ) -> AuthTask :
119
193
var auth_task : AuthTask = AuthTask .new (
@@ -163,7 +237,7 @@ func invite_user_by_email(email : String) -> AuthTask:
163
237
# Refresh the access_token of the authenticated client using the refresh_token
164
238
# No need to call this manually except specific needs, since the process will be handled automatically
165
239
func refresh_token (refresh_token : String = client .refresh_token , expires_in : float = client .expires_in ) -> AuthTask :
166
- yield (get_tree ().create_timer (expires_in ), "timeout" )
240
+ yield (get_tree ().create_timer (expires_in - 10 ), "timeout" )
167
241
var payload : Dictionary = {refresh_token = refresh_token }
168
242
var auth_task : AuthTask = AuthTask .new (
169
243
AuthTask .Task .REFRESH ,
@@ -185,6 +259,7 @@ func _get_link_response(delta : float) -> void:
185
259
else :
186
260
_get_link_response (delta )
187
261
262
+
188
263
# Process a specific task
189
264
func _process_task (task : AuthTask ) -> void :
190
265
var httprequest : HTTPRequest = HTTPRequest .new ()
@@ -204,12 +279,18 @@ func _on_task_completed(task : AuthTask) -> void:
204
279
match task ._code :
205
280
AuthTask .Task .SIGNUP :
206
281
emit_signal ("signed_up" , client )
282
+ AuthTask .Task .SIGNUPPHONEPASSWORD :
283
+ emit_signal ("signed_up_phone" , client )
207
284
AuthTask .Task .SIGNIN :
208
285
emit_signal ("signed_in" , client )
286
+ AuthTask .Task .SIGNINOTP :
287
+ emit_signal ("signed_in_otp" , client )
209
288
AuthTask .Task .UPDATE :
210
289
emit_signal ("user_updated" , client )
211
290
AuthTask .Task .REFRESH :
212
291
emit_signal ("token_refreshed" , client )
292
+ AuthTask .Task .VERIFYOTP :
293
+ emit_signal ("otp_verified" )
213
294
refresh_token ()
214
295
elif task .data == null :
215
296
match task ._code :
@@ -220,7 +301,7 @@ func _on_task_completed(task : AuthTask) -> void:
220
301
AuthTask .Task .INVITE :
221
302
emit_signal ("user_invited" )
222
303
AuthTask .Task .LOGOUT :
223
- emit_signal ("logged_out " )
304
+ emit_signal ("signed_out " )
224
305
client = null
225
306
_auth = ""
226
307
_bearer = ["Authorization: Bearer %s " ]
0 commit comments