Skip to content

Commit

Permalink
Merge pull request #1478 from OneSignal/identity_verification_callback
Browse files Browse the repository at this point in the history
Fire jwt invalidated callback when receiving 401 errors
  • Loading branch information
nan-li authored Oct 4, 2024
2 parents c9b0a94 + d4588f5 commit 0bc08eb
Show file tree
Hide file tree
Showing 43 changed files with 2,651 additions and 507 deletions.
2 changes: 1 addition & 1 deletion iOS_SDK/OneSignalDevApp/OneSignalDevApp/AppDelegate.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
#import <UIKit/UIKit.h>
#import <OneSignalFramework/OneSignalFramework.h>

@interface AppDelegate : UIResponder <UIApplicationDelegate, OSNotificationPermissionObserver, OSInAppMessageLifecycleListener, OSPushSubscriptionObserver, OSNotificationLifecycleListener, OSInAppMessageClickListener, OSNotificationClickListener, OSUserStateObserver>
@interface AppDelegate : UIResponder <UIApplicationDelegate, OSNotificationPermissionObserver, OSInAppMessageLifecycleListener, OSPushSubscriptionObserver, OSNotificationLifecycleListener, OSInAppMessageClickListener, OSNotificationClickListener, OSUserStateObserver, OSUserJwtInvalidatedListener>

@property (strong, nonatomic) UIWindow *window;

Expand Down
13 changes: 11 additions & 2 deletions iOS_SDK/OneSignalDevApp/OneSignalDevApp/AppDelegate.m
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ @implementation AppDelegate

OneSignalNotificationCenterDelegate *_notificationDelegate;

// ECM Should we ship these typedefs in OneSignalFramework.h to make them available to Objective C customers?
typedef void (^JwtCompletionBlock)(NSString*);
typedef void (^JwtExpiredBlock)(NSString *, JwtCompletionBlock);

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

