Skip to content
This repository has been archived by the owner on Mar 5, 2021. It is now read-only.

Commit

Permalink
Use HTTP basic auth for server auth, bump app API version to 5
Browse files Browse the repository at this point in the history
  • Loading branch information
elisee committed Mar 8, 2019
1 parent 661981d commit d6174de
Show file tree
Hide file tree
Showing 13 changed files with 92 additions and 118 deletions.
8 changes: 4 additions & 4 deletions public/locales/de/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,12 @@
"port": "Port",
"label": "Label",

"connecting": "Verbinde mit ${host}...",
"connecting": "Verbinde mit ${baseUrl}...",
"tryAgain": "Erneut versuchen",
"errors": {
"superpowersJSON": "${host}/superpowers.json konnte nicht heruntergeladen werden.",
"notSuperpowers": "Auf dem Server ${host} scheint keine Superpowers Instanz zu laufen.",
"incompatibleVersion": "Auf dem Server ${host} läuft eine inkompatible Version von Superpowers (App API Version ${serverVersion} gefunden, erwartet wird ${appVersion})."
"superpowersJSON": "${baseUrl}/superpowers.json konnte nicht heruntergeladen werden.",
"notSuperpowers": "Auf dem Server ${baseUrl} scheint keine Superpowers Instanz zu laufen.",
"incompatibleVersion": "Auf dem Server ${baseUrl} läuft eine inkompatible Version von Superpowers (App API Version ${serverVersion} gefunden, erwartet wird ${appVersion})."
}
}
}
12 changes: 6 additions & 6 deletions public/locales/en/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,15 @@
"hostname": "Hostname",
"port": "Port",
"label": "Label",
"httpUsername": "HTTP Username",
"httpPassword": "HTTP Password",
"password": "Password",

"connecting": "Connecting to ${host}...",
"connecting": "Connecting to ${baseUrl}...",
"tryAgain": "Try again",
"errors": {
"superpowersJSON": "Could not download ${host}/superpowers.json.",
"notSuperpowers": "The server at ${host} doesn't seem to be running Superpowers.",
"incompatibleVersion": "The server at ${host} runs an incompatible version of Superpowers (got app API version ${serverVersion}, expected ${appVersion})."
"superpowersJSON": "Could not download ${baseUrl}/superpowers.json.",
"incorrectPassword": "Wrong password for ${baseUrl}.",
"notSuperpowers": "The server at ${baseUrl} doesn't seem to be running Superpowers.",
"incompatibleVersion": "The server at ${baseUrl} runs an incompatible version of Superpowers (got app API version ${serverVersion}, expected ${appVersion})."
}
}
}
Expand Down
8 changes: 4 additions & 4 deletions public/locales/it/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,12 @@
"port": "Porta",
"label": "Etichetta",

"connecting": "Collegamento a ${host}...",
"connecting": "Collegamento a ${baseUrl}...",
"tryAgain": "Riprova",
"errors": {
"superpowersJSON": "Non è stato possibile scaricare ${host}/superpowers.json.",
"notSuperpowers": "Sembra che il server all'indirizzo ${host} non stia facendo girare Superpowers.",
"incompatibleVersion": "Il server all'indirizzo ${host} sta facendo girare una versione incompatibile di Superpowers (versione API ricevuta ${serverVersion}, prevista ${appVersion})."
"superpowersJSON": "Non è stato possibile scaricare ${baseUrl}/superpowers.json.",
"notSuperpowers": "Sembra che il server all'indirizzo ${baseUrl} non stia facendo girare Superpowers.",
"incompatibleVersion": "Il server all'indirizzo ${baseUrl} sta facendo girare una versione incompatibile di Superpowers (versione API ricevuta ${serverVersion}, prevista ${appVersion})."
}
}
}
8 changes: 4 additions & 4 deletions public/locales/ru/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@
"port": "Порт",
"label": "Название",

