-
Notifications
You must be signed in to change notification settings - Fork 168
/
Copy pathcredentials.kt
123 lines (96 loc) · 5.45 KB
/
credentials.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/*
* Copyright (c) 2020 GitLive Ltd. Use of this source code is governed by the Apache 2.0 license.
*/
package dev.gitlive.firebase.auth
import android.app.Activity
import com.google.firebase.FirebaseException
import com.google.firebase.auth.OAuthProvider
import com.google.firebase.auth.PhoneAuthProvider
import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.tasks.await
import java.util.concurrent.TimeUnit
actual open class AuthCredential(open val android: com.google.firebase.auth.AuthCredential) {
actual val providerId: String
get() = android.provider
}
actual class PhoneAuthCredential(override val android: com.google.firebase.auth.PhoneAuthCredential) : AuthCredential(android)
actual class OAuthCredential(override val android: com.google.firebase.auth.OAuthCredential) : AuthCredential(android)
actual object EmailAuthProvider {
actual fun credential(
email: String,
password: String
): AuthCredential = AuthCredential(com.google.firebase.auth.EmailAuthProvider.getCredential(email, password))
}
actual object FacebookAuthProvider {
actual fun credential(accessToken: String): AuthCredential = AuthCredential(com.google.firebase.auth.FacebookAuthProvider.getCredential(accessToken))
}
actual object GithubAuthProvider {
actual fun credential(token: String): AuthCredential = AuthCredential(com.google.firebase.auth.GithubAuthProvider.getCredential(token))
}
actual object GoogleAuthProvider {
actual fun credential(idToken: String, accessToken: String): AuthCredential = AuthCredential(com.google.firebase.auth.GoogleAuthProvider.getCredential(idToken, accessToken))
}
actual class OAuthProvider(val android: com.google.firebase.auth.OAuthProvider.Builder, private val auth: FirebaseAuth) {
actual constructor(provider: String, auth: FirebaseAuth) : this(com.google.firebase.auth.OAuthProvider.newBuilder(provider, auth.android), auth)
actual companion object {
actual fun credential(providerId: String, accessToken: String?, idToken: String?, rawNonce: String?): OAuthCredential {
val builder = OAuthProvider.newCredentialBuilder(providerId)
accessToken?.let { builder.accessToken = it }
idToken?.let { builder.idToken = it }
rawNonce?.let { builder.setIdTokenWithRawNonce(idToken!!, it) }
return OAuthCredential(builder.build() as com.google.firebase.auth.OAuthCredential)
}
}
private var customParameters: Map<String, String> = emptyMap()
actual fun addScope(vararg scope: String) {
android.scopes = android.scopes + scope.asList()
}
actual fun setCustomParameters(parameters: Map<String, String>) {
customParameters = parameters
}
actual suspend fun signIn(signInProvider: SignInProvider): AuthResult = AuthResult(auth.android.startActivityForSignInWithProvider(signInProvider, android.apply { addCustomParameters(customParameters) }.build()).await())
}
actual typealias SignInProvider = Activity
actual class PhoneAuthProvider(val android: com.google.firebase.auth.PhoneAuthProvider) {
actual constructor(auth: FirebaseAuth) : this(com.google.firebase.auth.PhoneAuthProvider.getInstance(auth.android))
actual fun credential(verificationId: String, smsCode: String): PhoneAuthCredential = PhoneAuthCredential(com.google.firebase.auth.PhoneAuthProvider.getCredential(verificationId, smsCode))
actual suspend fun verifyPhoneNumber(phoneNumber: String, verificationProvider: PhoneVerificationProvider): AuthCredential = coroutineScope {
val response = CompletableDeferred<Result<AuthCredential>>()
val callback = object :
PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
override fun onCodeSent(verificationId: String, forceResending: PhoneAuthProvider.ForceResendingToken) {
verificationProvider.codeSent { android.verifyPhoneNumber(phoneNumber, verificationProvider.timeout, verificationProvider.unit, verificationProvider.activity, this, forceResending) }
}
override fun onCodeAutoRetrievalTimeOut(verificationId: String) {
launch {
val code = verificationProvider.getVerificationCode()
try {
response.complete(Result.success(credential(verificationId, code)))
} catch (e: Exception) {
response.complete(Result.failure(e))
}
}
}
override fun onVerificationCompleted(credential: com.google.firebase.auth.PhoneAuthCredential) {
response.complete(Result.success(AuthCredential(credential)))
}
override fun onVerificationFailed(error: FirebaseException) {
response.complete(Result.failure(error))
}
}
android.verifyPhoneNumber(phoneNumber, verificationProvider.timeout, verificationProvider.unit, verificationProvider.activity, callback)
response.await().getOrThrow()
}
}
actual interface PhoneVerificationProvider {
val activity: Activity
val timeout: Long
val unit: TimeUnit
fun codeSent(triggerResend: (Unit) -> Unit)
suspend fun getVerificationCode(): String
}
actual object TwitterAuthProvider {
actual fun credential(token: String, secret: String): AuthCredential = AuthCredential(com.google.firebase.auth.TwitterAuthProvider.getCredential(token, secret))
}