UNPKG

globular-mvc

Version:

Generic template to create web-application that made use of globular as backend and materialize as css (wrap in web-component's)

413 lines (342 loc) 14.3 kB
// Globular conneciton. import * as GlobularWebClient from "globular-web-client"; import { getAllPeersInfo } from "globular-web-client/api"; import { GeneratePeerTokenRequest } from "globular-web-client/authentication/authentication_pb"; import { Peer } from "globular-web-client/resource/resource_pb"; import { formatBoolean } from "./components/utility"; import { View } from "./View"; // Keep the token in the map... let tokens: any = {} /** * Return the globule url. * @param globule * @param callback * @param errorCallback */ export function getUrl(globule: GlobularWebClient.Globular): string { // set the url for the image. let url = globule.config.Protocol + "://" + globule.domain if (window.location.hostname != globule.domain) { // if no peers has the address at windows location I will test if is an alternate domain, if so I will keep the alternate domain. if (globule.config.Peers.filter((p) => { return p.Domain === window.location.hostname; }).length == 0) { if (globule.config.AlternateDomains.indexOf(window.location.host) != -1) { // keep the given url... url = globule.config.Protocol + "://" + window.location.host } } } if (globule.config.Protocol == "https") { if (globule.config.PortHttps != 443) url += ":" + globule.config.PortHttps } else { if (globule.config.PortHttps != 80) url += ":" + globule.config.PortHttp } return url } /** * * @param {*} globule The globule * @param {*} callback The callback * @param {*} errorCallback */ export function generatePeerToken(globule: GlobularWebClient.Globular, callback: (token: string) => void, errorCallback: (err: any) => void) { if (!globule) { errorCallback("the globule was not initialyse") return } let mac = globule.config.Mac if (Model.globular.config.Mac == mac) { callback(localStorage.getItem("user_token")) return } if (tokens[mac]) { callback(tokens[mac]) return } let rqst = new GeneratePeerTokenRequest rqst.setMac(mac) Model.globular.authenticationService.generatePeerToken(rqst, { domain: Model.domain, application: Model.application, address: Model.address, token: localStorage.getItem("user_token") }) .then(rsp => { let token = rsp.getToken() tokens[mac] = token setTimeout(() => { delete tokens[mac] }, (globule.config.SessionTimeout * 60 * 1000) - 15000) // remove the token before it get invalid... callback(token) }) .catch(errorCallback) } export class Model { protected listeners: Array<any>; // Here I will keep list of connected globules... public static globules: Map<string, GlobularWebClient.Globular> // That function will return a public static getGlobule(address: string): GlobularWebClient.Globular { if(address == "localhost"){ return Model.globular; } return Model.globules.get(address); } public static getGlobules(): Array<GlobularWebClient.Globular> { let connections_ = Array.from(Model.globules.values()) let connections = new Array<GlobularWebClient.Globular>() // Remove duplicat connections_.forEach(c => { if (connections.filter(c_ => { return c.config.Name == c_.config.Name && c_.config.Domain == c_.config.Domain; }).length == 0) { connections.push(c) } }) return connections } // This is the globule where the application is running. private static _globular: GlobularWebClient.Globular; public static get globular(): GlobularWebClient.Globular { return Model.getGlobule(Model.address); } // This is the event controller. public static eventHub: GlobularWebClient.EventHub; // The domain of the application. public static domain: string; // The address... public static address: string; // The application name. public static application: string; // Pulish event on all globules... public static publish(name: string, data: any, local: boolean): void { let globules = Model.getGlobules() globules.forEach(g => { g.eventHub.publish(name, data, local) }) } // The view. private _view: View; protected get view(): View { return this._view; } protected set view(value: View) { this._view = value; } constructor() { // Set the application name. // The domain will be set with the hostname. if (window.location.protocol != "files:") { Model.domain = window.location.hostname Model.address = Model.domain + ":" + window.location.port if (Model.address.endsWith(":")) { if (window.location.protocol.toLocaleLowerCase() == "https:") { Model.address += "443" } else { Model.address += "80" } } } this.listeners = new Array<any>(); } // Append a listener. appendListener(name: string, uuid: string) { this.listeners.push({ name: name, uuid: uuid }) } // Explicitly close the view. close() { // Close all listeners. this.listeners.forEach((listener: any) => { Model.eventHub.unSubscribe(listener.name, listener.uuid) }) } /** * Return the json string of the class. That will be use to save user data into the database. */ toString(): string { return JSON.stringify(this) } /** * Set the view. * @param view */ setView(view: View) { this.view = view; } /** * Initialyse model from json object. * @param json The class data. */ static fromString(json: string): any { } /** * Initialyse the notification from object. * @param obj */ static fromObject(obj: any): any { } /** * Initialyse the peer. * @param peer The peer to initialyse * @param callback The success callback * @param errorCallback The error callback */ initPeer(peer: Peer, callback: () => void, errorCallback: (err: any) => void) { let port = 80 if (Model._globular.config.Protocol == "https") { port = 443 if (peer.getProtocol() == "https") { port = peer.getPorthttps() } } else { port = peer.getPorthttps() } let url = Model._globular.config.Protocol + "://" + peer.getDomain() + ":" + port + "/config" let globule = new GlobularWebClient.Globular(url, () => { // append the globule to the list. Model.globules.set(Model._globular.config.Protocol + "://" + peer.getDomain() + ":" + port, globule) Model.globules.set(url, globule) Model.globules.set(peer.getDomain(), globule) Model.globules.set(peer.getMac(), globule) callback() }, (err: any) => { console.log(err) errorCallback(err) }) } /** * Remove the peer from the list of active globule. * @param peer */ removePeer(peer: Peer) { let port = 80 if (Model._globular.config.Protocol == "https") { port = 443 if (peer.getProtocol() == "https") { port = peer.getPorthttps() } } else { port = peer.getPorthttps() } let url = Model._globular.config.Protocol + "://" + peer.getDomain() + ":" + port + "/config" // append the globule to the list. Model.globules.delete(Model._globular.config.Protocol + "://" + peer.getDomain() + ":" + port) Model.globules.delete(url) Model.globules.delete(peer.getDomain()) Model.globules.delete(peer.getMac()) } /** * Connect with the backend and get the initial configuration. * @param initCallback On success callback * @param errorCallback On error callback * @param adminPort The admin service port * @param adminProxy The admin service proxy */ init(url: string, initCallback: () => void, errorCallback: (err: any) => void) { // So here I will initilyse the server connection. Model._globular = new GlobularWebClient.Globular(url, () => { // set the event hub. Model.eventHub = Model._globular.eventHub; Model.eventHub.subscribe("start_peer_evt", uuid => { }, evt => { let obj = JSON.parse(evt) let peer = new Peer peer.setDomain(obj.domain) peer.setHostname(obj.hostname) peer.setMac(obj.mac) peer.setPorthttp(obj.portHttp) peer.setPorthttps(obj.portHttps) this.initPeer(peer, () => { // dispatch the event locally... Model.eventHub.publish("start_peer_evt_", peer, true) }, err => console.log(err)) }, false) Model.eventHub.subscribe("stop_peer_evt", uuid => { }, evt => { let obj = JSON.parse(evt) let peer = new Peer peer.setDomain(obj.domain) peer.setHostname(obj.hostname) peer.setMac(obj.mac) peer.setPorthttp(obj.portHttp) peer.setPorthttps(obj.portHttps) // remove the peer from the map. this.removePeer(peer) Model.eventHub.publish("stop_peer_evt_", peer, true) }, false) // If a new peers is connected... Model.eventHub.subscribe("update_peers_evt", uuid => { }, evt => { let obj = JSON.parse(evt) if (obj) { let peer = new Peer peer.setDomain(obj.domain) peer.setHostname(obj.hostname) peer.setMac(obj.mac) peer.setPorthttp(obj.portHttp) peer.setPorthttps(obj.portHttps) let actions = new Array<string>() if (obj.actions) { obj.actions.forEach((a: string) => { actions.push(a) }) } peer.setActionsList(actions) this.initPeer(peer, () => { // dispatch the event locally... Model.eventHub.publish("update_peers_evt_", peer, true) }, err => console.log(err)) } else { console.log("fail to parse ", evt) } }, false) // So here I will create connection to peers know by globular... Model.globules = new Map<string, GlobularWebClient.Globular>(); Model.globules.set(Model.address, Model._globular) Model.domain = Model._globular.domain; Model.globules.set(Model.domain, Model._globular) Model.globules.set(Model.domain + ":" + Model._globular.config.PortHttp, Model._globular) Model.globules.set(Model.domain + ":" + Model._globular.config.PortHttps, Model._globular) Model.globules.set(Model._globular.config.Mac, Model._globular) // I will also set the globule to other address... Model._globular.config.AlternateDomains.forEach(alternateDomain => { // I will set alternate domain only if no peer has it domain. if (Model._globular.config.Peers.filter((p) => { return p.Domain === alternateDomain; }).length == 0) { Model.globules.set(alternateDomain, Model._globular) let address = alternateDomain + ":" + window.location.port if (address.endsWith(":")) { if (Model._globular.config.Protocol == "https") { address += "443" } else { address += "80" } } Model.globules.set(address, Model._globular) } }); // Retreive peer's infos and register peers. getAllPeersInfo(Model.globular, (peers: Peer[]) => { let index = 0; let connectToPeers = () => { let peer = peers[index] if (index < peers.length) { index++ this.initPeer(peer, () => { if (index < peers.length) { connectToPeers() } else { initCallback(); } }, err => { console.log(err) if (index < peers.length) { connectToPeers() } else { initCallback(); } }) } else { initCallback(); } } // call onces connectToPeers() }, (err: any) => { initCallback(); }); }, err => { console.log(err); errorCallback(err); }); } }