2023-08-07 11:55:59 -07:00
// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import UIKit
/// Firebase Auth supported identity providers and other methods of authentication
2023-08-24 15:42:51 -07:00
enum AuthMenu : String {
case settings = "Settings"
2023-08-07 11:55:59 -07:00
case google = "google.com"
case apple = "apple.com"
case twitter = "twitter.com"
case microsoft = "microsoft.com"
case gitHub = "github.com"
case yahoo = "yahoo.com"
2024-05-09 14:30:23 -07:00
case linkedIn = "linkedin.com"
2023-08-07 11:55:59 -07:00
case facebook = "facebook.com"
2024-05-06 13:44:47 -07:00
case gameCenter = "gc.apple.com"
2023-08-07 11:55:59 -07:00
case emailPassword = "password"
case passwordless = "emailLink"
case phoneNumber = "phone"
case anonymous
case custom
2023-10-26 14:58:09 -07:00
case initRecaptcha
2023-10-27 12:09:29 -07:00
case customAuthDomain
2024-05-06 14:01:22 -07:00
case getToken
case getTokenForceRefresh
case addAuthStateChangeListener
case removeLastAuthStateChangeListener
case addIdTokenChangeListener
case removeLastIdTokenChangeListener
case verifyClient
case deleteApp
2024-05-06 15:53:49 -07:00
case actionType
case continueURL
case requestVerifyEmail
case requestPasswordReset
case resetPassword
case checkActionCode
case applyActionCode
case verifyPasswordResetCode
2024-05-06 16:05:12 -07:00
case phoneEnroll
case totpEnroll
case multifactorUnenroll
2023-08-07 11:55:59 -07:00
2024-05-06 14:01:22 -07:00
// More intuitively named getter for `rawValue`.
2023-08-07 11:55:59 -07:00
var id : String { rawValue }
2024-05-06 14:01:22 -07:00
// The UI friendly name of the `AuthMenu`. Used for display.
2023-08-07 11:55:59 -07:00
var name : String {
switch self {
2023-08-24 15:42:51 -07:00
case . settings :
return "Settings"
2023-08-07 11:55:59 -07:00
case . google :
return "Google"
case . apple :
return "Apple"
case . twitter :
return "Twitter"
case . microsoft :
return "Microsoft"
case . gitHub :
return "GitHub"
case . yahoo :
return "Yahoo"
2024-05-09 14:30:23 -07:00
case . linkedIn :
return "LinkedIn"
2023-08-07 11:55:59 -07:00
case . facebook :
return "Facebook"
2024-05-06 13:44:47 -07:00
case . gameCenter :
return "Game Center"
2023-08-07 11:55:59 -07:00
case . emailPassword :
return "Email & Password Login"
case . passwordless :
return "Email Link/Passwordless"
case . phoneNumber :
return "Phone Number"
case . anonymous :
return "Anonymous Authentication"
case . custom :
return "Custom Auth System"
2024-05-06 16:05:12 -07:00
// Recpatcha
2023-10-26 14:58:09 -07:00
case . initRecaptcha :
return "Initialize reCAPTCHA Enterprise"
2024-05-06 16:05:12 -07:00
// Custom Auth Domain
2023-10-27 12:09:29 -07:00
case . customAuthDomain :
return "Set Custom Auth Domain"
2024-05-06 16:05:12 -07:00
// App Section
2024-05-06 14:01:22 -07:00
case . getToken :
return "Get Token"
case . getTokenForceRefresh :
return "Get Token Force Refresh"
case . addAuthStateChangeListener :
return "Add Auth State Change Listener"
case . removeLastAuthStateChangeListener :
return "Remove Last Auth State Change Listener"
case . addIdTokenChangeListener :
return "Add ID Token Change Listener"
case . removeLastIdTokenChangeListener :
return "Remove Last ID Token Change Listener"
case . verifyClient :
return "Verify Client"
case . deleteApp :
return "Delete App"
2024-05-06 15:53:49 -07:00
// OOB
case . actionType :
return "Action Type"
case . continueURL :
return "Continue URL"
case . requestVerifyEmail :
return "Request Verify Email"
case . requestPasswordReset :
return "Request Password Reset"
case . resetPassword :
return "Reset Password"
case . checkActionCode :
return "Check Action Code"
case . applyActionCode :
return "Apply Action Code"
case . verifyPasswordResetCode :
return "Verify Password Reset Code"
2024-05-06 16:05:12 -07:00
// Multi factor
case . phoneEnroll :
return "Phone Enroll"
case . totpEnroll :
return "TOTP Enroll"
case . multifactorUnenroll :
return "Multifactor unenroll"
2023-08-07 11:55:59 -07:00
}
}
2024-05-06 14:01:22 -07:00
// Failable initializer to create an `AuthMenu` from its corresponding `name` value.
// - Parameter rawValue: String value representing `AuthMenu`'s name or type.
2023-08-07 11:55:59 -07:00
init ?( rawValue : String ) {
switch rawValue {
2023-08-24 15:42:51 -07:00
case "Settings" :
self = . settings
2023-08-07 11:55:59 -07:00
case "Google" :
self = . google
case "Apple" :
self = . apple
case "Twitter" :
self = . twitter
case "Microsoft" :
self = . microsoft
case "GitHub" :
self = . gitHub
case "Yahoo" :
self = . yahoo
2024-05-09 14:30:23 -07:00
case "LinkedIn" :
self = . linkedIn
2023-08-07 11:55:59 -07:00
case "Facebook" :
self = . facebook
2024-05-06 13:44:47 -07:00
case "Game Center" :
self = . gameCenter
2023-08-07 11:55:59 -07:00
case "Email & Password Login" :
self = . emailPassword
case "Email Link/Passwordless" :
self = . passwordless
case "Phone Number" :
self = . phoneNumber
case "Anonymous Authentication" :
self = . anonymous
case "Custom Auth System" :
self = . custom
2023-10-26 14:58:09 -07:00
case "Initialize reCAPTCHA Enterprise" :
self = . initRecaptcha
2023-10-27 12:09:29 -07:00
case "Set Custom Auth Domain" :
self = . customAuthDomain
2024-05-06 14:01:22 -07:00
case "Get Token" :
self = . getToken
case "Get Token Force Refresh" :
self = . getTokenForceRefresh
case "Add Auth State Change Listener" :
self = . addAuthStateChangeListener
case "Remove Last Auth State Change Listener" :
self = . removeLastAuthStateChangeListener
case "Add ID Token Change Listener" :
self = . addIdTokenChangeListener
case "Remove Last ID Token Change Listener" :
self = . removeLastIdTokenChangeListener
case "Verify Client" :
self = . verifyClient
case "Delete App" :
self = . deleteApp
2024-05-06 15:53:49 -07:00
case "Action Type" :
self = . actionType
case "Continue URL" :
self = . continueURL
case "Request Verify Email" :
self = . requestVerifyEmail
case "Request Password Reset" :
self = . requestPasswordReset
case "Reset Password" :
self = . resetPassword
case "Check Action Code" :
self = . checkActionCode
case "Apply Action Code" :
self = . applyActionCode
case "Verify Password Reset Code" :
self = . verifyPasswordResetCode
2024-05-06 16:05:12 -07:00
case "Phone Enroll" :
self = . phoneEnroll
case "TOTP Enroll" :
self = . totpEnroll
case "Multifactor unenroll" :
self = . multifactorUnenroll
2024-05-06 15:53:49 -07:00
default :
return nil
}
}
}
enum ActionCodeRequestType : String {
case email
case ` continue `
case inApp
var name : String {
switch self {
case . email :
return "Email Only"
case . inApp :
return "In-App + Continue URL"
case . continue :
return "Continue URL"
}
}
init ?( rawValue : String ) {
switch rawValue {
case "Email Only" :
self = . email
case "In-App + Continue URL" :
self = . inApp
case "Continue URL" :
self = . continue
2024-05-06 14:01:22 -07:00
default :
return nil
2023-08-07 11:55:59 -07:00
}
}
}
// MARK: DataSourceProvidable
2024-05-06 15:53:49 -07:00
class AuthMenuData : DataSourceProvidable {
2023-08-24 15:42:51 -07:00
private static var providers : [ AuthMenu ] {
2024-05-09 14:30:23 -07:00
[. google , . apple , . twitter , . microsoft , . gitHub , . yahoo , . linkedIn , . facebook , . gameCenter ]
2023-08-07 11:55:59 -07:00
}
2023-08-24 15:42:51 -07:00
static var settingsSection : Section {
let header = "Auth Settings"
2024-05-06 15:53:49 -07:00
let item = Item ( title : AuthMenu . settings . name , hasNestedContent : true )
2023-08-24 15:42:51 -07:00
return Section ( headerDescription : header , items : [ item ])
}
2023-08-07 11:55:59 -07:00
static var providerSection : Section {
let providers = self . providers . map { Item ( title : $0 . name ) }
let header = "Identity Providers"
let footer = "Choose a login flow from one of the identity providers above."
return Section ( headerDescription : header , footerDescription : footer , items : providers )
}
static var emailPasswordSection : Section {
let image = UIImage ( named : "firebaseIcon" )
2023-08-21 16:47:22 -07:00
let header = "Email and Password Login"
2024-05-06 15:53:49 -07:00
let item = Item ( title : AuthMenu . emailPassword . name , hasNestedContent : true , image : image )
2023-08-21 16:47:22 -07:00
return Section ( headerDescription : header , items : [ item ])
2023-08-07 11:55:59 -07:00
}
static var otherSection : Section {
let lockSymbol = UIImage . systemImage ( "lock.slash.fill" , tintColor : . systemOrange )
let phoneSymbol = UIImage . systemImage ( "phone.fill" , tintColor : . systemOrange )
let anonSymbol = UIImage . systemImage ( "questionmark.circle.fill" , tintColor : . systemOrange )
let shieldSymbol = UIImage . systemImage ( "lock.shield.fill" , tintColor : . systemOrange )
let otherOptions = [
2024-05-06 15:53:49 -07:00
Item ( title : AuthMenu . passwordless . name , image : lockSymbol ),
Item ( title : AuthMenu . phoneNumber . name , image : phoneSymbol ),
Item ( title : AuthMenu . anonymous . name , image : anonSymbol ),
Item ( title : AuthMenu . custom . name , image : shieldSymbol ),
2023-08-07 11:55:59 -07:00
]
2023-08-21 16:47:22 -07:00
let header = "Other Authentication Methods"
return Section ( headerDescription : header , items : otherOptions )
2023-08-07 11:55:59 -07:00
}
2023-10-26 14:58:09 -07:00
static var recaptchaSection : Section {
let image = UIImage ( named : "firebaseIcon" )
let header = "Initialize reCAPTCHA Enterprise"
2024-05-06 15:53:49 -07:00
let item = Item ( title : AuthMenu . initRecaptcha . name , hasNestedContent : false , image : image )
2023-10-26 14:58:09 -07:00
return Section ( headerDescription : header , items : [ item ])
}
2023-10-27 12:09:29 -07:00
static var customAuthDomainSection : Section {
let image = UIImage ( named : "firebaseIcon" )
let header = "Custom Auth Domain"
2024-05-06 15:53:49 -07:00
let item = Item ( title : AuthMenu . customAuthDomain . name , hasNestedContent : false , image : image )
2023-10-27 12:09:29 -07:00
return Section ( headerDescription : header , items : [ item ])
}
2024-05-06 14:01:22 -07:00
static var appSection : Section {
let header = "APP"
let items : [ Item ] = [
2024-05-06 15:53:49 -07:00
Item ( title : AuthMenu . getToken . name ),
Item ( title : AuthMenu . getTokenForceRefresh . name ),
Item ( title : AuthMenu . addAuthStateChangeListener . name ),
Item ( title : AuthMenu . removeLastAuthStateChangeListener . name ),
Item ( title : AuthMenu . addIdTokenChangeListener . name ),
Item ( title : AuthMenu . removeLastIdTokenChangeListener . name ),
Item ( title : AuthMenu . verifyClient . name ),
Item ( title : AuthMenu . deleteApp . name ),
2024-05-06 14:01:22 -07:00
]
return Section ( headerDescription : header , items : items )
}
2024-05-06 15:53:49 -07:00
static var oobSection : Section {
let header = "OOB"
let items : [ Item ] = [
Item ( title : AuthMenu . actionType . name , detailTitle : ActionCodeRequestType . inApp . name ),
Item ( title : AuthMenu . continueURL . name , detailTitle : "--" , isEditable : true ),
Item ( title : AuthMenu . requestVerifyEmail . name ),
Item ( title : AuthMenu . requestPasswordReset . name ),
Item ( title : AuthMenu . resetPassword . name ),
Item ( title : AuthMenu . checkActionCode . name ),
Item ( title : AuthMenu . applyActionCode . name ),
Item ( title : AuthMenu . verifyPasswordResetCode . name ),
]
return Section ( headerDescription : header , items : items )
2023-08-07 11:55:59 -07:00
}
2024-05-06 16:05:12 -07:00
static var multifactorSection : Section {
let header = "Multi Factor"
let items : [ Item ] = [
Item ( title : AuthMenu . phoneEnroll . name ),
Item ( title : AuthMenu . totpEnroll . name ),
Item ( title : AuthMenu . multifactorUnenroll . name ),
]
return Section ( headerDescription : header , items : items )
}
2024-06-14 07:01:28 -07:00
static let sections : [ Section ] =
2024-05-06 15:53:49 -07:00
[ settingsSection , providerSection , emailPasswordSection , otherSection , recaptchaSection ,
2024-05-06 16:05:12 -07:00
customAuthDomainSection , appSection , oobSection , multifactorSection ]
2024-05-06 15:53:49 -07:00
2023-08-07 11:55:59 -07:00
static var authLinkSections : [ Section ] {
2024-05-06 15:53:49 -07:00
let allItems = AuthMenuData . sections . flatMap { $0 . items }
2023-08-07 11:55:59 -07:00
let header = "Manage linking between providers"
let footer =
"Select an unchecked row to link the currently signed in user to that auth provider. To unlink the user from a linked provider, select its corresponding row marked with a checkmark."
return [ Section ( headerDescription : header , footerDescription : footer , items : allItems )]
}
2024-05-06 15:53:49 -07:00
var sections : [ Section ] = AuthMenuData . sections
2023-08-07 11:55:59 -07:00
}