Files
WebApp/Pods/FirebaseAuth/FirebaseAuth/Sources/Auth/FIRAuthTokenResult.m
2024-12-20 17:49:45 +08:00

167 lines
5.9 KiB
Objective-C

/*
* Copyright 2018 Google
*
* 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 "FirebaseAuth/Sources/Auth/FIRAuthTokenResult_Internal.h"
#import "FirebaseAuth/Sources/Utilities/FIRAuthErrorUtils.h"
NS_ASSUME_NONNULL_BEGIN
/** @var kExpirationDateKey
@brief The key used to encode the expirationDate property for NSSecureCoding.
*/
static NSString *const kExpirationDateKey = @"expiratinDate";
/** @var kTokenKey
@brief The key used to encode the token property for NSSecureCoding.
*/
static NSString *const kTokenKey = @"token";
/** @var kAuthDateKey
@brief The key used to encode the authDate property for NSSecureCoding.
*/
static NSString *const kAuthDateKey = @"authDate";
/** @var kIssuedDateKey
@brief The key used to encode the issuedDate property for NSSecureCoding.
*/
static NSString *const kIssuedDateKey = @"issuedDate";
/** @var kSignInProviderKey
@brief The key used to encode the signInProvider property for NSSecureCoding.
*/
static NSString *const kSignInProviderKey = @"signInProvider";
/** @var kSignInSecondFactorKey
@brief The key used to encode the signInSecondFactor property for NSSecureCoding.
*/
static NSString *const kSignInSecondFactorKey = @"signInSecondFactor";
/** @var kClaimsKey
@brief The key used to encode the claims property for NSSecureCoding.
*/
static NSString *const kClaimsKey = @"claims";
@implementation FIRAuthTokenResult
- (instancetype)initWithToken:(NSString *)token
expirationDate:(NSDate *)expirationDate
authDate:(NSDate *)authDate
issuedAtDate:(NSDate *)issuedAtDate
signInProvider:(NSString *)signInProvider
signInSecondFactor:(NSString *)signInSecondFactor
claims:(NSDictionary *)claims {
self = [super init];
if (self) {
_token = token;
_expirationDate = expirationDate;
_authDate = authDate;
_issuedAtDate = issuedAtDate;
_signInProvider = signInProvider;
_signInSecondFactor = signInSecondFactor;
_claims = claims;
}
return self;
}
+ (nullable FIRAuthTokenResult *)tokenResultWithToken:(NSString *)token {
NSArray *tokenStringArray = [token componentsSeparatedByString:@"."];
// The JWT should have three parts, though we only use the second in this method.
if (tokenStringArray.count != 3) {
return nil;
}
// The token payload is always the second index of the array.
NSString *IDToken = tokenStringArray[1];
// Convert the base64URL encoded string to a base64 encoded string.
// Replace "_" with "/"
NSMutableString *tokenPayload = [[IDToken stringByReplacingOccurrencesOfString:@"_"
withString:@"/"] mutableCopy];
// Replace "-" with "+"
[tokenPayload replaceOccurrencesOfString:@"-"
withString:@"+"
options:kNilOptions
range:NSMakeRange(0, tokenPayload.length)];
// Pad the token payload with "=" signs if the payload's length is not a multiple of 4.
while ((tokenPayload.length % 4) != 0) {
[tokenPayload appendFormat:@"="];
}
NSData *decodedTokenPayloadData =
[[NSData alloc] initWithBase64EncodedString:tokenPayload
options:NSDataBase64DecodingIgnoreUnknownCharacters];
if (!decodedTokenPayloadData) {
return nil;
}
NSError *jsonError = nil;
NSJSONReadingOptions options = NSJSONReadingMutableContainers | NSJSONReadingAllowFragments;
NSDictionary *tokenPayloadDictionary =
[NSJSONSerialization JSONObjectWithData:decodedTokenPayloadData
options:options
error:&jsonError];
if (jsonError != nil) {
return nil;
}
if (!tokenPayloadDictionary) {
return nil;
}
// These are dates since 00:00:00 January 1 1970, as described by the Terminology section in
// the JWT spec. https://tools.ietf.org/html/rfc7519
NSDate *expirationDate =
[NSDate dateWithTimeIntervalSince1970:[tokenPayloadDictionary[@"exp"] doubleValue]];
NSDate *authDate =
[NSDate dateWithTimeIntervalSince1970:[tokenPayloadDictionary[@"auth_time"] doubleValue]];
NSDate *issuedAtDate =
[NSDate dateWithTimeIntervalSince1970:[tokenPayloadDictionary[@"iat"] doubleValue]];
NSDictionary *firebaseTokenPayloadDictionary = tokenPayloadDictionary[@"firebase"];
NSString *signInProvider = firebaseTokenPayloadDictionary[@"sign_in_provider"];
NSString *signInSecondFactor = firebaseTokenPayloadDictionary[@"sign_in_second_factor"];
FIRAuthTokenResult *tokenResult =
[[FIRAuthTokenResult alloc] initWithToken:token
expirationDate:expirationDate
authDate:authDate
issuedAtDate:issuedAtDate
signInProvider:signInProvider
signInSecondFactor:signInSecondFactor
claims:tokenPayloadDictionary];
return tokenResult;
}
#pragma mark - NSSecureCoding
+ (BOOL)supportsSecureCoding {
return YES;
}
- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder {
NSString *token = [aDecoder decodeObjectOfClass:[NSDate class] forKey:kTokenKey];
return [FIRAuthTokenResult tokenResultWithToken:token];
}
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:_token forKey:kTokenKey];
}
@end
NS_ASSUME_NONNULL_END