"connecting": "Подключение к ${host}...",
"connecting": "Подключение к ${baseUrl}...",
"tryAgain": "Попробовать снова",
"errors": {
"superpowersJSON": "Не получилось загрузить ${host}/superpowers.json.",
"notSuperpowers": "Похоже, на сервере ${host} не запущен Superpowers.",
"incompatibleVersion": "На сервере ${host} работает несовместимая версия Superpowers (запущено приложение с API версии ${serverVersion}, необходима ${appVersion})."
"superpowersJSON": "Не получилось загрузить ${baseUrl}/superpowers.json.",
"notSuperpowers": "Похоже, на сервере ${baseUrl} не запущен Superpowers.",
"incompatibleVersion": "На сервере ${baseUrl} работает несовместимая версия Superpowers (запущено приложение с API версии ${serverVersion}, необходима ${appVersion})."
}
}
}
2 changes: 1 addition & 1 deletion public/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@
"main": "main.js",
"superpowers": {
"electron": "4.0.7",
"appApiVersion": 4
"appApiVersion": 5
}
}
8 changes: 4 additions & 4 deletions src/SupApp/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ electron.ipcRenderer.on("check-path-authorization-callback", onPathAuthorization
type ChooseFolderCallback = (folder: string) => void;
type ChooseFileCallback = (filename: string) => void;
type AuthorizeFolderCallback = () => void;
type CheckPathAuthorizationCallback = (normalizedPath: string, access: "readWrite"|"execute") => void;
type CheckPathAuthorizationCallback = (normalizedPath: string, access: "readWrite" | "execute") => void;

interface OpenWindowOptions {
size?: { width: number; height: number; };
Expand Down Expand Up @@ -69,7 +69,7 @@ function checkPathAuthorization(pathToCheck: string, callback: CheckPathAuthoriz
electron.ipcRenderer.send("check-path-authorization", secretKey, ipcId, window.location.origin, pathToCheck);
}

function onPathAuthorizationChecked(event: Electron.Event, ipcId: string, checkedPath: string, authorization: "readWrite"|"execute") {
function onPathAuthorizationChecked(event: Electron.Event, ipcId: string, checkedPath: string, authorization: "readWrite" | "execute") {
const callback = ipcCallbacks[ipcId] as CheckPathAuthorizationCallback;
if (callback == null) return;
delete ipcCallbacks[ipcId];
Expand Down Expand Up @@ -143,13 +143,13 @@ namespace SupApp {
electron.ipcRenderer.send("choose-folder", secretKey, ipcId, window.location.origin);
}

export function chooseFile(access: "readWrite"|"execute", callback: ChooseFileCallback) {
export function chooseFile(access: "readWrite" | "execute", callback: ChooseFileCallback) {
const ipcId = getNextIpcId();
ipcCallbacks[ipcId] = callback;
electron.ipcRenderer.send("choose-file", secretKey, ipcId, window.location.origin, access);
}

export function tryFileAccess(filePath: string, access: "readWrite"|"execute", callback: (err: any) => void) {
export function tryFileAccess(filePath: string, access: "readWrite" | "execute", callback: (err: any) => void) {
checkPathAuthorization(filePath, (err, authorization) => {
if (authorization !== access) { callback(new Error("Unauthorized")); return; }

Expand Down
3 changes: 1 addition & 2 deletions src/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,5 @@ interface ServerEntry {
hostname: string;
port: string;
label: string;
httpUsername: string;
httpPassword: string;
password: string;
}
25 changes: 14 additions & 11 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import * as menu from "./menu";
import getPaths from "./getPaths";
import getLanguageCode from "./getLanguageCode";
import * as SupAppIPC from "./ipc";
import * as url from "url";

let corePath: string;
let userDataPath: string;
Expand Down Expand Up @@ -58,7 +59,7 @@ function onAppReady() {

getLanguageCode(userDataPath, (languageCode) => {
i18n.setLanguageCode(languageCode);
i18n.load([ "startup", "tray" ], () => {
i18n.load(["startup", "tray"], () => {
if (dataPathErr != null) {
electron.dialog.showErrorBox(i18n.t("startup:failedToStart"), i18n.t(dataPathErr.key, dataPathErr.variables));
electron.app.quit();
Expand Down Expand Up @@ -171,27 +172,29 @@ function restoreMainWindow() {
}

// Handle HTTP basic auth
const authsByWebContentsId: { [id: string]: { username: string; password: string; }} = {};
const httpAuthByHosts: { [origin: string]: { username: string; password: string; } } = {};

electron.ipcMain.on("set-web-contents-http-auth", (event: Electron.Event, id: number, auth: { username: string; password: string; }) => {
authsByWebContentsId[id] = auth;
electron.ipcMain.on("set-http-auth", (event: Electron.Event, host: string, auth: { username: string; password: string; }) => {
httpAuthByHosts[host] = auth;
});

electron.app.on("login", (event, webContents, request, authInfo, callback) => {
event.preventDefault();

const authData = authsByWebContentsId[webContents.id];
const parsedUrl = url.parse(request.url);
const host = `${parsedUrl.hostname}:${parsedUrl.port}`;
const auth = httpAuthByHosts[host];

if (authData == null) {
// Since this might race with the set-web-contents-http-auth event above,
if (auth == null) {
// Since this might race with the set-http-auth event above,
// try again a second later
setTimeout(() => {
const authData = authsByWebContentsId[webContents.id];
if (authData == null) callback(null, null);
else callback(authData.username, authData.password);
const auth = httpAuthByHosts[host];
if (auth == null) callback(null, null);
else callback(auth.username, auth.password);
}, 1000);
return;
}

callback(authData.username, authData.password);
callback(auth.username, auth.password);
});
5 changes: 2 additions & 3 deletions src/renderer/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export function load(callback: (err: Error) => void) {

if (dataJSON == null) {
// Setup defaults
const myServerEntry: ServerEntry = { id: "0", hostname: "127.0.0.1", port: "4237", label: i18n.t("server:myServer"), httpUsername: "", httpPassword: "" };
const myServerEntry: ServerEntry = { id: "0", hostname: "127.0.0.1", port: "4237", label: i18n.t("server:myServer"), password: "" };
favoriteServers = [ myServerEntry ];
favoriteServersById[myServerEntry.id] = myServerEntry;

Expand All @@ -69,8 +69,7 @@ export function load(callback: (err: Error) => void) {
favoriteServers = data.favoriteServers;
for (const entry of favoriteServers) {
favoriteServersById[entry.id] = entry;
if (entry.httpUsername == null) entry.httpUsername = "";
if (entry.httpPassword == null) entry.httpPassword = "";
if (entry.password == null) entry.password = "";
}
recentProjects = data.recentProjects;
autoStartServer = data.autoStartServer;
Expand Down
63 changes: 21 additions & 42 deletions src/renderer/sidebar/AddOrEditServerDialog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,21 @@ type AddOrEditOptions = {
initialHostnameValue: string;
initialPortValue: string;
initialLabelValue: string;
initialHttpUsernameValue: string;
initialHttpPasswordValue: string;
initialPasswordValue: string;
};

interface AddOrEditServerResult {
hostname: string;
port: string;
label: string;
httpUsername: string;
httpPassword: string;
password: string;
}

export default class AddOrEditServerDialog extends BaseDialog<AddOrEditServerResult> {
private hostnameInputElt: HTMLInputElement;
private portInputElt: HTMLInputElement;
private labelInputElt: HTMLInputElement;
private httpUsernameInputElt: HTMLInputElement;
private httpPasswordInputElt: HTMLInputElement;
private passwordInputElt: HTMLInputElement;

constructor(headerLabel: string, options: AddOrEditOptions, callback: (result: AddOrEditServerResult) => void) {
super(callback);
Expand Down Expand Up @@ -83,40 +80,23 @@ export default class AddOrEditServerDialog extends BaseDialog<AddOrEditServerRes
this.labelInputElt.style.flex = "1 1 0";
labelRow.appendChild(this.labelInputElt);

// HTTP basic auth username
const httpUsernameRow = document.createElement("div");
httpUsernameRow.className = "group";
httpUsernameRow.style.display = "flex";
httpUsernameRow.style.alignItems = "center";
this.formElt.appendChild(httpUsernameRow);

const httpUsernameHeader = document.createElement("label");
httpUsernameHeader.textContent = i18n.t("common:server.httpUsername");
httpUsernameHeader.style.marginRight = "0.5em";
httpUsernameRow.appendChild(httpUsernameHeader);

this.httpUsernameInputElt = document.createElement("input");
this.httpUsernameInputElt.value = options.initialHttpUsernameValue;
this.httpUsernameInputElt.style.flex = "1 1 0";
httpUsernameRow.appendChild(this.httpUsernameInputElt);

// HTTP basic auth password
const httpPasswordRow = document.createElement("div");
httpPasswordRow.className = "group";
httpPasswordRow.style.display = "flex";
httpPasswordRow.style.alignItems = "center";
this.formElt.appendChild(httpPasswordRow);

const httpPasswordHeader = document.createElement("label");
httpPasswordHeader.textContent = i18n.t("common:server.httpPassword");
httpPasswordHeader.style.marginRight = "0.5em";
httpPasswordRow.appendChild(httpPasswordHeader);

this.httpPasswordInputElt = document.createElement("input");
this.httpPasswordInputElt.setAttribute("type", "password");
this.httpPasswordInputElt.value = options.initialHttpPasswordValue;
this.httpPasswordInputElt.style.flex = "1 1 0";
httpPasswordRow.appendChild(this.httpPasswordInputElt);
// Password
const passwordRow = document.createElement("div");
passwordRow.className = "group";
passwordRow.style.display = "flex";
passwordRow.style.alignItems = "center";
this.formElt.appendChild(passwordRow);

const passwordHeader = document.createElement("label");
passwordHeader.textContent = i18n.t("common:server.password");
passwordHeader.style.marginRight = "0.5em";
passwordRow.appendChild(passwordHeader);

this.passwordInputElt = document.createElement("input");
this.passwordInputElt.setAttribute("type", "password");
this.passwordInputElt.value = options.initialPasswordValue;
this.passwordInputElt.style.flex = "1 1 0";
passwordRow.appendChild(this.passwordInputElt);

// Buttons
const buttonsElt = document.createElement("div");
Expand Down Expand Up @@ -150,8 +130,7 @@ export default class AddOrEditServerDialog extends BaseDialog<AddOrEditServerRes
hostname: this.hostnameInputElt.value,
port: this.portInputElt.value !== "" ? this.portInputElt.value : null,
label: this.labelInputElt.value,
httpUsername: this.httpUsernameInputElt.value,
httpPassword: this.httpPasswordInputElt.value
password: this.passwordInputElt.value
};
super.submit(result);
}
Expand Down
9 changes: 3 additions & 6 deletions src/renderer/sidebar/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,7 @@ function onAddServerClick(event: MouseEvent) {
initialHostnameValue: "127.0.0.1",
initialPortValue: "4237",
initialLabelValue: "",
initialHttpUsernameValue: "",
initialHttpPasswordValue: ""
initialPasswordValue: ""
};

new AddAddOrEditServerDialog(i18n.t("sidebar:addServer.title"), addOrEditOptions, (newServer: ServerEntry) => {
Expand All @@ -62,8 +61,7 @@ function onEditServerClick(event: MouseEvent) {
initialHostnameValue: serverEntry.hostname,
initialPortValue: serverEntry.port,
initialLabelValue: serverEntry.label,
initialHttpUsernameValue: serverEntry.httpUsername,
initialHttpPasswordValue: serverEntry.httpPassword
initialPasswordValue: serverEntry.password
};

new AddAddOrEditServerDialog(i18n.t("sidebar:editServer.title"), addOrEditOptions, (updatedEntry) => {
Expand All @@ -72,8 +70,7 @@ function onEditServerClick(event: MouseEvent) {
serverEntry.hostname = updatedEntry.hostname;
serverEntry.port = updatedEntry.port;
serverEntry.label = updatedEntry.label;
serverEntry.httpUsername = updatedEntry.httpUsername;
serverEntry.httpPassword = updatedEntry.httpPassword;
serverEntry.password = updatedEntry.password;

const selectedServerElt = serversTreeView.treeRoot.querySelector(`li[data-server-id="${serverId}"]`);
const host = serverEntry.hostname + (serverEntry.port != null ? `:${serverEntry.port}` : "");
Expand Down
Loading

0 comments on commit d6174de

Please sign in to comment.