Skip to content

Commit

Permalink
feat: Check if both Cozy blue or Cozy gl exists
Browse files Browse the repository at this point in the history
Also refactored a little the CozySanitizeUrlService.
  • Loading branch information
zatteo committed Nov 15, 2024
1 parent 104c244 commit c63307f
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 59 deletions.
8 changes: 1 addition & 7 deletions apps/browser/src/_locales/en/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -759,13 +759,7 @@
"message": "Woops, the address is not correct. Try with \"cozy\" with a \"z\"!"
},
"noCozyFound": {
"message": "Unable to connect to address $VALUE$, please check that this is the address of your Cozy",
"placeholders": {
"value": {
"content": "$1",
"example": "https://alice.mycozy.cloud"
}
}
"message": "Unable to connect to given address, please check that this is the address of your Cozy"
},
"masterPassRequired": {
"message": "Master password is required."
Expand Down
8 changes: 1 addition & 7 deletions apps/browser/src/_locales/fr/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -759,13 +759,7 @@
"message": "Oups, ce n'est pas la bonne adresse. Essayez d'écrire \"cozy\" avec un \"z\" !"
},
"noCozyFound": {
"message": "Impossible de se connecter à l'adresse $VALUE$, veuillez vérifier que c’est bien l’adresse de votre Cozy",
"placeholders": {
"value": {
"content": "$1",
"example": "https://alice.mycozy.cloud"
}
}
"message": "Impossible de se connecter à l'adresse donnée, veuillez vérifier que c’est bien l’adresse de votre Cozy"
},
"masterPassRequired": {
"message": "Le mot de passe principal est requis."
Expand Down
34 changes: 25 additions & 9 deletions apps/browser/src/auth/popup/home.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import { ToastService } from "@bitwarden/components";
import { BrowserApi } from "../../platform/browser/browser-api";
import { CozySanitizeUrlService } from "../../popup/services/cozySanitizeUrl.service";
import { AccountSwitcherService } from "./account-switching/services/account-switcher.service";
import { sanitizeUrlInput } from "./login.component.functions";
/* eslint-enable */
/* end Cozy imports */

Expand Down Expand Up @@ -102,20 +101,38 @@ export class HomeComponent implements OnInit, OnDestroy {
}

// Cozy customization; check if Cozy exists before navigating to login page
const cozyUrl = sanitizeUrlInput(this.formGroup.value.email, this.cozySanitizeUrlService);
const cozyUrl = this.cozySanitizeUrlService.sanitizeUrlInput(this.formGroup.value.email);
const glUrl = this.cozySanitizeUrlService.sanitizeUrlInput(
this.formGroup.value.email,
".cozygrandlyon.cloud",
);
let selectedUrl = null;

const cozyExist = await this.cozyExist(cozyUrl);
if (cozyExist) {
selectedUrl = cozyUrl;
} else {
const glExist = await this.cozyExist(glUrl);
if (glExist) {
selectedUrl = glUrl;
}
}

if (await this.cozyDoesNotExist(cozyUrl)) {
if (!selectedUrl) {
this.toastService.showToast({
variant: "error",
title: this.i18nService.t("errorOccured"),
message: this.i18nService.t("noCozyFound", cozyUrl),
message: this.i18nService.t("noCozyFound"),
});
return;
}

// Cozy customization end

await this.setLoginEmailValues();
await this.router.navigate(["login"], { queryParams: { email: this.formGroup.value.email, cozyUrl } });
await this.router.navigate(["login"], {
queryParams: { email: this.formGroup.value.email, cozyUrl: selectedUrl },
});
}

async setLoginEmailValues() {
Expand All @@ -132,19 +149,18 @@ export class HomeComponent implements OnInit, OnDestroy {
/* end custo */

// Cozy customization; check if Cozy exists before navigating to login page
async cozyDoesNotExist(cozyUrl: string) {
async cozyExist(cozyUrl: string) {
const preloginCozyUrl = new URL("/public/prelogin", cozyUrl).toString();

try {
const preloginCozyResponse = await fetch(preloginCozyUrl);

return preloginCozyResponse.status === 404;
return preloginCozyResponse.status === 200;
} catch {
// If the request fails, we assume the Cozy does not exist.
// It happens if the user enter a valid URL but that does not answer.
return true;
return false;
}

}
// Cozy customization end
}
21 changes: 0 additions & 21 deletions apps/browser/src/auth/popup/login.component.functions.ts

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,75 +1,74 @@
import { sanitizeUrlInput } from "../../auth/popup/login.component.functions";
import { CozySanitizeUrlService } from "../services/cozySanitizeUrl.service";
import { CozySanitizeUrlService } from "./cozySanitizeUrl.service";

describe("url input", () => {
const cozySanitizeUrlService = new CozySanitizeUrlService();

it("should return undefined if the input is empty", () => {
const inputUrl = "";
expect(() => {
sanitizeUrlInput(inputUrl, cozySanitizeUrlService);
cozySanitizeUrlService.sanitizeUrlInput(inputUrl);
}).toThrow(new Error("cozyUrlRequired"));
});
it("should return undefined if the input is an email", () => {
const inputUrl = "claude@cozycloud.cc";
expect(() => {
sanitizeUrlInput(inputUrl, cozySanitizeUrlService);
cozySanitizeUrlService.sanitizeUrlInput(inputUrl);
}).toThrow(new Error("noEmailAsCozyUrl"));
});
it("should return the url without the app slug if present", () => {
const inputUrl = "claude-drive.mycozy.cloud";
const url = sanitizeUrlInput(inputUrl, cozySanitizeUrlService);
const url = cozySanitizeUrlService.sanitizeUrlInput(inputUrl);
expect(url).toEqual("https://claude.mycozy.cloud");
});
it("should return the url with the default domain if missing", () => {
const inputUrl = "claude-drive";
const url = sanitizeUrlInput(inputUrl, cozySanitizeUrlService);
const url = cozySanitizeUrlService.sanitizeUrlInput(inputUrl);
expect(url).toEqual("https://claude.mycozy.cloud");
});
it("should return the url with the default scheme if missing", () => {
const inputUrl = "claude.mycozy.cloud";
const url = sanitizeUrlInput(inputUrl, cozySanitizeUrlService);
const url = cozySanitizeUrlService.sanitizeUrlInput(inputUrl);
expect(url).toEqual("https://claude.mycozy.cloud");
});
it("should return the url if the input is correct", () => {
const inputUrl = "https://claude.mycozy.cloud";
const url = sanitizeUrlInput(inputUrl, cozySanitizeUrlService);
const url = cozySanitizeUrlService.sanitizeUrlInput(inputUrl);
expect(url).toEqual("https://claude.mycozy.cloud");
});
it("should accept local url", () => {
const inputUrl = "http://claude.cozy.tools:8080";
const url = sanitizeUrlInput(inputUrl, cozySanitizeUrlService);
const url = cozySanitizeUrlService.sanitizeUrlInput(inputUrl);
expect(url).toEqual("http://claude.cozy.tools:8080");
});
it("should not try to remove slug if present and url has a custom domain", () => {
const inputUrl = "claude-drive.on-premise.cloud";
const url = sanitizeUrlInput(inputUrl, cozySanitizeUrlService);
const url = cozySanitizeUrlService.sanitizeUrlInput(inputUrl);
expect(url).toEqual("https://claude-drive.on-premise.cloud");
});
it("should return the correct url if domains contains a dash", () => {
const inputUrl = "claude.on-premise.cloud";
const url = sanitizeUrlInput(inputUrl, cozySanitizeUrlService);
const url = cozySanitizeUrlService.sanitizeUrlInput(inputUrl);
expect(url).toEqual("https://claude.on-premise.cloud");
});
it("should return the correct url if domains contains a dash and cozy is installed on domain root", () => {
const inputUrl = "https://on-premise.cloud";
const url = sanitizeUrlInput(inputUrl, cozySanitizeUrlService);
const url = cozySanitizeUrlService.sanitizeUrlInput(inputUrl);
expect(url).toEqual("https://on-premise.cloud");
});
it(`should throw if user write 'mycosy' instead of 'mycozy'`, () => {
const inputUrl = "https://claude.mycosy.cloud";
expect(() => {
sanitizeUrlInput(inputUrl, cozySanitizeUrlService);
cozySanitizeUrlService.sanitizeUrlInput(inputUrl);
}).toThrow(new Error("hasMispelledCozy"));
});
it(`should accept real '*cosy*' url`, () => {
const inputUrl = "https://claude.realdomaincosy.cloud";
const url = sanitizeUrlInput(inputUrl, cozySanitizeUrlService);
const url = cozySanitizeUrlService.sanitizeUrlInput(inputUrl);
expect(url).toEqual("https://claude.realdomaincosy.cloud");
});
it(`should remove trailing / in url`, () => {
const inputUrl = "https://claude.realdomaincosy.cloud/";
const url = sanitizeUrlInput(inputUrl, cozySanitizeUrlService);
const url = cozySanitizeUrlService.sanitizeUrlInput(inputUrl);
expect(url).toEqual("https://claude.realdomaincosy.cloud");
});
});
17 changes: 17 additions & 0 deletions apps/browser/src/popup/services/cozySanitizeUrl.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,21 @@ export class CozySanitizeUrlService {
};

protected removeTrailingSlash = (value: string) => value.replace(/\/$/, "");

sanitizeUrlInput = (inputUrl: string, domain: string = this.cozyDomain): string => {
// Prevent empty url
if (!inputUrl) {
throw new Error("cozyUrlRequired");
}
// Prevent email input
if (inputUrl.includes("@")) {
throw new Error("noEmailAsCozyUrl");
}

if (this.hasMispelledCozy(inputUrl)) {
throw new Error("hasMispelledCozy");
}

return this.normalizeURL(inputUrl, domain);
};
}

0 comments on commit c63307f

Please sign in to comment.