Skip to content

WIP Jwt app startup #1467

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 13 commits into from
51 changes: 39 additions & 12 deletions iOS_SDK/OneSignalDevApp/OneSignalDevApp/Base.lproj/Main.storyboard

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions iOS_SDK/OneSignalDevApp/OneSignalDevApp/SwiftTest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,7 @@ class SwiftTest: NSObject {
func testSwiftUserModel() {
let token1 = OneSignal.User.pushSubscription.token
let token = OneSignal.User.pushSubscription.token
OneSignal.Debug.dump()
OneSignal.updateUserJwt("externalId", withToken: "jwtToken")
}
}
2 changes: 2 additions & 0 deletions iOS_SDK/OneSignalDevApp/OneSignalDevApp/ViewController.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,9 @@
@property (weak, nonatomic) IBOutlet UIButton *removeSmsButton;

@property (weak, nonatomic) IBOutlet UITextField *externalUserIdTextField;
@property (weak, nonatomic) IBOutlet UITextField *tokenTextField;
@property (weak, nonatomic) IBOutlet UIButton *loginExternalUserIdButton;
@property (weak, nonatomic) IBOutlet UIButton *updateJwtButton;
@property (weak, nonatomic) IBOutlet UIButton *logoutButton;

@property (weak, nonatomic) IBOutlet UITextField *addAliasLabelTextField;
Expand Down
13 changes: 11 additions & 2 deletions iOS_SDK/OneSignalDevApp/OneSignalDevApp/ViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ - (IBAction)sendTagButton:(id)sender {
- (IBAction)getTagsButton:(id)sender {
NSDictionary<NSString *, NSString*> *tags = [OneSignal.User getTags];
NSLog(@"Tags: %@", tags);
[OneSignal.Debug dump];
}

- (IBAction)sendTagsButton:(id)sender {
Expand Down Expand Up @@ -195,8 +196,16 @@ - (IBAction)inAppMessagingSegmentedControlValueChanged:(UISegmentedControl *)sen

- (IBAction)loginExternalUserId:(UIButton *)sender {
NSString* externalUserId = self.externalUserIdTextField.text;
NSLog(@"Dev App: Logging in to external user ID %@", externalUserId);
[OneSignal login:externalUserId];
NSString* token = self.tokenTextField.text;
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);
[OneSignal updateUserJwt:externalUserId withToken:token];
}

- (IBAction)logout:(UIButton *)sender {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
@property (weak, nonatomic) IBOutlet UITextField *addTriggerValue;
@property (weak, nonatomic) IBOutlet UIButton *addTriggerButton;
@property (weak, nonatomic) IBOutlet UITextField *removeTriggerKey;
- (IBAction)updateJwt:(id)sender;
@property (weak, nonatomic) IBOutlet UITextField *getTriggerKey;
@property (weak, nonatomic) IBOutlet UILabel *infoLabel;
@property (weak, nonatomic) IBOutlet UITextField *outcomeName;
Expand Down
227 changes: 6 additions & 221 deletions iOS_SDK/OneSignalDevApp/OneSignalExample.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

16 changes: 16 additions & 0 deletions iOS_SDK/OneSignalSDK/OneSignal.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
3C0151922C2E298F0079E076 /* OneSignalInAppMessages.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DEBAAE282A4211D900BF2C1C /* OneSignalInAppMessages.framework */; };
3C01519C2C2E29F90079E076 /* IAMRequestTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 3C01519B2C2E29F90079E076 /* IAMRequestTests.m */; };
3C0EF49E28A1DBCB00E5434B /* OSUserInternalImpl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C0EF49D28A1DBCB00E5434B /* OSUserInternalImpl.swift */; };
3C10E0632BF5651500A7B37F /* OSLoggable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C10E0622BF5651500A7B37F /* OSLoggable.swift */; };
3C115165289A259500565C41 /* OneSignalOSCore.docc in Sources */ = {isa = PBXBuildFile; fileRef = 3C115164289A259500565C41 /* OneSignalOSCore.docc */; };
3C115171289A259500565C41 /* OneSignalOSCore.h in Headers */ = {isa = PBXBuildFile; fileRef = 3C115163289A259500565C41 /* OneSignalOSCore.h */; settings = {ATTRIBUTES = (Public, ); }; };
3C115185289ADE4F00565C41 /* OSModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C115184289ADE4F00565C41 /* OSModel.swift */; };
Expand All @@ -73,6 +74,7 @@
3C277D7E2BD76E0000857606 /* OSIdentityModelRepo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C277D7D2BD76E0000857606 /* OSIdentityModelRepo.swift */; };
3C2C7DC8288F3C020020F9AE /* OSSubscriptionModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C2C7DC7288F3C020020F9AE /* OSSubscriptionModel.swift */; };
3C2D8A5928B4C4E300BE41F6 /* OSDelta.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C2D8A5828B4C4E300BE41F6 /* OSDelta.swift */; };
3C2FF9D02C5FCD760081293B /* OSUserJwtConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C2FF9CF2C5FCD760081293B /* OSUserJwtConfig.swift */; };
3C44673E296D099D0039A49E /* OneSignalMobileProvision.m in Sources */ = {isa = PBXBuildFile; fileRef = 912411FD1E73342200E41FD7 /* OneSignalMobileProvision.m */; };
3C44673F296D09CC0039A49E /* OneSignalMobileProvision.h in Headers */ = {isa = PBXBuildFile; fileRef = 912411FC1E73342200E41FD7 /* OneSignalMobileProvision.h */; settings = {ATTRIBUTES = (Public, ); }; };
3C448B9D2936ADFD002F96BC /* OSBackgroundTaskHandlerImpl.h in Headers */ = {isa = PBXBuildFile; fileRef = 3C448B9B2936ADFD002F96BC /* OSBackgroundTaskHandlerImpl.h */; };
Expand Down Expand Up @@ -1208,6 +1210,7 @@
3C01518E2C2E298E0079E076 /* OneSignalInAppMessagesTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = OneSignalInAppMessagesTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
3C01519B2C2E29F90079E076 /* IAMRequestTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = IAMRequestTests.m; sourceTree = "<group>"; };
3C0EF49D28A1DBCB00E5434B /* OSUserInternalImpl.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OSUserInternalImpl.swift; sourceTree = "<group>"; };
3C10E0622BF5651500A7B37F /* OSLoggable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OSLoggable.swift; sourceTree = "<group>"; };
3C115161289A259500565C41 /* OneSignalOSCore.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = OneSignalOSCore.framework; sourceTree = BUILT_PRODUCTS_DIR; };
3C115163289A259500565C41 /* OneSignalOSCore.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OneSignalOSCore.h; sourceTree = "<group>"; };
3C115164289A259500565C41 /* OneSignalOSCore.docc */ = {isa = PBXFileReference; lastKnownFileType = folder.documentationcatalog; path = OneSignalOSCore.docc; sourceTree = "<group>"; };
Expand All @@ -1224,6 +1227,7 @@
3C2C7DC2288E007E0020F9AE /* UnitTests-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "UnitTests-Bridging-Header.h"; sourceTree = "<group>"; };
3C2C7DC7288F3C020020F9AE /* OSSubscriptionModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OSSubscriptionModel.swift; sourceTree = "<group>"; };
3C2D8A5828B4C4E300BE41F6 /* OSDelta.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OSDelta.swift; sourceTree = "<group>"; };
3C2FF9CF2C5FCD760081293B /* OSUserJwtConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OSUserJwtConfig.swift; sourceTree = "<group>"; };
3C448B9B2936ADFD002F96BC /* OSBackgroundTaskHandlerImpl.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OSBackgroundTaskHandlerImpl.h; sourceTree = "<group>"; };
3C448B9C2936ADFD002F96BC /* OSBackgroundTaskHandlerImpl.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OSBackgroundTaskHandlerImpl.m; sourceTree = "<group>"; };
3C448BA12936B474002F96BC /* OSBackgroundTaskManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OSBackgroundTaskManager.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -2048,6 +2052,7 @@
isa = PBXGroup;
children = (
3C115163289A259500565C41 /* OneSignalOSCore.h */,
3C2FF9CE2C5FCD590081293B /* Jwt */,
3C115188289ADEA300565C41 /* OSModelStore.swift */,
3C115186289ADE7700565C41 /* OSModelStoreListener.swift */,
3C115184289ADE4F00565C41 /* OSModel.swift */,
Expand All @@ -2061,10 +2066,19 @@
4710EA522B8FCFB200435356 /* OSDispatchQueue.swift */,
DEFB3E642BB7346D00E65DAD /* OSLiveActivities.swift */,
DEFB3E662BB735B500E65DAD /* OSStubLiveActivities.swift */,
3C10E0622BF5651500A7B37F /* OSLoggable.swift */,
);
path = Source;
sourceTree = "<group>";
};
3C2FF9CE2C5FCD590081293B /* Jwt */ = {
isa = PBXGroup;
children = (
3C2FF9CF2C5FCD760081293B /* OSUserJwtConfig.swift */,
);
path = Jwt;
sourceTree = "<group>";
};
3C8544B72C5AEFF700F542A9 /* OneSignalOSCoreMocks */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -4035,6 +4049,7 @@
DEFB3E652BB7346D00E65DAD /* OSLiveActivities.swift in Sources */,
3C4F9E4428A4466C009F453A /* OSOperationRepo.swift in Sources */,
3C11518B289ADEEB00565C41 /* OSEventProducer.swift in Sources */,
3C10E0632BF5651500A7B37F /* OSLoggable.swift in Sources */,
3C115165289A259500565C41 /* OneSignalOSCore.docc in Sources */,
3C115189289ADEA300565C41 /* OSModelStore.swift in Sources */,
3C115185289ADE4F00565C41 /* OSModel.swift in Sources */,
Expand All @@ -4043,6 +4058,7 @@
3CE5F9E3289D88DC004A156E /* OSModelStoreChangedHandler.swift in Sources */,
3C2D8A5928B4C4E300BE41F6 /* OSDelta.swift in Sources */,
4710EA532B8FCFB200435356 /* OSDispatchQueue.swift in Sources */,
3C2FF9D02C5FCD760081293B /* OSUserJwtConfig.swift in Sources */,
DEFB3E672BB735B500E65DAD /* OSStubLiveActivities.swift in Sources */,
3C11518D289AF5E800565C41 /* OSModelChangedHandler.swift in Sources */,
3C8E6DF928A6D89E0031E48A /* OSOperationExecutor.swift in Sources */,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@
// Remote Params
#define OSUD_LOCATION_ENABLED @"OSUD_LOCATION_ENABLED"
#define OSUD_REQUIRES_USER_PRIVACY_CONSENT @"OSUD_REQUIRES_USER_PRIVACY_CONSENT"
// 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"
// Remote Params - Receive Receipts
#define OSUD_RECEIVE_RECEIPTS_ENABLED @"OS_ENABLE_RECEIVE_RECEIPTS" // * OSUD_RECEIVE_RECEIPTS_ENABLED
// Outcomes
Expand Down Expand Up @@ -128,7 +130,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"
#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_RECEIVE_RECEIPTS_ENABLE @"receive_receipts_enable"
#define IOS_OUTCOMES_V2_SERVICE_ENABLE @"v2_enabled"
#define IOS_LOCATION_SHARED @"location_shared"
Expand Down
3 changes: 2 additions & 1 deletion iOS_SDK/OneSignalSDK/OneSignalCore/Source/OneSignalLog.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,10 @@ typedef NS_ENUM(NSUInteger, ONE_S_LOG_LEVEL) {
@protocol OSDebug <NSObject>
+ (void)setLogLevel:(ONE_S_LOG_LEVEL)logLevel;
+ (void)setAlertLevel:(ONE_S_LOG_LEVEL)logLevel NS_REFINED_FOR_SWIFT;
+ (void)dump;
@end

@interface OneSignalLog : NSObject<OSDebug>
@interface OneSignalLog : NSObject <OSDebug>
+ (Class<OSDebug>)Debug;
+ (void)onesignalLog:(ONE_S_LOG_LEVEL)logLevel message:(NSString* _Nonnull)message;
+ (ONE_S_LOG_LEVEL)getLogLevel;
Expand Down
19 changes: 16 additions & 3 deletions iOS_SDK/OneSignalSDK/OneSignalCore/Source/OneSignalLog.m
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@
#import "OneSignalLog.h"
#import "OSDialogInstanceManager.h"

/**
Implements the setter methods of protocol `OSDebug`.
The `log` method will be implemented in OneSignal module.
*/
@implementation OneSignalLog

static ONE_S_LOG_LEVEL _nsLogLevel = ONE_S_LL_WARN;
Expand All @@ -46,6 +50,9 @@ + (void)setAlertLevel:(ONE_S_LOG_LEVEL)logLevel {
_alertLogLevel = logLevel;
}

+ (void)dump {}


+ (void)onesignalLog:(ONE_S_LOG_LEVEL)logLevel message:(NSString* _Nonnull)message {
onesignal_Log(logLevel, message);
}
Expand Down Expand Up @@ -79,9 +86,15 @@ void onesignal_Log(ONE_S_LOG_LEVEL logLevel, NSString* message) {
default:
break;
}

if (logLevel <= _nsLogLevel)
NSLog(@"%@", [levelString stringByAppendingString:message]);

if (logLevel <= _nsLogLevel) {
NSString *thread = @"";
if ([NSThread.currentThread isMainThread]) {
thread = @"[main]: ";
}
// NSLog(@"%@", [levelString stringByAppendingString:message]);
NSLog(@"%@", [NSString stringWithFormat:@"%@%@%@", thread, levelString, message]);
}

if (logLevel <= _alertLogLevel) {
[[OSDialogInstanceManager sharedInstance] presentDialogWithTitle:levelString withMessage:message withActions:nil cancelTitle:NSLocalizedString(@"Close", @"Close button") withActionCompletion:nil];
Expand Down
114 changes: 114 additions & 0 deletions iOS_SDK/OneSignalSDK/OneSignalOSCore/Source/Jwt/OSUserJwtConfig.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
/*
Modified MIT License

Copyright 2024 OneSignal

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

1. The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

2. All copies of substantial portions of the Software may only be used in connection
with services provided by OneSignal.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

import Foundation
import OneSignalCore

/**
Use an enum to avoid working with optional Bool, which is unsightly to cache and uncache.
*/
enum OSRequiresUserAuth: String {
case on
case off
case unknown
// TODO: JWT 🔐 consider additional reasons such as detecting this by dev calling loginWithJWT / onViaRemoteParams

func isRequired() -> Bool? {
return switch self {
case .on:
true
case .off:
false
default:
nil
}
}
}

/**
Internal listener.
*/
public protocol OSUserJwtConfigListener {
// TODO: JWT 🔐 exact callbacks TBD
func onRequiresUserAuthChanged(from: Bool?, to: Bool?)
func onJwtInvalidated(externalId: String, error: String?)
func onJwtUpdated(externalId: String, jwtToken: String)
func onJwtTokenChanged(externalId: String, from: String?, to: String?)
}

public class OSUserJwtConfig {
public let changeNotifier = OSEventProducer<OSUserJwtConfigListener>()

private var requiresUserAuth: OSRequiresUserAuth {
didSet {
guard oldValue != requiresUserAuth else {
return
}

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

// Persist new value
OneSignalUserDefaults.initShared().saveString(forKey: OSUD_USE_IDENTITY_VERIFICATION, withValue: requiresUserAuth.rawValue)

self.changeNotifier.fire { listener in
listener.onRequiresUserAuthChanged(from: oldValue.isRequired(), to: requiresUserAuth.isRequired())
}
}
}

public var isRequired: Bool? {
get {
return requiresUserAuth.isRequired()
}
set {
requiresUserAuth = switch newValue {
case true:
OSRequiresUserAuth.on
case false:
OSRequiresUserAuth.off
default:
OSRequiresUserAuth.unknown
}
}
}

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

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

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

public func onJwtTokenChanged(externalId: String, from: String?, to: String?) {
if to == "invalid" {
changeNotifier.fire { listener in
listener.onJwtInvalidated(externalId: externalId, error: nil)
}
}
}
}
30 changes: 30 additions & 0 deletions iOS_SDK/OneSignalSDK/OneSignalOSCore/Source/OSLoggable.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
Modified MIT License

Copyright 2024 OneSignal

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

1. The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

2. All copies of substantial portions of the Software may only be used in connection
with services provided by OneSignal.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

public protocol OSLoggable {
func logSelf()
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import OneSignalCore
/**
Concrete executors drop OSDeltas and Requests when initializing from the cache, when they cannot be connected to their respective models anymore. These cannot be sent, so they are dropped..
*/
public protocol OSOperationExecutor {
public protocol OSOperationExecutor: OSLoggable {
var supportedDeltas: [String] { get }
var deltaQueue: [OSDelta] { get }

Expand Down
Loading
Loading