Skip to content
Open
8 changes: 8 additions & 0 deletions configs/app.base.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,14 @@
"metrics": {
"record": "gpii.app.metrics",
"target": "{/ gpii.metrics}.options.gradeNames"
},
"linkRedirect": {
"record": {
"linkRedirect": {
"type": "gpii.app.linkRedirect"
}
},
"target": "{/ gpii.flowManager.local}.options.components"
}
}
}
Expand Down
6 changes: 6 additions & 0 deletions siteconfig.json5
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@

alwaysUseChrome: false,

// The redirect url to open links by showing the tab if the link is already open in the browser. The encoded
// destination url is added to the end of this, or replaces `$1`. Normally, this value is
// "http://opensametab.morphic.org/redirect/", but it can be "http://refreshsametab.morphic.org/redirect/"
// to make the tab reload itself.
currentTabRedirect: "http://opensametab.morphic.org/redirect/",

// The template that is used for every label of the language setting's options.
// The "%" followed by a word specifies a variable and there are three possible variables:
// - native - the name of the language in its native form
Expand Down
1 change: 1 addition & 0 deletions src/main/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ require("./storage.js");
require("./tray.js");
require("./userErrorsHandler.js");
require("./metrics.js");
require("./linkRedirect.js");

// enhance the normal require to work with .json5 files
require("json5/lib/register");
Expand Down
74 changes: 74 additions & 0 deletions src/main/linkRedirect.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/**
* Handles link redirection.
*
* Copyright 2020 Raising the Floor - International
*
* Licensed under the New BSD license. You may not use this file except in
* compliance with this License.
*
* The R&D leading to these results received funding from the
* Department of Education - Grant H421A150005 (GPII-APCP). However,
* these results do not necessarily represent the policy of the
* Department of Education, and you should not assume endorsement by the
* Federal Government.
*
* You may obtain a copy of the License at
* https://github.com/GPII/gpii-app/blob/master/LICENSE.txt
*/

"use strict";

var fluid = require("infusion"),
URL = require("url").URL;

var gpii = fluid.registerNamespace("gpii");
fluid.registerNamespace("gpii.app.linkRedirect");

/**
* Handles /redirect, which redirects the browser to the provided url.
* This is a fall-back for the 'open link in existing tab' feature [GPII-4410], where the browser is opened with a
* special link which gets intercepted by a browser extension. The link really points to this handler, so it will
* still work with browsers that don't have the extension installed.
*/
fluid.defaults("gpii.app.linkRedirect", {
gradeNames: ["kettle.app"],
defaultRedirectUrl: "http://opensametab.morphic.org/redirect/$1",
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see where the "refreshsametab.morphic.org" urls are redirected. Is that in configuration somewhere?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

requestHandlers: {
handle: {
type: "gpii.app.linkRedirect.request",
route: "/redirect/:destination(.*)"
}
}
});

fluid.defaults("gpii.app.linkRedirect.request", {
gradeNames: ["kettle.request.http"],
invokers: {
handleRequest: {
funcName: "gpii.app.linkRedirect.handleRequest",
args: [
"{request}",
"{request}.req.params.destination"
]
}
}
});

/**
* Handler for /redirect. Redirects the browser to the given url.
*
* @param {Component} request The request object.
* @param {String} destination The destination URL.
*/
gpii.app.linkRedirect.handleRequest = function (request, destination) {
try {
// Make sure the url is valid before sending it out.
var url = new URL(destination);
request.res.status(301).redirect(url.href);
} catch (e) {
request.handlerPromise.reject({
statusCode: 400,
message: e.message
});
}
};
44 changes: 43 additions & 1 deletion src/main/siteConfigurationHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
*/
"use strict";

var fluid = require("infusion");
var fluid = require("infusion"),
URL = require("url").URL;

var gpii = fluid.registerNamespace("gpii");

