Skip to content
This repository has been archived by the owner on Apr 17, 2023. It is now read-only.

Commit

Permalink
Merge pull request #379 from danielpassos/AEROGEAR-9230
Browse files Browse the repository at this point in the history
Add push unregister
  • Loading branch information
Daniel Passos authored Jun 24, 2019
2 parents c279617 + b2d6d91 commit ac41fb8
Show file tree
Hide file tree
Showing 2 changed files with 151 additions and 76 deletions.
203 changes: 127 additions & 76 deletions packages/push/src/PushRegistration.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import { isCordovaAndroid, isCordovaIOS, ServiceConfiguration, ConfigurationService } from "@aerogear/core";
import axios from "axios";
import {
ConfigurationService,
isCordovaAndroid,
isCordovaIOS
} from "@aerogear/core";
import axios, { AxiosInstance } from "axios";

declare var window: any;

Expand All @@ -15,15 +19,85 @@ declare var window: any;
export class PushRegistration {

public static readonly TYPE: string = "push";
public static readonly API_PATH: string = "rest/registry/device";

private readonly pushConfig?: ServiceConfiguration;
private _objectInstance: any;
private static readonly API_PATH: string = "rest/registry/device";
private static readonly TOKEN_KEY = "UPS_DEVICE_TOKEN";

private readonly validationError?: string;
private readonly variantId?: string;
private readonly httpClient?: AxiosInstance;
private readonly push?: any;

constructor(config: ConfigurationService) {
const configuration = config.getConfigByType(PushRegistration.TYPE);

if (configuration && configuration.length > 0) {
this.pushConfig = configuration[0];
const pushConfig = configuration[0];

if (!window || !window.device || !window.PushNotification) {
const errorMessage = "@aerogear/cordova-plugin-aerogear-push plugin not installed.";
this.validationError = errorMessage;
console.warn(errorMessage);
}

if (!pushConfig || !pushConfig.config) {
const errorMessage = "UnifiedPush server configuration not found";
this.validationError = errorMessage;
console.warn(errorMessage);
}

const unifiedPushServerURL = pushConfig.url;
if (!pushConfig.url) {
const errorMessage = "UnifiedPush server URL not found";
this.validationError = errorMessage;
console.warn(errorMessage);
}

let platformConfig;
if (isCordovaAndroid()) {
platformConfig = pushConfig.config.android;
} else if (isCordovaIOS()) {
platformConfig = pushConfig.config.ios;
} else {
const errorMessage = "Platform is not supported by UnifiedPush";
this.validationError = errorMessage;
console.warn(errorMessage);
}

this.variantId = platformConfig.variantId || platformConfig.variantID;
if (!this.variantId) {
const errorMessage = "UnifiedPush VariantId is not defined";
this.validationError = errorMessage;
console.warn(errorMessage);
}

const variantSecret = platformConfig.variantSecret;
if (!variantSecret) {
const errorMessage = "UnifiedPush VariantSecret is not defined";
this.validationError = errorMessage;
console.warn(errorMessage);
}

if (!this.validationError) {
const token = window.btoa(`${this.variantId}:${variantSecret}`);
this.httpClient = axios.create({
baseURL: unifiedPushServerURL,
timeout: 5000,
headers: {"Authorization": `Basic ${token}`}
});

this.push = window.PushNotification.init(
{
android: {},
ios: {
alert: true,
badge: true,
sound: true
}
}
);
}

} else {
console.warn("Push configuration is missing. UPS server registration will not work.");
}
Expand All @@ -37,56 +111,15 @@ export class PushRegistration {
* @param categories array list of categories that device should be register to.
*/
public register(deviceToken: string, alias: string = "", categories: string[] = []): Promise<void> {
if (!window || !window.device || !window.PushNotification) {
return Promise.reject(new Error("Registration requires cordova plugin. Verify the " +
"@aerogear/cordova-plugin-aerogear-push plugin is installed."));
}

if (!this.pushConfig || !this.pushConfig.config || !this.pushConfig.url) {
return Promise.reject(new Error("UPS registration: configuration is invalid"));
}

if (!deviceToken) {
return Promise.reject(new Error("Device token should not be empty"));
}

let platformConfig;
const url = this.pushConfig.url;
if (isCordovaAndroid()) {
platformConfig = this.pushConfig.config.android;
} else if (isCordovaIOS()) {
platformConfig = this.pushConfig.config.ios;
} else {
return Promise.reject(new Error("UPS registration: Platform is not supported."));
}

if (!platformConfig) {
return Promise.reject(new Error("UPS registration: Platform is configured." +
"Please add UPS variant and generate mobile - config.json again"));
if (this.validationError) {
return Promise.reject(new Error(this.validationError));
}

const variantId = platformConfig.variantId || platformConfig.variantID;
if (!variantId) {
return Promise.reject(new Error("UPS registration: variantId is not defined."));
}

const variantSecret = platformConfig.variantSecret;
if (!variantSecret) {
return Promise.reject(new Error("UPS registration: variantSecret is not defined."));
}

this._objectInstance = window.PushNotification.init(
{
android: {},
ios: {
alert: true,
badge: true,
sound: true
}
}
);

const authToken = window.btoa(`${variantId}:${variantSecret}`);
const postData = {
"deviceToken": deviceToken,
"deviceType": window.device.model,
Expand All @@ -96,45 +129,63 @@ export class PushRegistration {
"categories": categories
};

const instance = axios.create({
baseURL: url,
timeout: 5000,
headers: {"Authorization": `Basic ${authToken}`}
});

return new Promise((resolve, reject) => {
return instance.post(PushRegistration.API_PATH, postData)
.then(
() => {
if (isCordovaAndroid()) {
this.subscribeToFirebaseTopic(variantId);
for (const category of categories) {
this.subscribeToFirebaseTopic(category);
if (this.httpClient) {
return this.httpClient.post(PushRegistration.API_PATH, postData)
.then(
() => {
const storage = window.localStorage;
storage.setItem(PushRegistration.TOKEN_KEY, deviceToken);

if (isCordovaAndroid() && this.variantId) {
this.subscribeToFirebaseTopic(this.variantId);
for (const category of categories) {
this.subscribeToFirebaseTopic(category);
}
}

resolve();
}
resolve();
}
)
.catch(reject);
)
.catch(reject);
} else {
// It should never happend but...
return Promise.reject(new Error("Push is not properly configured"));
}
});
}

/**
* Return the config used for the push service
* Unregister device for Android or IOS platforms
*/
public getConfig(): ServiceConfiguration | undefined {
return this.pushConfig;
}
public unregister(): Promise<void> {

/**
* Return true if config is present
*/
public hasConfig(): boolean {
return !!this.pushConfig;
const storage = window.localStorage;
const deviceToken = storage.getItem(PushRegistration.TOKEN_KEY);

if (!deviceToken) {
return Promise.reject(new Error("Device token should not be empty"));
}

if (this.validationError) {
return Promise.reject(new Error(this.validationError));
}

return new Promise((resolve, reject) => {
if (this.httpClient) {
const endpoint = PushRegistration.API_PATH + "/" + deviceToken;
return this.httpClient.delete(endpoint, {})
.then(() => resolve())
.catch(reject);
} else {
// It should never happend but...
return Promise.reject(new Error("Push is not properly configured"));
}
});
}

private subscribeToFirebaseTopic(topic: string) {
this._objectInstance.subscribe(
this.push.subscribe(
topic,
() => {
console.warn("FCM topic: " + topic + " subscribed");
Expand Down
24 changes: 24 additions & 0 deletions packages/push/test/PushRegistrationTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ declare var global: any;

global.window = { btoa: () => "dGVzdA==" };
global.window.PushNotification = { init: () => "" };
global.window.localStorage = { setItem: () => "" };
window.device = { platform: "iOS" };

describe("Registration tests", () => {
Expand Down Expand Up @@ -52,4 +53,27 @@ describe("Registration tests", () => {
}
});
});

describe("#unregister", async () => {
it("should fail to unregister in push server", async () => {
try {
await registration.unregister();
assert.fail();
} catch (_) {
return "ok";
}
});

it("should unregister in push server", async function() {
// in CI environment this test sometimes fails because of the default timeout 2s
// increase timeout to 10s
this.timeout(10000);
try {
global.window.localStorage = { getItem: () => "deviceToken" };
await registration.unregister();
} catch (error) {
assert.fail(error);
}
});
});
});

0 comments on commit ac41fb8

Please sign in to comment.