| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166 |
- /*
- * 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
|