Proyectos de Subversion Iphone Microlearning

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
/*
2
 * Copyright 2019 Google
3
 *
4
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 * you may not use this file except in compliance with the License.
6
 * You may obtain a copy of the License at
7
 *
8
 *      http://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 * Unless required by applicable law or agreed to in writing, software
11
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 * See the License for the specific language governing permissions and
14
 * limitations under the License.
15
 */
16
 
17
#import "FirebaseMessaging/Sources/Token/FIRMessagingTokenInfo.h"
18
 
19
#import "FirebaseMessaging/Sources/FIRMessagingConstants.h"
20
#import "FirebaseMessaging/Sources/FIRMessagingLogger.h"
21
#import "FirebaseMessaging/Sources/FIRMessagingUtilities.h"
22
 
23
/**
24
 *  @enum Token Info Dictionary Key Constants
25
 *  @discussion The keys that are checked when a token info is
26
 *              created from a dictionary. The same keys are used
27
 *              when decoding/encoding an archive.
28
 */
29
/// Specifies a dictonary key whose value represents the authorized entity, or
30
/// Sender ID for the token.
31
static NSString *const kFIRInstanceIDAuthorizedEntityKey = @"authorized_entity";
32
/// Specifies a dictionary key whose value represents the scope of the token,
33
/// typically "*".
34
static NSString *const kFIRInstanceIDScopeKey = @"scope";
35
/// Specifies a dictionary key which represents the token value itself.
36
static NSString *const kFIRInstanceIDTokenKey = @"token";
37
/// Specifies a dictionary key which represents the app version associated
38
/// with the token.
39
static NSString *const kFIRInstanceIDAppVersionKey = @"app_version";
40
/// Specifies a dictionary key which represents the GMP App ID associated with
41
/// the token.
42
static NSString *const kFIRInstanceIDFirebaseAppIDKey = @"firebase_app_id";
43
/// Specifies a dictionary key representing an archive for a
44
/// `FIRInstanceIDAPNSInfo` object.
45
static NSString *const kFIRInstanceIDAPNSInfoKey = @"apns_info";
46
/// Specifies a dictionary key representing the "last cached" time for the token.
47
static NSString *const kFIRInstanceIDCacheTimeKey = @"cache_time";
48
/// Default interval that token stays fresh.
49
static const NSTimeInterval kDefaultFetchTokenInterval = 7 * 24 * 60 * 60;  // 7 days.
50
 
51
@implementation FIRMessagingTokenInfo
52
 
53
- (instancetype)initWithAuthorizedEntity:(NSString *)authorizedEntity
54
                                   scope:(NSString *)scope
55
                                   token:(NSString *)token
56
                              appVersion:(NSString *)appVersion
57
                           firebaseAppID:(NSString *)firebaseAppID {
58
  self = [super init];
59
  if (self) {
60
    _authorizedEntity = [authorizedEntity copy];
61
    _scope = [scope copy];
62
    _token = [token copy];
63
    _appVersion = [appVersion copy];
64
    _firebaseAppID = [firebaseAppID copy];
65
  }
66
  return self;
67
}
68
 
69
- (BOOL)isFreshWithIID:(NSString *)IID {
70
  // Last fetch token cache time could be null if token is from legacy storage format. Then token is
71
  // considered not fresh and should be refreshed and overwrite with the latest storage format.
72
  if (!IID) {
73
    return NO;
74
  }
75
  if (!_cacheTime) {
76
    return NO;
77
  }
78
 
79
  // Check if it's consistent with IID
80
  if (![self.token hasPrefix:IID]) {
81
    return NO;
82
  }
83
 
84
  // Check if app has just been updated to a new version.
85
  NSString *currentAppVersion = FIRMessagingCurrentAppVersion();
86
  if (!_appVersion || ![_appVersion isEqualToString:currentAppVersion]) {
87
    FIRMessagingLoggerDebug(kFIRMessagingMessageCodeTokenManager004,
88
                            @"Invalidating cached token for %@ (%@) due to app version change.",
89
                            _authorizedEntity, _scope);
90
    return NO;
91
  }
92
 
93
  // Check if GMP App ID has changed
94
  NSString *currentFirebaseAppID = FIRMessagingFirebaseAppID();
95
  if (!_firebaseAppID || ![_firebaseAppID isEqualToString:currentFirebaseAppID]) {
96
    FIRMessagingLoggerDebug(
97
        kFIRMessagingMessageCodeTokenInfoFirebaseAppIDChanged,
98
        @"Invalidating cached token due to Firebase App IID change from %@ to %@", _firebaseAppID,
99
        currentFirebaseAppID);
100
    return NO;
101
  }
102
 
103
  // Check whether locale has changed, if yes, token needs to be updated with server for locale
104
  // information.
105
  if (FIRMessagingHasLocaleChanged()) {
106
    FIRMessagingLoggerDebug(kFIRMessagingMessageCodeTokenInfoLocaleChanged,
107
                            @"Invalidating cached token due to locale change");
108
    return NO;
109
  }
110
 
111
  // Locale is not changed, check whether token has been fetched within 7 days.
112
  NSTimeInterval lastFetchTokenTimestamp = [_cacheTime timeIntervalSince1970];
113
  NSTimeInterval currentTimestamp = FIRMessagingCurrentTimestampInSeconds();
114
  NSTimeInterval timeSinceLastFetchToken = currentTimestamp - lastFetchTokenTimestamp;
115
  return (timeSinceLastFetchToken < kDefaultFetchTokenInterval);
116
}
117
 
