-
Notifications
You must be signed in to change notification settings - Fork 43
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Added support for passwordless authentication (#503)
- Loading branch information
Showing
27 changed files
with
759 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
59 changes: 59 additions & 0 deletions
59
...kotlin/com/auth0/auth0_flutter/request_handlers/api/EmailPasswordlessApiRequestHandler.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
package com.auth0.auth0_flutter.request_handlers.api | ||
|
||
import com.auth0.android.authentication.AuthenticationAPIClient | ||
import com.auth0.android.authentication.AuthenticationException | ||
import com.auth0.android.authentication.PasswordlessType | ||
import com.auth0.android.callback.Callback | ||
import com.auth0.auth0_flutter.request_handlers.MethodCallRequest | ||
import com.auth0.auth0_flutter.toMap | ||
import com.auth0.auth0_flutter.utils.assertHasProperties | ||
import io.flutter.plugin.common.MethodChannel | ||
import java.util.HashMap | ||
|
||
private const val PASSWORDLESS_EMAIL_LOGIN_METHOD = "auth#passwordlessWithEmail" | ||
|
||
class EmailPasswordlessApiRequestHandler : ApiRequestHandler { | ||
override val method: String = PASSWORDLESS_EMAIL_LOGIN_METHOD | ||
|
||
override fun handle( | ||
api: AuthenticationAPIClient, | ||
request: MethodCallRequest, | ||
result: MethodChannel.Result | ||
) { | ||
val args = request.data | ||
assertHasProperties(listOf("email", "passwordlessType"), args) | ||
val passwordlessType = getPasswordlessType(args["passwordlessType"] as String) | ||
|
||
val builder = api.passwordlessWithEmail( | ||
args["email"] as String, | ||
passwordlessType | ||
) | ||
|
||
if (args["parameters"] is HashMap<*, *>) { | ||
builder.addParameters(args["parameters"] as Map<String, String>) | ||
} | ||
|
||
builder.start(object : Callback<Void?, AuthenticationException> { | ||
override fun onFailure(error: AuthenticationException) { | ||
result.error( | ||
error.getCode(), | ||
error.getDescription(), | ||
error.toMap() | ||
) | ||
} | ||
|
||
override fun onSuccess(void: Void?) { | ||
result.success(null) | ||
} | ||
}) | ||
} | ||
|
||
private fun getPasswordlessType(passwordlessType: String): PasswordlessType { | ||
return when (passwordlessType) { | ||
"code" -> PasswordlessType.CODE | ||
"link" -> PasswordlessType.WEB_LINK | ||
"link_android" -> PasswordlessType.ANDROID_LINK | ||
else -> PasswordlessType.CODE | ||
} | ||
} | ||
} |
67 changes: 67 additions & 0 deletions
67
...otlin/com/auth0/auth0_flutter/request_handlers/api/LoginWithEmailCodeApiRequestHandler.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
package com.auth0.auth0_flutter.request_handlers.api | ||
|
||
import com.auth0.android.authentication.AuthenticationAPIClient | ||
import com.auth0.android.authentication.AuthenticationException | ||
import com.auth0.android.callback.Callback | ||
import com.auth0.android.result.Credentials | ||
import com.auth0.auth0_flutter.request_handlers.MethodCallRequest | ||
import com.auth0.auth0_flutter.toMap | ||
import com.auth0.auth0_flutter.utils.assertHasProperties | ||
import io.flutter.plugin.common.MethodChannel | ||
import java.util.ArrayList | ||
import java.util.HashMap | ||
|
||
private const val EMAIL_LOGIN_METHOD = "auth#loginWithEmail" | ||
|
||
class LoginWithEmailCodeApiRequestHandler : ApiRequestHandler { | ||
override val method: String = EMAIL_LOGIN_METHOD | ||
|
||
override fun handle( | ||
api: AuthenticationAPIClient, | ||
request: MethodCallRequest, | ||
result: MethodChannel.Result | ||
) { | ||
val args = request.data | ||
assertHasProperties(listOf("email", "verificationCode"), args) | ||
|
||
val builder = api.loginWithEmail( | ||
args["email"] as String, | ||
args["verificationCode"] as String | ||
).apply { | ||
val scopes = (args["scopes"] ?: arrayListOf<String>()) as ArrayList<*> | ||
setScope(scopes.joinToString(separator = " ")) | ||
if (args["audience"] is String) { | ||
setAudience(args["audience"] as String) | ||
} | ||
if (args["parameters"] is HashMap<*, *>) { | ||
addParameters(args["parameters"] as Map<String, String>) | ||
} | ||
} | ||
|
||
builder.start(object : Callback<Credentials, AuthenticationException> { | ||
override fun onFailure(error: AuthenticationException) { | ||
result.error( | ||
error.getCode(), | ||
error.getDescription(), | ||
error.toMap() | ||
) | ||
} | ||
|
||
override fun onSuccess(credentials: Credentials) { | ||
val scope = credentials.scope?.split(" ") ?: listOf() | ||
val formattedDate = credentials.expiresAt.toInstant().toString() | ||
result.success( | ||
mapOf( | ||
"accessToken" to credentials.accessToken, | ||
"idToken" to credentials.idToken, | ||
"refreshToken" to credentials.refreshToken, | ||
"userProfile" to credentials.user.toMap(), | ||
"expiresAt" to formattedDate, | ||
"scopes" to scope, | ||
"tokenType" to credentials.type | ||
) | ||
) | ||
} | ||
}) | ||
} | ||
} |
63 changes: 63 additions & 0 deletions
63
.../kotlin/com/auth0/auth0_flutter/request_handlers/api/LoginWithSMSCodeApiRequestHandler.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
package com.auth0.auth0_flutter.request_handlers.api | ||
|
||
import com.auth0.android.authentication.AuthenticationAPIClient | ||
import com.auth0.android.authentication.AuthenticationException | ||
import com.auth0.android.callback.Callback | ||
import com.auth0.android.result.Credentials | ||
import com.auth0.auth0_flutter.request_handlers.MethodCallRequest | ||
import com.auth0.auth0_flutter.toMap | ||
import com.auth0.auth0_flutter.utils.assertHasProperties | ||
import io.flutter.plugin.common.MethodChannel | ||
import java.util.ArrayList | ||
import java.util.HashMap | ||
|
||
private const val SMS_LOGIN_METHOD = "auth#loginWithPhoneNumber" | ||
|
||
class LoginWithSMSCodeApiRequestHandler : ApiRequestHandler { | ||
override val method: String = SMS_LOGIN_METHOD | ||
|
||
override fun handle( | ||
api: AuthenticationAPIClient, request: MethodCallRequest, result: MethodChannel.Result | ||
) { | ||
val args = request.data | ||
assertHasProperties(listOf("phoneNumber", "verificationCode"), args) | ||
|
||
val builder = api.loginWithPhoneNumber( | ||
args["email"] as String, | ||
args["verificationCode"] as String | ||
).apply { | ||
val scopes = (args["scopes"] ?: arrayListOf<String>()) as ArrayList<*> | ||
setScope(scopes.joinToString(separator = " ")) | ||
if (args["audience"] is String) { | ||
setAudience(args["audience"] as String) | ||
} | ||
if (args["parameters"] is HashMap<*, *>) { | ||
addParameters(args["parameters"] as Map<String, String>) | ||
} | ||
} | ||
|
||
builder.start(object : Callback<Credentials, AuthenticationException> { | ||
override fun onFailure(error: AuthenticationException) { | ||
result.error( | ||
error.getCode(), error.getDescription(), error.toMap() | ||
) | ||
} | ||
|
||
override fun onSuccess(credentials: Credentials) { | ||
val scope = credentials.scope?.split(" ") ?: listOf() | ||
val formattedDate = credentials.expiresAt.toInstant().toString() | ||
result.success( | ||
mapOf( | ||
"accessToken" to credentials.accessToken, | ||
"idToken" to credentials.idToken, | ||
"refreshToken" to credentials.refreshToken, | ||
"userProfile" to credentials.user.toMap(), | ||
"expiresAt" to formattedDate, | ||
"scopes" to scope, | ||
"tokenType" to credentials.type | ||
) | ||
) | ||
} | ||
}) | ||
} | ||
} |
59 changes: 59 additions & 0 deletions
59
.../com/auth0/auth0_flutter/request_handlers/api/PhoneNumberPasswordlessApiRequestHandler.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
package com.auth0.auth0_flutter.request_handlers.api | ||
|
||
import com.auth0.android.authentication.AuthenticationAPIClient | ||
import com.auth0.android.authentication.AuthenticationException | ||
import com.auth0.android.authentication.PasswordlessType | ||
import com.auth0.android.callback.Callback | ||
import com.auth0.auth0_flutter.request_handlers.MethodCallRequest | ||
import com.auth0.auth0_flutter.toMap | ||
import com.auth0.auth0_flutter.utils.assertHasProperties | ||
import io.flutter.plugin.common.MethodChannel | ||
import java.util.HashMap | ||
|
||
private const val PASSWORDLESS_PHONE_NUMBER_LOGIN_METHOD = "auth#passwordlessWithPhoneNumber" | ||
|
||
class PhoneNumberPasswordlessApiRequestHandler : ApiRequestHandler { | ||
override val method: String = PASSWORDLESS_PHONE_NUMBER_LOGIN_METHOD | ||
|
||
override fun handle( | ||
api: AuthenticationAPIClient, | ||
request: MethodCallRequest, | ||
result: MethodChannel.Result | ||
) { | ||
val args = request.data | ||
assertHasProperties(listOf("phoneNumber", "passwordlessType"), args) | ||
val passwordlessType = getPasswordlessType(args["passwordlessType"] as String) | ||
|
||
val builder = api.passwordlessWithSMS( | ||
args["phoneNumber"] as String, | ||
passwordlessType | ||
) | ||
|
||
if (args["parameters"] is HashMap<*, *>) { | ||
builder.addParameters(args["parameters"] as Map<String, String>) | ||
} | ||
|
||
builder.start(object : Callback<Void?, AuthenticationException> { | ||
override fun onFailure(exception: AuthenticationException) { | ||
result.error( | ||
exception.getCode(), | ||
exception.getDescription(), | ||
exception.toMap() | ||
) | ||
} | ||
|
||
override fun onSuccess(void: Void?) { | ||
result.success(void) | ||
} | ||
}) | ||
} | ||
|
||
private fun getPasswordlessType(passwordlessType: String): PasswordlessType { | ||
return when (passwordlessType) { | ||
"code" -> PasswordlessType.CODE | ||
"link" -> PasswordlessType.WEB_LINK | ||
"link_android" -> PasswordlessType.ANDROID_LINK | ||
else -> PasswordlessType.CODE | ||
} | ||
} | ||
} |
47 changes: 47 additions & 0 deletions
47
auth0_flutter/darwin/Classes/AuthAPI/AuthAPIEmailPasswordlessLoginMethodHandler.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
import Auth0 | ||
|
||
#if os(iOS) | ||
import Flutter | ||
#else | ||
import FlutterMacOS | ||
#endif | ||
|
||
struct AuthAPIPasswordlessEmailMethodHandler: MethodHandler { | ||
enum Argument: String { | ||
case email | ||
case passwordlessType | ||
case parameters | ||
} | ||
|
||
let client: Authentication | ||
|
||
func handle(with arguments: [String: Any], callback: @escaping FlutterResult) { | ||
guard let email = arguments[Argument.email] as? String else { | ||
return callback(FlutterError(from: .requiredArgumentMissing(Argument.email.rawValue))) | ||
} | ||
|
||
guard let passwordlessTypeString = arguments[Argument.passwordlessType] as? String, | ||
let passwordlessType = PasswordlessType(rawValue: passwordlessTypeString) else { | ||
return callback(FlutterError(from: .requiredArgumentMissing(Argument.passwordlessType.rawValue))) | ||
} | ||
|
||
guard let parameters = arguments[Argument.parameters] as? [String: Any] else { | ||
return callback(FlutterError(from: .requiredArgumentMissing(Argument.parameters.rawValue))) | ||
} | ||
|
||
client | ||
.startPasswordless(email: email, | ||
type: passwordlessType, | ||
connection: "email" | ||
) | ||
.parameters(["authParams":parameters]) | ||
.start { | ||
switch $0 { | ||
case let .success: | ||
callback(nil) | ||
case let .failure(error): | ||
callback(FlutterError(from: error)) | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.