Expand Down Expand Up @@ -111,6 +112,27 @@ fluid.defaults("gpii.app.siteConfigurationHandler", {
distributeMetrics: {
record: "{that}.options.siteConfig.metrics",
target: "{/ gpii.app.metrics}.options.siteConfig"
},
distributeQssConfigUrl: {
record: {
// Tweaks the redirect url so it's on the same port as the app.
expander: {
funcName: "gpii.app.siteConfigurationHandler.setUrlPort",
args: [
{
expander: {
funcName: "fluid.firstDefined",
args: [
"{that}.options.siteConfig.qss.currentTabRedirect",
"{gpii.app.linkRedirect}.options.defaultRedirectUrl"
]
}
},
"{kettle.server}.options.port"
]
}
},
target: "{that qssWrapper}.options.siteConfig.currentTabRedirect"
}
},

Expand Down Expand Up @@ -156,3 +178,23 @@ gpii.app.siteConfigurationHandler.requireFirst = function (files) {
}
return togo;
};

/**
* Sets the port value of a url.
* @param {String} url The url to update.
* @param {Number} port The new port number.
* @return {String} The url, with the updated port.
*/
gpii.app.siteConfigurationHandler.setUrlPort = function (url, port) {
var togo;
if (url) {
try {
var u = new URL(url);
u.port = port;
togo = u.href;
} catch (e) {
fluid.log(fluid.logLevel.WARN, "Unable to parse url '" + url + "' ", e.message);
}
}
return togo;
};
20 changes: 16 additions & 4 deletions src/renderer/common/js/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,28 +92,40 @@
* @param {String} siteUrl - cloud folder's url
* @param {Boolean} alwaysUseChrome - true to use chrome, rather than the default browser.
* @param {Boolean} forceFullScreen - the function requires the browser to be open maximized
* @param {String} redirectUrl - [optional] A url which will wrap `siteUrl`. This can be used to make a redirection
* url. Current use case is to make an extension open an existing tab. `siteUrl` is encoded and added to the end of
* this, or a placeholder of `$1` can be used.
*/
gpii.windows.openUrl = function (siteUrl, alwaysUseChrome, forceFullScreen) {
gpii.windows.openUrl = function (siteUrl, alwaysUseChrome, forceFullScreen, redirectUrl) {
if (fluid.isValue(siteUrl)) {
var finalUrl = siteUrl;

// Wrap the url in the opensametab
if (redirectUrl) {
finalUrl = redirectUrl.replace(/\$1|$/, encodeURIComponent(siteUrl));
}

fluid.log("Opening link", finalUrl);

if (alwaysUseChrome) {
var command =
// Check chrome is installed
"reg query \"HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\chrome.exe\" /ve"
// If so, run chrome
+ " && start chrome \"" + siteUrl.replace(/"/g, "%22") + "\"";
+ " && start chrome \"" + finalUrl.replace(/"/g, "%22") + "\"";
if (forceFullScreen) {
// adding the full screen option for Chrome as well
command += " --start-fullscreen";
}
child_process.exec(command, function (err) {
if (err) {
// It failed, so use the default browser.
shell.openExternal(siteUrl);
shell.openExternal(finalUrl);
}
});
} else {
// we have the url, opening it in the default browser
shell.openExternal(siteUrl);
shell.openExternal(finalUrl);
}
} else {
// there is no value in the config, sending the warning
Expand Down
9 changes: 9 additions & 0 deletions src/renderer/qss/js/qss.js
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,15 @@
updateIsKeyedIn: {
changePath: "isKeyedIn",
value: "{arguments}.0"
},
openUrl: {
funcName: "gpii.windows.openUrl",
args: [
"{arguments}.0", // siteUrl
"{arguments}.1", // alwaysUseChrome
"{arguments}.2", // forceFullScreen
"{that}.options.siteConfig.currentTabRedirect" // redirectUrl,
]
}
}
});
Expand Down
2 changes: 1 addition & 1 deletion src/renderer/qss/js/qssServiceButtons.js
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@
gradeNames: ["gpii.qss.buttonPresenter"],
invokers: {
activate: {
funcName: "gpii.windows.openUrl",
func: "{gpii.qss}.openUrl",
args: [
"{that}.model.item.schema.url", // using the url from the custom button's schema
true, // Override the OS default browser to always use Chrome instead
Expand Down