|
@@ -36,12 +36,14 @@ final class GoogleSignInAuthenticator: ObservableObject {
|
|
|
return
|
|
return
|
|
|
}
|
|
}
|
|
|
let manualNonce = UUID().uuidString
|
|
let manualNonce = UUID().uuidString
|
|
|
|
|
+ let tokenClaims: Set<GIDTokenClaim> = Set([GIDTokenClaim.authTime()])
|
|
|
|
|
|
|
|
GIDSignIn.sharedInstance.signIn(
|
|
GIDSignIn.sharedInstance.signIn(
|
|
|
withPresenting: rootViewController,
|
|
withPresenting: rootViewController,
|
|
|
hint: nil,
|
|
hint: nil,
|
|
|
additionalScopes: nil,
|
|
additionalScopes: nil,
|
|
|
- nonce: manualNonce
|
|
|
|
|
|
|
+ nonce: manualNonce,
|
|
|
|
|
+ tokenClaims:tokenClaims
|
|
|
) { signInResult, error in
|
|
) { signInResult, error in
|
|
|
guard let signInResult = signInResult else {
|
|
guard let signInResult = signInResult else {
|
|
|
print("Error! \(String(describing: error))")
|
|
print("Error! \(String(describing: error))")
|
|
@@ -57,6 +59,9 @@ final class GoogleSignInAuthenticator: ObservableObject {
|
|
|
assertionFailure("ERROR: Returned nonce doesn't match manual nonce!")
|
|
assertionFailure("ERROR: Returned nonce doesn't match manual nonce!")
|
|
|
return
|
|
return
|
|
|
}
|
|
}
|
|
|
|
|
+ if let authTimeDate = self.decodeAuthTime(fromJWT: idToken) {
|
|
|
|
|
+ self.authViewModel.authTime = authTimeDate
|
|
|
|
|
+ }
|
|
|
self.authViewModel.state = .signedIn(signInResult.user)
|
|
self.authViewModel.state = .signedIn(signInResult.user)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -154,6 +159,16 @@ private extension GoogleSignInAuthenticator {
|
|
|
return nonce
|
|
return nonce
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ func decodeAuthTime(fromJWT jwt: String) -> Date? {
|
|
|
|
|
+ let segments = jwt.components(separatedBy: ".")
|
|
|
|
|
+ guard segments.count > 1,
|
|
|
|
|
+ let parts = decodeJWTSegment(segments[1]),
|
|
|
|
|
+ let authTimeInterval = parts["auth_time"] as? TimeInterval else {
|
|
|
|
|
+ return nil
|
|
|
|
|
+ }
|
|
|
|
|
+ return Date(timeIntervalSince1970: authTimeInterval)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
func decodeJWTSegment(_ segment: String) -> [String: Any]? {
|
|
func decodeJWTSegment(_ segment: String) -> [String: Any]? {
|
|
|
guard let segmentData = base64UrlDecode(segment),
|
|
guard let segmentData = base64UrlDecode(segment),
|
|
|
let segmentJSON = try? JSONSerialization.jsonObject(with: segmentData, options: []),
|
|
let segmentJSON = try? JSONSerialization.jsonObject(with: segmentData, options: []),
|