// [FIRApp configure];
Expand All @@ -72,6 +76,7 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(
[OneSignal.User addObserver:self];
[OneSignal.Notifications addPermissionObserver:self];
[OneSignal.InAppMessages addClickListener:self];
[OneSignal addUserJwtInvalidatedListener:self];

NSLog(@"UNUserNotificationCenter.delegate: %@", UNUserNotificationCenter.currentNotificationCenter.delegate);

Expand All @@ -86,8 +91,8 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(
return YES;
}

#define ONESIGNAL_APP_ID_DEFAULT @"STAGING_APP_HERE"
#define ONESIGNAL_APP_ID_KEY_FOR_TESTING @"YOUR_APP_ID_HERE"
#define ONESIGNAL_APP_ID_DEFAULT @"77e32082-ea27-42e3-a898-c72e141824ef"
#define ONESIGNAL_APP_ID_KEY_FOR_TESTING @"77e32082-ea27-42e3-a898-c72e141824ef"

+ (NSString*)getOneSignalAppId {
NSString* userDefinedAppId = [[NSUserDefaults standardUserDefaults] objectForKey:ONESIGNAL_APP_ID_KEY_FOR_TESTING];
Expand Down Expand Up @@ -121,6 +126,10 @@ - (void)onUserStateDidChangeWithState:(OSUserChangedState * _Nonnull)state {
NSLog(@"Dev App onUserStateDidChangeWithState: %@", [state jsonRepresentation]);
}

- (void)onUserJwtInvalidatedWithEvent:(OSUserJwtInvalidatedEvent * _Nonnull)event {
NSLog(@"Dev App onUserJwtInvalidatedWithEvent: %@", [event jsonRepresentation]);
}

#pragma mark OSInAppMessageDelegate

- (void)onClickInAppMessage:(OSInAppMessageClickEvent * _Nonnull)event {
Expand Down
11 changes: 10 additions & 1 deletion iOS_SDK/OneSignalDevApp/OneSignalDevApp/SwiftTest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,19 @@
import Foundation
import OneSignalFramework

class SwiftTest: NSObject {
class SwiftTest: NSObject, OSUserJwtInvalidatedListener {
func onUserJwtInvalidated(event: OSUserJwtInvalidatedEvent) {
print("event: \(event.jsonRepresentation())")
print("externalId: \(event.externalId)")
}

func testSwiftUserModel() {
let token1 = OneSignal.User.pushSubscription.token
let token = OneSignal.User.pushSubscription.token
OneSignal.Debug._dump()
OneSignal.login(externalId: "euid", token: "token")
OneSignal.updateUserJwt(externalId: "euid", token: "token")
OneSignal.addUserJwtInvalidatedListener(self)
OneSignal.removeUserJwtInvalidatedListener(self)
}
}
4 changes: 2 additions & 2 deletions iOS_SDK/OneSignalDevApp/OneSignalDevApp/ViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -197,14 +197,14 @@ - (IBAction)inAppMessagingSegmentedControlValueChanged:(UISegmentedControl *)sen
- (IBAction)loginExternalUserId:(UIButton *)sender {
NSString* externalUserId = self.externalUserIdTextField.text;
NSString* token = self.tokenTextField.text;
NSLog(@"Dev App: Logging in to external user ID %@ and token %@", externalUserId, token);
NSLog(@"Dev App: Logging in to external user ID %@ and token %@", externalUserId, token);
[OneSignal login:externalUserId withToken:token];
}

- (IBAction)updateJwt:(id)sender {
NSString* externalUserId = self.externalUserIdTextField.text;
NSString* token = self.tokenTextField.text;
NSLog(@"Dev App: updating JWT for external user ID %@ and token %@", externalUserId, token);
NSLog(@"Dev App: updating JWT for external user ID %@ and token %@", externalUserId, token);
[OneSignal updateUserJwt:externalUserId withToken:token];
}

Expand Down
227 changes: 221 additions & 6 deletions iOS_SDK/OneSignalDevApp/OneSignalExample.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

68 changes: 60 additions & 8 deletions iOS_SDK/OneSignalSDK/OneSignal.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@
// Networking
#define OS_API_VERSION @"1"
#define OS_API_ACCEPT_HEADER @"application/vnd.onesignal.v" OS_API_VERSION @"+json"
#define OS_API_SERVER_URL @"https://api.staging.onesignal.com/"
#define OS_IAM_WEBVIEW_BASE_URL @"https://staging.onesignal.com/"
#define OS_API_SERVER_URL @"https://api.onesignal.com/"
#define OS_IAM_WEBVIEW_BASE_URL @"https://onesignal.com/"

// OneSignalUserDefault keys
// String values start with "OSUD_" to maintain a level of uniqueness from other libs and app code
Expand Down Expand Up @@ -79,7 +79,6 @@
#define OSUD_REQUIRES_USER_PRIVACY_CONSENT @"OSUD_REQUIRES_USER_PRIVACY_CONSENT"

/* Identity Verification */
// TODO: JWT 🔐 Figure out the key below and may need to relate to existing key IOS_REQUIRES_USER_ID_AUTHENTICATION
#define OSUD_USE_IDENTITY_VERIFICATION @"OSUD_USE_IDENTITY_VERIFICATION"
#define OS_JWT_BEARER_TOKEN @"OS_JWT_BEARER_TOKEN"
#define OS_JWT_TOKEN_INVALID @"OS_JWT_TOKEN_INVALID"
Expand Down Expand Up @@ -135,7 +134,7 @@
#define IOS_USES_PROVISIONAL_AUTHORIZATION @"uses_provisional_auth"
#define IOS_REQUIRES_EMAIL_AUTHENTICATION @"require_email_auth"
#define IOS_REQUIRES_SMS_AUTHENTICATION @"require_sms_auth"
#define IOS_REQUIRES_USER_ID_AUTHENTICATION @"require_user_id_auth" // TODO: JWT 🔐 Figure out the key, also think about needing to migrate this value
#define IOS_JWT_REQUIRED @"jwt_required" // Returned by remote params
#define IOS_RECEIVE_RECEIPTS_ENABLE @"receive_receipts_enable"
#define IOS_OUTCOMES_V2_SERVICE_ENABLE @"v2_enabled"
#define IOS_LOCATION_SHARED @"location_shared"
Expand Down Expand Up @@ -347,23 +346,28 @@ typedef enum {GET, POST, HEAD, PUT, DELETE, OPTIONS, CONNECT, TRACE, PATCH} HTTP
#define OS_USER_EXECUTOR @"OS_USER_EXECUTOR"
#define OS_USER_EXECUTOR_USER_REQUEST_QUEUE_KEY @"OS_USER_EXECUTOR_USER_REQUEST_QUEUE_KEY"
#define OS_USER_EXECUTOR_TRANSFER_SUBSCRIPTION_REQUEST_QUEUE_KEY @"OS_USER_EXECUTOR_TRANSFER_SUBSCRIPTION_REQUEST_QUEUE_KEY"
#define OS_USER_EXECUTOR_PENDING_QUEUE_KEY @"OS_USER_EXECUTOR_PENDING_QUEUE_KEY"

// Identity Executor
#define OS_IDENTITY_EXECUTOR @"OS_IDENTITY_EXECUTOR"
#define OS_IDENTITY_EXECUTOR_DELTA_QUEUE_KEY @"OS_IDENTITY_EXECUTOR_DELTA_QUEUE_KEY"
#define OS_IDENTITY_EXECUTOR_ADD_REQUEST_QUEUE_KEY @"OS_IDENTITY_EXECUTOR_ADD_REQUEST_QUEUE_KEY"
#define OS_IDENTITY_EXECUTOR_REMOVE_REQUEST_QUEUE_KEY @"OS_IDENTITY_EXECUTOR_REMOVE_REQUEST_QUEUE_KEY"
#define OS_IDENTITY_EXECUTOR_PENDING_QUEUE_KEY @"OS_IDENTITY_EXECUTOR_PENDING_QUEUE_KEY"

// Property Executor
#define OS_PROPERTIES_EXECUTOR @"OS_PROPERTIES_EXECUTOR"
#define OS_PROPERTIES_EXECUTOR_DELTA_QUEUE_KEY @"OS_PROPERTIES_EXECUTOR_DELTA_QUEUE_KEY"
#define OS_PROPERTIES_EXECUTOR_UPDATE_REQUEST_QUEUE_KEY @"OS_PROPERTIES_EXECUTOR_UPDATE_REQUEST_QUEUE_KEY"
#define OS_PROPERTIES_EXECUTOR_PENDING_QUEUE_KEY @"OS_PROPERTIES_EXECUTOR_PENDING_QUEUE_KEY"

// Subscription Executor
#define OS_SUBSCRIPTION_EXECUTOR @"OS_SUBSCRIPTION_EXECUTOR"
#define OS_SUBSCRIPTION_EXECUTOR_DELTA_QUEUE_KEY @"OS_SUBSCRIPTION_EXECUTOR_DELTA_QUEUE_KEY"
#define OS_SUBSCRIPTION_EXECUTOR_ADD_REQUEST_QUEUE_KEY @"OS_SUBSCRIPTION_EXECUTOR_ADD_REQUEST_QUEUE_KEY"
#define OS_SUBSCRIPTION_EXECUTOR_REMOVE_REQUEST_QUEUE_KEY @"OS_SUBSCRIPTION_EXECUTOR_REMOVE_REQUEST_QUEUE_KEY"
#define OS_SUBSCRIPTION_EXECUTOR_UPDATE_REQUEST_QUEUE_KEY @"OS_SUBSCRIPTION_EXECUTOR_UPDATE_REQUEST_QUEUE_KEY"
#define OS_SUBSCRIPTION_EXECUTOR_PENDING_QUEUE_KEY @"OS_SUBSCRIPTION_EXECUTOR_PENDING_QUEUE_KEY"

// Live Activies Executor
#define OS_LIVE_ACTIVITIES_EXECUTOR_UPDATE_TOKENS_KEY @"OS_LIVE_ACTIVITIES_EXECUTOR_UPDATE_TOKENS_KEY"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ + (OSUIApplicationReleaseMode) releaseMode {
NSDictionary *entitlements = nil;
NSDictionary *provision = [self getProvision];
if (provision) {
// [OneSignalLog onesignalLog:ONE_S_LL_DEBUG message:[NSString stringWithFormat:@"provision: %@", provision]];
[OneSignalLog onesignalLog:ONE_S_LL_DEBUG message:[NSString stringWithFormat:@"provision: %@", provision]];
entitlements = [provision objectForKey:@"Entitlements"];
}
else
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,10 @@ - (void)initializeTriggerController {

- (void)updateInAppMessagesFromCache {
self.messages = [OneSignalUserDefaults.initStandard getSavedCodeableDataForKey:OS_IAM_MESSAGES_ARRAY defaultValue:[NSArray new]];
[self evaluateMessages];
// ECM THIS NEEDS TO RUN ON THE MAIN THREAD
dispatch_async(dispatch_get_main_queue(), ^{
[self evaluateMessages];
});
}

/**
Expand Down Expand Up @@ -323,11 +326,16 @@ - (void)getInAppMessagesFromServer {
OSResponseStatusType responseType = [OSNetworkingUtils getResponseStatusType:error.code];
if (responseType == OSResponseStatusUnauthorized) {
shouldRetryGetInAppMessagesOnJwtUpdated = true;
[self handleUnauthroizedError:error externalId:alias.id];
}
[self updateInAppMessagesFromCache];
}];
}

- (void)handleUnauthroizedError:(NSError*)error externalId:(NSString *)externalId {
[OneSignalUserManagerImpl.sharedInstance invalidateJwtForExternalIdWithExternalId:externalId error:error];
}

- (void)updateInAppMessagesFromServer:(NSArray<OSInAppMessageInternal *> *)newMessages {
[OneSignalLog onesignalLog:ONE_S_LL_VERBOSE message:@"updateInAppMessagesFromServer"];
self.messages = newMessages;
Expand Down Expand Up @@ -1146,7 +1154,6 @@ - (void)onPushSubscriptionDidChangeWithState:(OSPushSubscriptionChangedState * _

#pragma mark OSUserStateObserver Methods
- (void)onUserStateDidChangeWithState:(OSUserChangedState * _Nonnull)state {
NSLog(@"❌ OSMessagingController onUserStateDidChangeWithState: %@", [state jsonRepresentation]);
if (state.current.onesignalId && shouldRetryGetInAppMessagesOnUserChange) {
shouldRetryGetInAppMessagesOnUserChange = false;
[self getInAppMessagesFromServer];
Expand All @@ -1159,7 +1166,6 @@ - (void)onRequiresUserAuthChangedFrom:(enum OSRequiresUserAuth)from to:(enum OSR
}

- (void)onJwtUpdatedWithExternalId:(NSString *)externalId token:(NSString *)token {
NSLog(@"❌ OSMessagingController onJwtUpdatedWithExternalId: %@ token: %@", externalId, token);
if (![token isEqual: OS_JWT_TOKEN_INVALID] && shouldRetryGetInAppMessagesOnJwtUpdated) {
shouldRetryGetInAppMessagesOnJwtUpdated = false;
[self getInAppMessagesFromServer];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,7 @@ public class OSUserJwtConfig {
return
}

print("❌ OSUserJwtConfig.requiresUserAuth: changing from \(oldValue) to \(requiresUserAuth), firing \(changeNotifier)")

OneSignalLog.onesignalLog(.LL_VERBOSE, message: "OSUserJwtConfig.requiresUserAuth: changing from \(oldValue) to \(requiresUserAuth), firing listeners")
// Persist new value
OneSignalUserDefaults.initShared().saveInteger(forKey: OSUD_USE_IDENTITY_VERIFICATION, withValue: requiresUserAuth.rawValue)

Expand Down Expand Up @@ -93,9 +92,6 @@ public class OSUserJwtConfig {

public init() {
let rawValue = OneSignalUserDefaults.initShared().getSavedInteger(forKey: OSUD_USE_IDENTITY_VERIFICATION, defaultValue: OSRequiresUserAuth.unknown.rawValue)

print("❌ OSUserJwtConfig init(): \(String(describing: OSRequiresUserAuth(rawValue: rawValue))))")

requiresUserAuth = OSRequiresUserAuth(rawValue: rawValue) ?? OSRequiresUserAuth.unknown
}

Expand All @@ -104,7 +100,7 @@ public class OSUserJwtConfig {
}

public func onJwtTokenChanged(externalId: String, token: String?) {
print("OSUserJwtConfig.onJwtTokenChanged \(externalId): \(token)")
OneSignalLog.onesignalLog(.LL_VERBOSE, message: "OSUserJwtConfig.onJwtTokenChanged for \(externalId) with token \(token ?? "nil"), firing listeners")
changeNotifier.fire { listener in
listener.onJwtUpdated(externalId: externalId, token: token)
}
Expand Down
18 changes: 10 additions & 8 deletions iOS_SDK/OneSignalSDK/OneSignalOSCore/Source/OSOperationRepo.swift
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,6 @@ public class OSOperationRepo {
public init(jwtConfig: OSUserJwtConfig) {
self.jwtConfig = jwtConfig
self.jwtConfig.subscribe(self, key: OS_OPERATION_REPO)
print("❌ OSOperationRepo init(\(String(describing: jwtConfig.isRequired))) called")

// Read the Deltas from cache, if any...
guard let deltaQueue = OneSignalUserDefaults.initShared().getSavedCodeableData(forKey: OS_OPERATION_REPO_DELTA_QUEUE_KEY, defaultValue: []) as? [OSDelta] else {
OneSignalLog.onesignalLog(.LL_ERROR, message: "OSOperationRepo is unable to uncache the OSDelta queue.")
Expand All @@ -73,7 +71,7 @@ public class OSOperationRepo {
}

guard jwtConfig.isRequired != nil else {
print("OSOperationRepo.start() returning early due to unknown Identity Verification status.")
OneSignalLog.onesignalLog(.LL_DEBUG, message: "OSOperationRepo.start() returning early due to unknown Identity Verification status")
return
}

Expand Down Expand Up @@ -185,7 +183,6 @@ public class OSOperationRepo {

extension OSOperationRepo: OSUserJwtConfigListener {
public func onRequiresUserAuthChanged(from: OSRequiresUserAuth, to: OSRequiresUserAuth) {
print("❌ OSOperationRepo onRequiresUserAuthChanged from \(String(describing: from)) to \(String(describing: to))")
// If auth changed from false or unknown to true, process deltas
if to == .on {
removeInvalidDeltas()
Expand All @@ -194,7 +191,7 @@ extension OSOperationRepo: OSUserJwtConfigListener {
}

public func onJwtUpdated(externalId: String, token: String?) {
print("❌ OSOperationRepo onJwtUpdated for \(externalId) to \(String(describing: token))")
// Not used for now
}

/**
Expand All @@ -203,14 +200,19 @@ extension OSOperationRepo: OSUserJwtConfigListener {
Executors will handle this.
*/
func removeInvalidDeltas() {
print("❌ OSOperationRepo removeInvalidDeltas TODO!")
// Not used for now
}
}

extension OSOperationRepo: OSLoggable {
public func logSelf() {
print("💛 Operation Repo: deltaQueue: \(self.deltaQueue )")
print("💛 Operation Repo: executors that are subscribed:")
OneSignalLog.onesignalLog(.LL_VERBOSE, message:
"""
Operation Repo: deltaQueue: \(self.deltaQueue)
Operation Repo: executors that are subscribed:
"""
)
for executor in self.executors {
executor.logSelf()
}
Expand Down
Loading

0 comments on commit 0bc08eb

Please sign in to comment.