Skip to content

Commit

Permalink
feat: #1 port to typescript
Browse files Browse the repository at this point in the history
  • Loading branch information
Patrick Ammann committed Jul 14, 2021
1 parent 1e0f990 commit 3a84c11
Show file tree
Hide file tree
Showing 54 changed files with 1,074 additions and 627 deletions.
23 changes: 14 additions & 9 deletions src/AccessTokenEvents.js → src/AccessTokenEvents.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,30 @@
// Copyright (c) Brock Allen & Dominick Baier. All rights reserved.
// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.

import { Log } from './Log.js';
import { Timer } from './Timer.js';
import { Log } from './Log';
import { Timer } from './Timer';
import { User } from './User';

const DefaultAccessTokenExpiringNotificationTime = 60; // seconds

export type AccessTokenCallback = (...ev: any[]) => void;

export class AccessTokenEvents {
private _accessTokenExpiringNotificationTime: number
private _accessTokenExpiring: Timer
private _accessTokenExpired: Timer

constructor({
accessTokenExpiringNotificationTime = DefaultAccessTokenExpiringNotificationTime,
accessTokenExpiringTimer = new Timer("Access token expiring"),
accessTokenExpiredTimer = new Timer("Access token expired")
} = {}) {
this._accessTokenExpiringNotificationTime = accessTokenExpiringNotificationTime;

this._accessTokenExpiring = accessTokenExpiringTimer;
this._accessTokenExpired = accessTokenExpiredTimer;
}

load(container) {
load(container: User) {
// only register events if there's an access token and it has an expiration
if (container.access_token && container.expires_in !== undefined) {
let duration = container.expires_in;
Expand All @@ -31,7 +36,7 @@ export class AccessTokenEvents {
if (expiring <= 0){
expiring = 1;
}

Log.debug("AccessTokenEvents.load: registering expiring timer in:", expiring);
this._accessTokenExpiring.init(expiring);
}
Expand All @@ -57,17 +62,17 @@ export class AccessTokenEvents {
this._accessTokenExpired.cancel();
}

addAccessTokenExpiring(cb) {
addAccessTokenExpiring(cb: AccessTokenCallback) {
this._accessTokenExpiring.addHandler(cb);
}
removeAccessTokenExpiring(cb) {
removeAccessTokenExpiring(cb: AccessTokenCallback) {
this._accessTokenExpiring.removeHandler(cb);
}

addAccessTokenExpired(cb) {
addAccessTokenExpired(cb: AccessTokenCallback) {
this._accessTokenExpired.addHandler(cb);
}
removeAccessTokenExpired(cb) {
removeAccessTokenExpired(cb: AccessTokenCallback) {
this._accessTokenExpired.removeHandler(cb);
}
}
38 changes: 27 additions & 11 deletions src/CheckSessionIFrame.js → src/CheckSessionIFrame.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,26 @@
// Copyright (c) Brock Allen & Dominick Baier. All rights reserved.
// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.

import { Log } from './Log.js';
import { Log } from './Log';

const DefaultInterval = 2000;

export class CheckSessionIFrame {
constructor(callback, client_id, url, interval, stopOnError = true) {
private _callback: () => void;
private _client_id: string;
private _interval: number;
private _stopOnError: boolean;
private _frame_origin: string;
private _frame: HTMLIFrameElement;
private _boundMessageEvent: ((e: any) => void) | null;
private _timer: number | null;
private _session_state: any | null;

constructor(callback: () => void, client_id: string, url: string, interval?: number, stopOnError?: boolean) {
this._callback = callback;
this._client_id = client_id;
this._url = url;
this._interval = interval || DefaultInterval;
this._stopOnError = stopOnError;
this._stopOnError = stopOnError || true;

var idx = url.indexOf("/", url.indexOf("//") + 2);
this._frame_origin = url.substr(0, idx);
Expand All @@ -22,13 +31,17 @@ export class CheckSessionIFrame {
this._frame.style.visibility = "hidden";
this._frame.style.position = "absolute";
this._frame.style.display = "none";
this._frame.width = 0;
this._frame.height = 0;

this._frame.width = "0";
this._frame.height = "0";
this._frame.src = url;

this._boundMessageEvent = null;
this._timer = null;

}

load() {
return new Promise((resolve) => {
return new Promise<void>((resolve) => {
this._frame.onload = () => {
resolve();
}
Expand All @@ -38,7 +51,8 @@ export class CheckSessionIFrame {
window.addEventListener("message", this._boundMessageEvent, false);
});
}
_message(e) {

_message(e: any) {
if (e.origin === this._frame_origin &&
e.source === this._frame.contentWindow
) {
Expand All @@ -58,7 +72,8 @@ export class CheckSessionIFrame {
}
}
}
start(session_state) {

start(session_state: any) {
if (this._session_state !== session_state) {
Log.debug("CheckSessionIFrame.start");

Expand All @@ -67,9 +82,10 @@ export class CheckSessionIFrame {
this._session_state = session_state;

let send = () => {
this._frame.contentWindow &&
this._frame.contentWindow.postMessage(this._client_id + " " + this._session_state, this._frame_origin);
};

// trigger now
send();

Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
// Copyright (c) Brock Allen & Dominick Baier. All rights reserved.
// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.

import { CordovaPopupWindow } from './CordovaPopupWindow.js';
import { CordovaPopupWindow } from './CordovaPopupWindow';
import { INavigator } from './INavigator';

export class CordovaIFrameNavigator {
export class CordovaIFrameNavigator implements INavigator {

prepare(params) {
prepare(params: any) {
params.popupWindowFeatures = 'hidden=yes';
let popup = new CordovaPopupWindow(params);
return Promise.resolve(popup);
Expand Down
7 changes: 4 additions & 3 deletions src/CordovaPopupNavigator.js → src/CordovaPopupNavigator.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
// Copyright (c) Brock Allen & Dominick Baier. All rights reserved.
// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.

import { CordovaPopupWindow } from './CordovaPopupWindow.js';
import { CordovaPopupWindow } from './CordovaPopupWindow';
import { INavigator } from './INavigator';

export class CordovaPopupNavigator {
export class CordovaPopupNavigator implements INavigator {

prepare(params) {
prepare(params: any) {
let popup = new CordovaPopupWindow(params);
return Promise.resolve(popup);
}
Expand Down
56 changes: 36 additions & 20 deletions src/CordovaPopupWindow.js → src/CordovaPopupWindow.ts
Original file line number Diff line number Diff line change
@@ -1,51 +1,67 @@
// Copyright (c) Brock Allen & Dominick Baier. All rights reserved.
// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.

import { Log } from './Log.js';
import { Log } from './Log';
import { IWindow } from './IWindow';

const DefaultPopupFeatures = 'location=no,toolbar=no,zoom=no';
const DefaultPopupTarget = "_blank";

export class CordovaPopupWindow {
export class CordovaPopupWindow implements IWindow {
private _promise: Promise<unknown>;
private _resolve!: (value: unknown) => void;
private _reject!: (reason?: any) => void;
private features: string;
private target: string;
private redirect_uri: string;
private _popup: any;
private _exitCallbackEvent?: (message: any) => void;
private _loadStartCallbackEvent?: (event: any) => void;

constructor(params) {
constructor(params: any) {
this._promise = new Promise((resolve, reject) => {
this._resolve = resolve;
this._reject = reject;
});

this.features = params.popupWindowFeatures || DefaultPopupFeatures;
this.target = params.popupWindowTarget || DefaultPopupTarget;

this.redirect_uri = params.startUrl;
Log.debug("CordovaPopupWindow.ctor: redirect_uri: " + this.redirect_uri);
}

_isInAppBrowserInstalled(cordovaMetadata) {
_isInAppBrowserInstalled(cordovaMetadata: any) {
return ["cordova-plugin-inappbrowser", "cordova-plugin-inappbrowser.inappbrowser", "org.apache.cordova.inappbrowser"].some(function (name) {
return cordovaMetadata.hasOwnProperty(name)
})
}
navigate(params) {

navigate(params: any) {
if (!params || !params.url) {
this._error("No url provided");
} else {
// @ts-ignore
if (!window.cordova) {
return this._error("cordova is undefined")
this._error("cordova is undefined");
return this.promise;
}


// @ts-ignore
var cordovaMetadata = window.cordova.require("cordova/plugin_list").metadata;
if (this._isInAppBrowserInstalled(cordovaMetadata) === false) {
return this._error("InAppBrowser plugin not found")
this._error("InAppBrowser plugin not found");
return this.promise;
}

// @ts-ignore
this._popup = cordova.InAppBrowser.open(params.url, this.target, this.features);
if (this._popup) {
Log.debug("CordovaPopupWindow.navigate: popup successfully created");
this._exitCallbackEvent = this._exitCallback.bind(this);

this._exitCallbackEvent = this._exitCallback.bind(this);
this._loadStartCallbackEvent = this._loadStartCallback.bind(this);

this._popup.addEventListener("exit", this._exitCallbackEvent, false);
this._popup.addEventListener("loadstart", this._loadStartCallbackEvent, false);
} else {
Expand All @@ -59,22 +75,22 @@ export class CordovaPopupWindow {
return this._promise;
}

_loadStartCallback(event) {
_loadStartCallback(event: any) {
if (event.url.indexOf(this.redirect_uri) === 0) {
this._success({ url: event.url });
}
}
}
_exitCallback(message) {
this._error(message);
_exitCallback(message: string) {
this._error(message);
}
_success(data) {

_success(data: any) {
this._cleanup();

Log.debug("CordovaPopupWindow: Successful response from cordova popup window");
this._resolve(data);
}
_error(message) {
_error(message: string) {
this._cleanup();

Log.error(message);
Expand Down
18 changes: 14 additions & 4 deletions src/ErrorResponse.js → src/ErrorResponse.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,22 @@
// Copyright (c) Brock Allen & Dominick Baier. All rights reserved.
// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.

import { Log } from './Log.js';
import { Log } from './Log';

export class ErrorResponse extends Error {
constructor({error, error_description, error_uri, state, session_state}={}
) {
if (!error){
public readonly name: string;

public readonly error: string;
public readonly error_description: string;
public readonly error_uri: string;

public readonly state: any;
public readonly session_state?: string;

constructor({
error, error_description, error_uri, state, session_state
}: any) {
if (!error) {
Log.error("No error passed to ErrorResponse");
throw new Error("error");
}
Expand Down
12 changes: 7 additions & 5 deletions src/Event.js → src/Event.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,29 @@
// Copyright (c) Brock Allen & Dominick Baier. All rights reserved.
// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.

import { Log } from './Log.js';
import { Log } from './Log';

export class Event {
protected _name: string;
private _callbacks: ((...ev: any[]) => void)[];

constructor(name) {
constructor(name: string) {
this._name = name;
this._callbacks = [];
}

addHandler(cb) {
addHandler(cb: (...ev: any[]) => void) {
this._callbacks.push(cb);
}

removeHandler(cb) {
removeHandler(cb: (...ev: any[]) => void) {
var idx = this._callbacks.findIndex(item => item === cb);
if (idx >= 0) {
this._callbacks.splice(idx, 1);
}
}

raise(...params) {
raise(...params: any[]) {
Log.debug("Event: Raising event: " + this._name);
for (let i = 0; i < this._callbacks.length; i++) {
this._callbacks[i](...params);
Expand Down
Loading

0 comments on commit 3a84c11

Please sign in to comment.