@capgo/capacitor-supabase 8.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,751 @@
1
+ package ee.forgr.plugin.capacitor_supabase
2
+
3
+ import android.content.Intent
4
+ import android.net.Uri
5
+ import com.getcapacitor.JSArray
6
+ import com.getcapacitor.JSObject
7
+ import com.getcapacitor.Plugin
8
+ import com.getcapacitor.PluginCall
9
+ import com.getcapacitor.PluginMethod
10
+ import com.getcapacitor.annotation.CapacitorPlugin
11
+ import io.github.jan.supabase.SupabaseClient
12
+ import io.github.jan.supabase.auth.Auth
13
+ import io.github.jan.supabase.auth.auth
14
+ import io.github.jan.supabase.auth.providers.builtin.Email
15
+ import io.github.jan.supabase.auth.providers.builtin.OTP
16
+ import io.github.jan.supabase.auth.status.SessionStatus
17
+ import io.github.jan.supabase.auth.user.UserSession
18
+ import io.github.jan.supabase.auth.user.UserInfo
19
+ import io.github.jan.supabase.createSupabaseClient
20
+ import io.github.jan.supabase.postgrest.Postgrest
21
+ import io.github.jan.supabase.postgrest.postgrest
22
+ import io.github.jan.supabase.postgrest.query.Columns
23
+ import io.github.jan.supabase.postgrest.query.Order
24
+ import kotlinx.coroutines.CoroutineScope
25
+ import kotlinx.coroutines.Dispatchers
26
+ import kotlinx.coroutines.Job
27
+ import kotlinx.coroutines.cancel
28
+ import kotlinx.coroutines.launch
29
+ import kotlinx.serialization.json.Json
30
+ import kotlinx.serialization.json.JsonElement
31
+ import kotlinx.serialization.json.JsonObject
32
+ import kotlinx.serialization.json.JsonPrimitive
33
+ import kotlinx.serialization.json.buildJsonObject
34
+ import org.json.JSONArray
35
+ import org.json.JSONObject
36
+
37
+ @CapacitorPlugin(name = "CapacitorSupabase")
38
+ class CapacitorSupabasePlugin : Plugin() {
39
+ private val pluginVersion = "7.0.0"
40
+ private var supabaseClient: SupabaseClient? = null
41
+ private val scope = CoroutineScope(Dispatchers.Main + Job())
42
+ private var authStateJob: Job? = null
43
+
44
+ override fun handleOnDestroy() {
45
+ authStateJob?.cancel()
46
+ scope.cancel()
47
+ super.handleOnDestroy()
48
+ }
49
+
50
+ @PluginMethod
51
+ fun initialize(call: PluginCall) {
52
+ val supabaseUrl = call.getString("supabaseUrl")
53
+ val supabaseKey = call.getString("supabaseKey")
54
+
55
+ if (supabaseUrl.isNullOrEmpty() || supabaseKey.isNullOrEmpty()) {
56
+ call.reject("Missing supabaseUrl or supabaseKey")
57
+ return
58
+ }
59
+
60
+ try {
61
+ supabaseClient = createSupabaseClient(
62
+ supabaseUrl = supabaseUrl,
63
+ supabaseKey = supabaseKey
64
+ ) {
65
+ install(Auth)
66
+ install(Postgrest)
67
+ }
68
+
69
+ setupAuthStateListener()
70
+ call.resolve()
71
+ } catch (e: Exception) {
72
+ call.reject("Failed to initialize Supabase client: ${e.message}")
73
+ }
74
+ }
75
+
76
+ private fun setupAuthStateListener() {
77
+ authStateJob?.cancel()
78
+ authStateJob = scope.launch {
79
+ supabaseClient?.auth?.sessionStatus?.collect { status ->
80
+ val eventName = when (status) {
81
+ is SessionStatus.Authenticated -> "SIGNED_IN"
82
+ is SessionStatus.NotAuthenticated -> "SIGNED_OUT"
83
+ is SessionStatus.RefreshFailure -> "TOKEN_REFRESHED"
84
+ SessionStatus.Initializing -> "INITIAL_SESSION"
85
+ else -> return@collect
86
+ }
87
+
88
+ val data = JSObject()
89
+ data.put("event", eventName)
90
+
91
+ when (status) {
92
+ is SessionStatus.Authenticated -> {
93
+ data.put("session", sessionToJSObject(status.session))
94
+ }
95
+ else -> {
96
+ data.put("session", JSONObject.NULL)
97
+ }
98
+ }
99
+
100
+ notifyListeners("authStateChange", data)
101
+ }
102
+ }
103
+ }
104
+
105
+ @PluginMethod
106
+ fun signInWithPassword(call: PluginCall) {
107
+ val client = supabaseClient
108
+ if (client == null) {
109
+ call.reject("Supabase client not initialized. Call initialize() first.")
110
+ return
111
+ }
112
+
113
+ val emailStr = call.getString("email")
114
+ val passwordStr = call.getString("password")
115
+
116
+ if (emailStr.isNullOrEmpty() || passwordStr.isNullOrEmpty()) {
117
+ call.reject("Missing email or password")
118
+ return
119
+ }
120
+
121
+ scope.launch {
122
+ try {
123
+ client.auth.signInWith(Email) {
124
+ email = emailStr
125
+ password = passwordStr
126
+ }
127
+
128
+ val session = client.auth.currentSessionOrNull()
129
+ val user = client.auth.currentUserOrNull()
130
+
131
+ val result = JSObject()
132
+ result.put("session", session?.let { sessionToJSObject(it) } ?: JSONObject.NULL)
133
+ result.put("user", user?.let { userToJSObject(it) } ?: JSONObject.NULL)
134
+ call.resolve(result)
135
+ } catch (e: Exception) {
136
+ call.reject("Sign in failed: ${e.message}")
137
+ }
138
+ }
139
+ }
140
+
141
+ @PluginMethod
142
+ fun signUp(call: PluginCall) {
143
+ val client = supabaseClient
144
+ if (client == null) {
145
+ call.reject("Supabase client not initialized. Call initialize() first.")
146
+ return
147
+ }
148
+
149
+ val emailStr = call.getString("email")
150
+ val passwordStr = call.getString("password")
151
+ val userData = call.getObject("data")
152
+
153
+ if (emailStr.isNullOrEmpty() || passwordStr.isNullOrEmpty()) {
154
+ call.reject("Missing email or password")
155
+ return
156
+ }
157
+
158
+ scope.launch {
159
+ try {
160
+ val jsonData = userData?.let { jsObjectToJsonObject(it) }
161
+
162
+ client.auth.signUpWith(Email) {
163
+ email = emailStr
164
+ password = passwordStr
165
+ if (jsonData != null) {
166
+ data = jsonData
167
+ }
168
+ }
169
+
170
+ val session = client.auth.currentSessionOrNull()
171
+ val user = client.auth.currentUserOrNull()
172
+
173
+ val result = JSObject()
174
+ result.put("session", session?.let { sessionToJSObject(it) } ?: JSONObject.NULL)
175
+ result.put("user", user?.let { userToJSObject(it) } ?: JSONObject.NULL)
176
+ call.resolve(result)
177
+ } catch (e: Exception) {
178
+ call.reject("Sign up failed: ${e.message}")
179
+ }
180
+ }
181
+ }
182
+
183
+ @PluginMethod
184
+ fun signInWithOAuth(call: PluginCall) {
185
+ val client = supabaseClient
186
+ if (client == null) {
187
+ call.reject("Supabase client not initialized. Call initialize() first.")
188
+ return
189
+ }
190
+
191
+ val providerString = call.getString("provider")
192
+ val redirectTo = call.getString("redirectTo")
193
+
194
+ if (providerString.isNullOrEmpty()) {
195
+ call.reject("Missing provider")
196
+ return
197
+ }
198
+
199
+ scope.launch {
200
+ try {
201
+ val provider = getOAuthProvider(providerString)
202
+ if (provider == null) {
203
+ call.reject("Invalid OAuth provider: $providerString")
204
+ return@launch
205
+ }
206
+
207
+ val url = client.auth.getOAuthUrl(provider)
208
+
209
+ val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
210
+ activity.startActivity(intent)
211
+ call.resolve()
212
+ } catch (e: Exception) {
213
+ call.reject("OAuth sign in failed: ${e.message}")
214
+ }
215
+ }
216
+ }
217
+
218
+ @PluginMethod
219
+ fun signInWithOtp(call: PluginCall) {
220
+ val client = supabaseClient
221
+ if (client == null) {
222
+ call.reject("Supabase client not initialized. Call initialize() first.")
223
+ return
224
+ }
225
+
226
+ val emailStr = call.getString("email")
227
+ val phoneStr = call.getString("phone")
228
+
229
+ if (emailStr.isNullOrEmpty() && phoneStr.isNullOrEmpty()) {
230
+ call.reject("Either email or phone is required")
231
+ return
232
+ }
233
+
234
+ scope.launch {
235
+ try {
236
+ if (!emailStr.isNullOrEmpty()) {
237
+ client.auth.signInWith(OTP) {
238
+ email = emailStr
239
+ }
240
+ } else if (!phoneStr.isNullOrEmpty()) {
241
+ client.auth.signInWith(OTP) {
242
+ phone = phoneStr
243
+ }
244
+ }
245
+ call.resolve()
246
+ } catch (e: Exception) {
247
+ call.reject("OTP sign in failed: ${e.message}")
248
+ }
249
+ }
250
+ }
251
+
252
+ @PluginMethod
253
+ fun verifyOtp(call: PluginCall) {
254
+ val client = supabaseClient
255
+ if (client == null) {
256
+ call.reject("Supabase client not initialized. Call initialize() first.")
257
+ return
258
+ }
259
+
260
+ val emailStr = call.getString("email")
261
+ val phoneStr = call.getString("phone")
262
+ val token = call.getString("token")
263
+ val type = call.getString("type")
264
+
265
+ if (token.isNullOrEmpty()) {
266
+ call.reject("Missing token")
267
+ return
268
+ }
269
+
270
+ if (emailStr.isNullOrEmpty() && phoneStr.isNullOrEmpty()) {
271
+ call.reject("Either email or phone is required")
272
+ return
273
+ }
274
+
275
+ scope.launch {
276
+ try {
277
+ if (!emailStr.isNullOrEmpty()) {
278
+ client.auth.verifyEmailOtp(
279
+ type = getEmailOtpType(type ?: "email"),
280
+ email = emailStr,
281
+ token = token
282
+ )
283
+ } else if (!phoneStr.isNullOrEmpty()) {
284
+ client.auth.verifyPhoneOtp(
285
+ type = getPhoneOtpType(type ?: "sms"),
286
+ phone = phoneStr,
287
+ token = token
288
+ )
289
+ }
290
+
291
+ val session = client.auth.currentSessionOrNull()
292
+ val user = client.auth.currentUserOrNull()
293
+
294
+ val result = JSObject()
295
+ result.put("session", session?.let { sessionToJSObject(it) } ?: JSONObject.NULL)
296
+ result.put("user", user?.let { userToJSObject(it) } ?: JSONObject.NULL)
297
+ call.resolve(result)
298
+ } catch (e: Exception) {
299
+ call.reject("OTP verification failed: ${e.message}")
300
+ }
301
+ }
302
+ }
303
+
304
+ @PluginMethod
305
+ fun signOut(call: PluginCall) {
306
+ val client = supabaseClient
307
+ if (client == null) {
308
+ call.reject("Supabase client not initialized. Call initialize() first.")
309
+ return
310
+ }
311
+
312
+ scope.launch {
313
+ try {
314
+ client.auth.signOut()
315
+ call.resolve()
316
+ } catch (e: Exception) {
317
+ call.reject("Sign out failed: ${e.message}")
318
+ }
319
+ }
320
+ }
321
+
322
+ @PluginMethod
323
+ fun getSession(call: PluginCall) {
324
+ val client = supabaseClient
325
+ if (client == null) {
326
+ call.reject("Supabase client not initialized. Call initialize() first.")
327
+ return
328
+ }
329
+
330
+ scope.launch {
331
+ try {
332
+ val session = client.auth.currentSessionOrNull()
333
+ val result = JSObject()
334
+ result.put("session", session?.let { sessionToJSObject(it) } ?: JSONObject.NULL)
335
+ call.resolve(result)
336
+ } catch (e: Exception) {
337
+ val result = JSObject()
338
+ result.put("session", JSONObject.NULL)
339
+ call.resolve(result)
340
+ }
341
+ }
342
+ }
343
+
344
+ @PluginMethod
345
+ fun refreshSession(call: PluginCall) {
346
+ val client = supabaseClient
347
+ if (client == null) {
348
+ call.reject("Supabase client not initialized. Call initialize() first.")
349
+ return
350
+ }
351
+
352
+ scope.launch {
353
+ try {
354
+ client.auth.refreshCurrentSession()
355
+ val session = client.auth.currentSessionOrNull()
356
+ val result = JSObject()
357
+ result.put("session", session?.let { sessionToJSObject(it) } ?: JSONObject.NULL)
358
+ call.resolve(result)
359
+ } catch (e: Exception) {
360
+ call.reject("Session refresh failed: ${e.message}")
361
+ }
362
+ }
363
+ }
364
+
365
+ @PluginMethod
366
+ fun getUser(call: PluginCall) {
367
+ val client = supabaseClient
368
+ if (client == null) {
369
+ call.reject("Supabase client not initialized. Call initialize() first.")
370
+ return
371
+ }
372
+
373
+ scope.launch {
374
+ try {
375
+ val user = client.auth.currentUserOrNull()
376
+ val result = JSObject()
377
+ result.put("user", user?.let { userToJSObject(it) } ?: JSONObject.NULL)
378
+ call.resolve(result)
379
+ } catch (e: Exception) {
380
+ val result = JSObject()
381
+ result.put("user", JSONObject.NULL)
382
+ call.resolve(result)
383
+ }
384
+ }
385
+ }
386
+
387
+ @PluginMethod
388
+ fun setSession(call: PluginCall) {
389
+ val client = supabaseClient
390
+ if (client == null) {
391
+ call.reject("Supabase client not initialized. Call initialize() first.")
392
+ return
393
+ }
394
+
395
+ val accessToken = call.getString("accessToken")
396
+ val refreshToken = call.getString("refreshToken")
397
+
398
+ if (accessToken.isNullOrEmpty() || refreshToken.isNullOrEmpty()) {
399
+ call.reject("Missing accessToken or refreshToken")
400
+ return
401
+ }
402
+
403
+ scope.launch {
404
+ try {
405
+ client.auth.importSession(
406
+ UserSession(
407
+ accessToken = accessToken,
408
+ refreshToken = refreshToken,
409
+ expiresIn = 3600,
410
+ tokenType = "bearer",
411
+ user = null
412
+ )
413
+ )
414
+ val session = client.auth.currentSessionOrNull()
415
+ val result = JSObject()
416
+ result.put("session", session?.let { sessionToJSObject(it) } ?: JSONObject.NULL)
417
+ call.resolve(result)
418
+ } catch (e: Exception) {
419
+ call.reject("Set session failed: ${e.message}")
420
+ }
421
+ }
422
+ }
423
+
424
+ // Database Operations
425
+
426
+ @PluginMethod
427
+ fun select(call: PluginCall) {
428
+ val client = supabaseClient
429
+ if (client == null) {
430
+ call.reject("Supabase client not initialized. Call initialize() first.")
431
+ return
432
+ }
433
+
434
+ val table = call.getString("table")
435
+ if (table.isNullOrEmpty()) {
436
+ call.reject("Missing table name")
437
+ return
438
+ }
439
+
440
+ val columns = call.getString("columns") ?: "*"
441
+ val filter = call.getObject("filter")
442
+ val limit = call.getInt("limit")
443
+ val offset = call.getInt("offset")
444
+ val orderBy = call.getString("orderBy")
445
+ val ascending = call.getBoolean("ascending", true) ?: true
446
+ val single = call.getBoolean("single", false) ?: false
447
+
448
+ scope.launch {
449
+ try {
450
+ val result = client.postgrest.from(table).select(Columns.raw(columns)) {
451
+ filter?.let { f ->
452
+ f.keys().forEach { key ->
453
+ val value = f.get(key)
454
+ filter { eq(key, value) }
455
+ }
456
+ }
457
+
458
+ orderBy?.let {
459
+ order(it, if (ascending) Order.ASCENDING else Order.DESCENDING)
460
+ }
461
+
462
+ limit?.let {
463
+ limit(it.toLong())
464
+ }
465
+
466
+ offset?.let { off ->
467
+ val lim = limit ?: 1000
468
+ range(off.toLong(), (off + lim - 1).toLong())
469
+ }
470
+
471
+ if (single) {
472
+ single()
473
+ }
474
+ }
475
+
476
+ val jsonString = result.data
477
+ val response = JSObject()
478
+ try {
479
+ if (single) {
480
+ response.put("data", JSObject(jsonString))
481
+ } else {
482
+ response.put("data", JSArray(jsonString))
483
+ }
484
+ } catch (e: Exception) {
485
+ response.put("data", jsonString)
486
+ }
487
+ response.put("error", JSONObject.NULL)
488
+ call.resolve(response)
489
+ } catch (e: Exception) {
490
+ val response = JSObject()
491
+ response.put("data", JSONObject.NULL)
492
+ response.put("error", e.message)
493
+ call.resolve(response)
494
+ }
495
+ }
496
+ }
497
+
498
+ @PluginMethod
499
+ fun insert(call: PluginCall) {
500
+ val client = supabaseClient
501
+ if (client == null) {
502
+ call.reject("Supabase client not initialized. Call initialize() first.")
503
+ return
504
+ }
505
+
506
+ val table = call.getString("table")
507
+ if (table.isNullOrEmpty()) {
508
+ call.reject("Missing table name")
509
+ return
510
+ }
511
+
512
+ val values = call.getObject("values")
513
+ if (values == null) {
514
+ call.reject("Missing values to insert")
515
+ return
516
+ }
517
+
518
+ scope.launch {
519
+ try {
520
+ val jsonObject = jsObjectToJsonObject(values)
521
+ val result = client.postgrest.from(table).insert(jsonObject) {
522
+ select()
523
+ single()
524
+ }
525
+
526
+ val jsonString = result.data
527
+ val response = JSObject()
528
+ try {
529
+ response.put("data", JSObject(jsonString))
530
+ } catch (e: Exception) {
531
+ response.put("data", jsonString)
532
+ }
533
+ response.put("error", JSONObject.NULL)
534
+ call.resolve(response)
535
+ } catch (e: Exception) {
536
+ val response = JSObject()
537
+ response.put("data", JSONObject.NULL)
538
+ response.put("error", e.message)
539
+ call.resolve(response)
540
+ }
541
+ }
542
+ }
543
+
544
+ @PluginMethod
545
+ fun update(call: PluginCall) {
546
+ val client = supabaseClient
547
+ if (client == null) {
548
+ call.reject("Supabase client not initialized. Call initialize() first.")
549
+ return
550
+ }
551
+
552
+ val table = call.getString("table")
553
+ if (table.isNullOrEmpty()) {
554
+ call.reject("Missing table name")
555
+ return
556
+ }
557
+
558
+ val values = call.getObject("values")
559
+ if (values == null) {
560
+ call.reject("Missing values to update")
561
+ return
562
+ }
563
+
564
+ val filter = call.getObject("filter")
565
+ if (filter == null || filter.length() == 0) {
566
+ call.reject("Missing filter for update operation")
567
+ return
568
+ }
569
+
570
+ scope.launch {
571
+ try {
572
+ val jsonObject = jsObjectToJsonObject(values)
573
+ val result = client.postgrest.from(table).update(jsonObject) {
574
+ filter.keys().forEach { key ->
575
+ val value = filter.get(key)
576
+ filter { eq(key, value) }
577
+ }
578
+ select()
579
+ }
580
+
581
+ val jsonString = result.data
582
+ val response = JSObject()
583
+ try {
584
+ response.put("data", JSArray(jsonString))
585
+ } catch (e: Exception) {
586
+ response.put("data", jsonString)
587
+ }
588
+ response.put("error", JSONObject.NULL)
589
+ call.resolve(response)
590
+ } catch (e: Exception) {
591
+ val response = JSObject()
592
+ response.put("data", JSONObject.NULL)
593
+ response.put("error", e.message)
594
+ call.resolve(response)
595
+ }
596
+ }
597
+ }
598
+
599
+ @PluginMethod
600
+ fun delete(call: PluginCall) {
601
+ val client = supabaseClient
602
+ if (client == null) {
603
+ call.reject("Supabase client not initialized. Call initialize() first.")
604
+ return
605
+ }
606
+
607
+ val table = call.getString("table")
608
+ if (table.isNullOrEmpty()) {
609
+ call.reject("Missing table name")
610
+ return
611
+ }
612
+
613
+ val filter = call.getObject("filter")
614
+ if (filter == null || filter.length() == 0) {
615
+ call.reject("Missing filter for delete operation")
616
+ return
617
+ }
618
+
619
+ scope.launch {
620
+ try {
621
+ val result = client.postgrest.from(table).delete {
622
+ filter.keys().forEach { key ->
623
+ val value = filter.get(key)
624
+ filter { eq(key, value) }
625
+ }
626
+ select()
627
+ }
628
+
629
+ val jsonString = result.data
630
+ val response = JSObject()
631
+ try {
632
+ response.put("data", JSArray(jsonString))
633
+ } catch (e: Exception) {
634
+ response.put("data", jsonString)
635
+ }
636
+ response.put("error", JSONObject.NULL)
637
+ call.resolve(response)
638
+ } catch (e: Exception) {
639
+ val response = JSObject()
640
+ response.put("data", JSONObject.NULL)
641
+ response.put("error", e.message)
642
+ call.resolve(response)
643
+ }
644
+ }
645
+ }
646
+
647
+ @PluginMethod
648
+ fun getPluginVersion(call: PluginCall) {
649
+ val result = JSObject()
650
+ result.put("version", pluginVersion)
651
+ call.resolve(result)
652
+ }
653
+
654
+ // Helper Methods
655
+
656
+ private fun sessionToJSObject(session: UserSession): JSObject {
657
+ val obj = JSObject()
658
+ obj.put("accessToken", session.accessToken)
659
+ obj.put("refreshToken", session.refreshToken)
660
+ obj.put("tokenType", session.tokenType)
661
+ obj.put("expiresIn", session.expiresIn)
662
+ obj.put("expiresAt", session.expiresAt?.epochSeconds ?: 0)
663
+ session.user?.let { obj.put("user", userToJSObject(it)) }
664
+ return obj
665
+ }
666
+
667
+ private fun userToJSObject(user: UserInfo): JSObject {
668
+ val obj = JSObject()
669
+ obj.put("id", user.id)
670
+ user.email?.let { obj.put("email", it) }
671
+ user.phone?.let { obj.put("phone", it) }
672
+ user.createdAt?.let { obj.put("createdAt", it.toString()) }
673
+ user.lastSignInAt?.let { obj.put("lastSignInAt", it.toString()) }
674
+ user.userMetadata?.let { metadata ->
675
+ try {
676
+ val jsonString = Json.encodeToString(JsonObject.serializer(), metadata)
677
+ obj.put("userMetadata", JSObject(jsonString))
678
+ } catch (e: Exception) {
679
+ // Ignore serialization errors
680
+ }
681
+ }
682
+ user.appMetadata?.let { metadata ->
683
+ try {
684
+ val jsonString = Json.encodeToString(JsonObject.serializer(), metadata)
685
+ obj.put("appMetadata", JSObject(jsonString))
686
+ } catch (e: Exception) {
687
+ // Ignore serialization errors
688
+ }
689
+ }
690
+ return obj
691
+ }
692
+
693
+ private fun jsObjectToJsonObject(jsObject: JSObject): JsonObject {
694
+ return buildJsonObject {
695
+ jsObject.keys().forEach { key ->
696
+ val value = jsObject.get(key)
697
+ when (value) {
698
+ is String -> put(key, JsonPrimitive(value))
699
+ is Number -> put(key, JsonPrimitive(value))
700
+ is Boolean -> put(key, JsonPrimitive(value))
701
+ is JSObject -> put(key, jsObjectToJsonObject(value))
702
+ null -> put(key, kotlinx.serialization.json.JsonNull)
703
+ else -> put(key, JsonPrimitive(value.toString()))
704
+ }
705
+ }
706
+ }
707
+ }
708
+
709
+ private fun getOAuthProvider(provider: String): io.github.jan.supabase.auth.providers.OAuthProvider? {
710
+ return when (provider.lowercase()) {
711
+ "apple" -> io.github.jan.supabase.auth.providers.Apple
712
+ "azure" -> io.github.jan.supabase.auth.providers.Azure
713
+ "bitbucket" -> io.github.jan.supabase.auth.providers.Bitbucket
714
+ "discord" -> io.github.jan.supabase.auth.providers.Discord
715
+ "facebook" -> io.github.jan.supabase.auth.providers.Facebook
716
+ "figma" -> io.github.jan.supabase.auth.providers.Figma
717
+ "github" -> io.github.jan.supabase.auth.providers.Github
718
+ "gitlab" -> io.github.jan.supabase.auth.providers.Gitlab
719
+ "google" -> io.github.jan.supabase.auth.providers.Google
720
+ "kakao" -> io.github.jan.supabase.auth.providers.Kakao
721
+ "keycloak" -> io.github.jan.supabase.auth.providers.Keycloak
722
+ "linkedin" -> io.github.jan.supabase.auth.providers.LinkedIn
723
+ "linkedin_oidc" -> io.github.jan.supabase.auth.providers.LinkedInOIDC
724
+ "notion" -> io.github.jan.supabase.auth.providers.Notion
725
+ "slack" -> io.github.jan.supabase.auth.providers.Slack
726
+ "slack_oidc" -> io.github.jan.supabase.auth.providers.SlackOIDC
727
+ "spotify" -> io.github.jan.supabase.auth.providers.Spotify
728
+ "twitch" -> io.github.jan.supabase.auth.providers.Twitch
729
+ "twitter" -> io.github.jan.supabase.auth.providers.Twitter
730
+ "zoom" -> io.github.jan.supabase.auth.providers.Zoom
731
+ else -> null
732
+ }
733
+ }
734
+
735
+ private fun getEmailOtpType(type: String): io.github.jan.supabase.auth.OtpType.Email {
736
+ return when (type.lowercase()) {
737
+ "signup" -> io.github.jan.supabase.auth.OtpType.Email.SIGNUP
738
+ "magiclink" -> io.github.jan.supabase.auth.OtpType.Email.MAGIC_LINK
739
+ "recovery" -> io.github.jan.supabase.auth.OtpType.Email.RECOVERY
740
+ "email" -> io.github.jan.supabase.auth.OtpType.Email.EMAIL
741
+ else -> io.github.jan.supabase.auth.OtpType.Email.EMAIL
742
+ }
743
+ }
744
+
745
+ private fun getPhoneOtpType(type: String): io.github.jan.supabase.auth.OtpType.Phone {
746
+ return when (type.lowercase()) {
747
+ "sms" -> io.github.jan.supabase.auth.OtpType.Phone.SMS
748
+ else -> io.github.jan.supabase.auth.OtpType.Phone.SMS
749
+ }
750
+ }
751
+ }