118
- (BOOL)isDefaultToken {
119
  return [self.scope isEqualToString:kFIRMessagingDefaultTokenScope];
120
}
121
 
122
#pragma mark - NSCoding
123
 
124
- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder {
125
  // These value cannot be nil
126
 
127
  id authorizedEntity = [aDecoder decodeObjectForKey:kFIRInstanceIDAuthorizedEntityKey];
128
  if (![authorizedEntity isKindOfClass:[NSString class]]) {
129
    return nil;
130
  }
131
 
132
  id scope = [aDecoder decodeObjectForKey:kFIRInstanceIDScopeKey];
133
  if (![scope isKindOfClass:[NSString class]]) {
134
    return nil;
135
  }
136
 
137
  id token = [aDecoder decodeObjectForKey:kFIRInstanceIDTokenKey];
138
  if (![token isKindOfClass:[NSString class]]) {
139
    return nil;
140
  }
141
 
142
  // These values are nullable, so only fail the decode if the type does not match
143
 
144
  id appVersion = [aDecoder decodeObjectForKey:kFIRInstanceIDAppVersionKey];
145
  if (appVersion && ![appVersion isKindOfClass:[NSString class]]) {
146
    return nil;
147
  }
148
 
149
  id firebaseAppID = [aDecoder decodeObjectForKey:kFIRInstanceIDFirebaseAppIDKey];
150
  if (firebaseAppID && ![firebaseAppID isKindOfClass:[NSString class]]) {
151
    return nil;
152
  }
153
 
154
  id rawAPNSInfo = [aDecoder decodeObjectForKey:kFIRInstanceIDAPNSInfoKey];
155
  if (rawAPNSInfo && ![rawAPNSInfo isKindOfClass:[NSData class]]) {
156
    return nil;
157
  }
158
 
159
  FIRMessagingAPNSInfo *APNSInfo = nil;
160
  if (rawAPNSInfo) {
161
    // TODO(chliangGoogle: Use the new API and secureCoding protocol.
162
    @try {
163
      [NSKeyedUnarchiver setClass:[FIRMessagingAPNSInfo class]
164
                     forClassName:@"FIRInstanceIDAPNSInfo"];
165
#pragma clang diagnostic push
166
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
167
      APNSInfo = [NSKeyedUnarchiver unarchiveObjectWithData:rawAPNSInfo];
168
#pragma clang diagnostic pop
169
    } @catch (NSException *exception) {
170
      FIRMessagingLoggerInfo(kFIRMessagingMessageCodeTokenInfoBadAPNSInfo,
171
                             @"Could not parse raw APNS Info while parsing archived token info.");
172
      APNSInfo = nil;
173
    } @finally {
174
    }
175
  }
176
 
177
  id cacheTime = [aDecoder decodeObjectForKey:kFIRInstanceIDCacheTimeKey];
178
  if (cacheTime && ![cacheTime isKindOfClass:[NSDate class]]) {
179
    return nil;
180
  }
181
 
182
  self = [super init];
183
  if (self) {
184
    _authorizedEntity = [authorizedEntity copy];
185
    _scope = [scope copy];
186
    _token = [token copy];
187
    _appVersion = [appVersion copy];
188
    _firebaseAppID = [firebaseAppID copy];
189
    _APNSInfo = [APNSInfo copy];
190
    _cacheTime = cacheTime;
191
  }
192
  return self;
193
}
194
 
195
- (void)encodeWithCoder:(NSCoder *)aCoder {
196
  [aCoder encodeObject:self.authorizedEntity forKey:kFIRInstanceIDAuthorizedEntityKey];
197
  [aCoder encodeObject:self.scope forKey:kFIRInstanceIDScopeKey];
198
  [aCoder encodeObject:self.token forKey:kFIRInstanceIDTokenKey];
199
  [aCoder encodeObject:self.appVersion forKey:kFIRInstanceIDAppVersionKey];
200
  [aCoder encodeObject:self.firebaseAppID forKey:kFIRInstanceIDFirebaseAppIDKey];
201
  NSData *rawAPNSInfo;
202
  if (self.APNSInfo) {
203
    // TODO(chliangGoogle: Use the new API and secureCoding protocol.
204
    [NSKeyedArchiver setClassName:@"FIRInstanceIDAPNSInfo" forClass:[FIRMessagingAPNSInfo class]];
205
#pragma clang diagnostic push
206
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
207
    rawAPNSInfo = [NSKeyedArchiver archivedDataWithRootObject:self.APNSInfo];
208
#pragma clang diagnostic pop
209
 
210
    [aCoder encodeObject:rawAPNSInfo forKey:kFIRInstanceIDAPNSInfoKey];
211
  }
212
  [aCoder encodeObject:self.cacheTime forKey:kFIRInstanceIDCacheTimeKey];
213
}
214
 
215
@end