@@ -39,12 +39,15 @@ export class SafariClient extends BaseClient {
3939
4040 async _detectSubscriptionChange ( ) {
4141 const storedToken = await this . _deviceStateStore . getToken ( ) ;
42- const actualToken = getDeviceToken ( this . _websitePushId ) ;
42+ const { deviceToken : actualToken } = getCurrentPermission (
43+ this . _websitePushId
44+ ) ;
4345
4446 const tokenHasChanged = storedToken !== actualToken ;
4547 if ( tokenHasChanged ) {
46- // The device token has changed. This is should only really happen when
47- // users restore from an iCloud backup
48+ // The device token has changed. This could be because the user has
49+ // rescinded permission, or because the user has restored from a backup.
50+ // Either way we should clear out the old state
4851 await this . _deviceStateStore . clear ( ) ;
4952 this . _deviceId = null ;
5053 this . _token = null ;
@@ -53,6 +56,12 @@ export class SafariClient extends BaseClient {
5356 }
5457
5558 _requestPermission ( ) {
59+ // Check to see whether we've already asked for permission, if we have we
60+ // can't ask again
61+ let { deviceToken, permission } = getCurrentPermission ( this . _websitePushId ) ;
62+ if ( permission !== 'default' ) {
63+ return Promise . resolve ( { deviceToken, permission } ) ;
64+ }
5665 return new Promise ( resolve => {
5766 window . safari . pushNotification . requestPermission (
5867 this . _serviceUrl ,
@@ -70,34 +79,27 @@ export class SafariClient extends BaseClient {
7079 return this ;
7180 }
7281
73- let { permission } = getPermission ( this . _websitePushId ) ;
74-
75- if ( permission === 'default' ) {
76- console . debug ( 'permission is default, requesting permission' ) ;
77- let { deviceToken, permission } = await this . _requestPermission (
82+ let { deviceToken, permission } = await this . _requestPermission ( ) ;
83+ if ( permission == 'granted' ) {
84+ const deviceId = await this . _registerDevice (
85+ deviceToken ,
7886 this . _websitePushId
7987 ) ;
80- if ( permission == 'granted' ) {
81- const deviceId = await this . _registerDevice (
82- deviceToken ,
83- this . _websitePushId
84- ) ;
85- await this . _deviceStateStore . setToken ( deviceToken ) ;
86- await this . _deviceStateStore . setDeviceId ( deviceId ) ;
87- await this . _deviceStateStore . setLastSeenSdkVersion ( sdkVersion ) ;
88- await this . _deviceStateStore . setLastSeenUserAgent (
89- window . navigator . userAgent
90- ) ;
91- this . _token = deviceToken ;
92- this . _deviceId = deviceId ;
93- }
88+ await this . _deviceStateStore . setToken ( deviceToken ) ;
89+ await this . _deviceStateStore . setDeviceId ( deviceId ) ;
90+ await this . _deviceStateStore . setLastSeenSdkVersion ( sdkVersion ) ;
91+ await this . _deviceStateStore . setLastSeenUserAgent (
92+ window . navigator . userAgent
93+ ) ;
94+ this . _token = deviceToken ;
95+ this . _deviceId = deviceId ;
9496 }
9597 }
9698
9799 async getRegistrationState ( ) {
98100 await this . _resolveSDKState ( ) ;
99101
100- const { permission } = getPermission ( this . _websitePushId ) ;
102+ const { permission } = getCurrentPermission ( this . _websitePushId ) ;
101103
102104 if ( permission === 'denied' ) {
103105 return RegistrationState . PERMISSION_DENIED ;
@@ -115,15 +117,16 @@ export class SafariClient extends BaseClient {
115117 }
116118
117119 async clearAllState ( ) {
118- // TODO we can only call start() in a user gesture so this may not work in
119- // safari, can't we clear the state another way
120- throw new Error ( 'Not implemented' ) ;
121- // if (!this._isSupportedBrowser()) {
122- // return;
123- // }
124-
125- // await this.stop();
126- // await this.start();
120+ if ( ! this . _isSupportedBrowser ( ) ) {
121+ return ;
122+ }
123+
124+ await this . _deleteDevice ( ) ;
125+ await this . _deviceStateStore . clear ( ) ;
126+
127+ this . _deviceId = null ;
128+ this . _token = null ;
129+ this . _userId = null ;
127130 }
128131
129132 async stop ( ) {
@@ -136,14 +139,7 @@ export class SafariClient extends BaseClient {
136139 if ( this . _deviceId === null ) {
137140 return ;
138141 }
139-
140- await this . _deleteDevice ( ) ;
141- await this . _deviceStateStore . clear ( ) ;
142- this . _clearPushToken ( ) . catch ( ( ) => { } ) ; // Not awaiting this, best effort.
143-
144- this . _deviceId = null ;
145- this . _token = null ;
146- this . _userId = null ;
142+ await this . clearAllState ( ) ;
147143 }
148144
149145 async _registerDevice ( token , websitePushId ) {
@@ -167,12 +163,6 @@ export class SafariClient extends BaseClient {
167163 }
168164}
169165
170- function getPermission ( pushId ) {
171- return window . safari . pushNotification . permission ( pushId ) ;
172- }
173- function getDeviceToken ( websitePushId ) {
174- const { deviceToken } = window . safari . pushNotification . permission (
175- websitePushId
176- ) ;
177- return deviceToken ;
166+ function getCurrentPermission ( websitePushId ) {
167+ return window . safari . pushNotification . permission ( websitePushId ) ;
178168}
0 commit comments