Skip to content

Commit

Permalink
Make footer content accessible without auth under /unrestricted #190
Browse files Browse the repository at this point in the history
  • Loading branch information
hupf committed Dec 19, 2024
1 parent 64472b1 commit e4c0c86
Show file tree
Hide file tree
Showing 31 changed files with 508 additions and 144 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ Download the [latest build](https://bkd-mba-fbi.github.io/evento-portal/evento-p
- [Browser Testing](./doc/browser-testing.md) – Support & BrowserStack.com
- [Progressive Web App (PWA)](./doc/pwa.md) – Installability & offline support
- [iframe Limitations & Workarounds](./doc/iframe.md) – Implementation details (iframe.js)
- [Unrestricted Content Pages](./doc/unrestricted-content.md) – Footer content

### Operations

Expand Down
190 changes: 130 additions & 60 deletions cypress/e2e/footer.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,88 +3,158 @@ describe("Footer", () => {
cy.resizeToDesktop();
});

describe("de", () => {
beforeEach(() => {
cy.login({ locale: "de-CH", roles: ["TeacherRole"], permissions: [] });
});
describe("authenticated", () => {
describe("de", () => {
beforeEach(() => {
cy.login({ locale: "de-CH", roles: ["TeacherRole"], permissions: [] });
});

it("renders the footer with links to contact, legal and imprint pages", () => {
cy.visitPortal("/index.html");
it("renders the footer with links to contact, legal and imprint pages", () => {
cy.visitPortal("/");

cy.get("bkd-footer").within(() => {
cy.get("a").contains("Kontakt");
cy.get("a").contains("Rechtliche Hinweise");
cy.get("a").contains("Impressum");
cy.get("bkd-footer").within(() => {
cy.get("a").contains("Kontakt");
cy.get("a").contains("Rechtliche Hinweise");
cy.get("a").contains("Impressum");
});
});
});

it("renders the static contact page", () => {
cy.visitPortal("/index.html");
cy.get("bkd-footer").find("a").contains("Kontakt").click();
it("renders the static contact page", () => {
cy.visitPortal("/");
cy.get("bkd-footer").find("a").contains("Kontakt").click();

cy.get("h1").contains("Kontakt", {});
cy.contains("an die zuständige Stelle in ihrer Schule");
cy.get("iframe").should("not.exist");
});
cy.get("h1").contains("Kontakt", {});
cy.contains("an die zuständige Stelle in ihrer Schule");
cy.get("iframe").should("not.exist");
});

it("renders the static legal page", () => {
cy.visitPortal("/index.html");
cy.get("bkd-footer").find("a").contains("Rechtliche Hinweise").click();
it("renders the static legal page", () => {
cy.visitPortal("/");
cy.get("bkd-footer").find("a").contains("Rechtliche Hinweise").click();

cy.get("h1").contains("Rechtliche Hinweise", {});
cy.contains("Haftungsausschluss");
cy.get("iframe").should("not.exist");
cy.get("h1").contains("Rechtliche Hinweise", {});
cy.contains("Haftungsausschluss");
cy.get("iframe").should("not.exist");
});

it("renders the static imprint page", () => {
cy.visitPortal("/");
cy.get("bkd-footer").find("a").contains("Impressum").click();

cy.get("h1").contains("Impressum", {});
cy.contains("Inhaltsverantwortung");
cy.get("iframe").should("not.exist");
});
});

it("renders the static imprint page", () => {
cy.visitPortal("/index.html");
cy.get("bkd-footer").find("a").contains("Impressum").click();
describe("fr", () => {
beforeEach(() => {
cy.login({ locale: "fr-CH", roles: ["TeacherRole"], permissions: [] });
});

it("renders the footer with links to contact, legal and imprint pages", () => {
cy.visitPortal("/?locale=fr-CH");
cy.get("bkd-footer").within(() => {
cy.get("a").contains("Contact");
cy.get("a").contains("Mentions légales");
cy.get("a").contains("Impressum");
});
});

it("renders the static contact page", () => {
cy.visitPortal("/?locale=fr-CH");
cy.get("bkd-footer").find("a").contains("Contact").click();

cy.get("h1").contains("Contact", {});
cy.contains("contacter le service compétent de leur établissement");
cy.get("iframe").should("not.exist");
});

it("renders the static legal page", () => {
cy.visitPortal("/?locale=fr-CH");
cy.get("bkd-footer").find("a").contains("Mentions légales").click();

cy.get("h1").contains("Mentions légales", {});
cy.contains("Exclusion de la responsabilité");
cy.get("iframe").should("not.exist");
});

it("renders the static imprint page", () => {
cy.visitPortal("/?locale=fr-CH");
cy.get("bkd-footer").find("a").contains("Impressum").click();

cy.get("h1").contains("Impressum", {});
cy.contains("Inhaltsverantwortung");
cy.get("iframe").should("not.exist");
cy.get("h1").contains("Impressum", {});
cy.contains("Responsabilité du contenu");
cy.get("iframe").should("not.exist");
});
});
});

describe("fr", () => {
beforeEach(() => {
cy.login({ locale: "fr-CH", roles: ["TeacherRole"], permissions: [] });
});
describe("unauthenticated via /unrestricted/", () => {
describe("de", () => {
it("renders the static contact page", () => {
cy.visit("/unrestricted/?locale=de-CH&module=contact");

it("renders the footer with links to contact, legal and imprint pages", () => {
cy.visitPortal("/index.html?locale=fr-CH");
cy.get("bkd-footer").within(() => {
cy.get("a").contains("Contact");
cy.get("a").contains("Mentions légales");
cy.get("a").contains("Impressum");
cy.get("h1").contains("Kontakt", {});
cy.contains("an die zuständige Stelle in ihrer Schule");
});
});

it("renders the static contact page", () => {
cy.visitPortal("/index.html?locale=fr-CH");
cy.get("bkd-footer").find("a").contains("Contact").click();
it("renders the static legal page", () => {
cy.visit("/unrestricted/?locale=de-CH&module=legal");

cy.get("h1").contains("Contact", {});
cy.contains("contacter le service compétent de leur établissement");
cy.get("iframe").should("not.exist");
});
cy.get("h1").contains("Rechtliche Hinweise", {});
cy.contains("Haftungsausschluss");
});

it("renders the static legal page", () => {
cy.visitPortal("/index.html?locale=fr-CH");
cy.get("bkd-footer").find("a").contains("Mentions légales").click();
it("renders the static imprint page", () => {
cy.visit("/unrestricted/?locale=de-CH&module=imprint");

cy.get("h1").contains("Impressum", {});
cy.contains("Inhaltsverantwortung");
});

it("navigates to legal page via footer", () => {
cy.visit("/unrestricted/?locale=de-CH&module=contact");
cy.get("h1").contains("Kontakt", {});

cy.get("bkd-footer").find("a").contains("Rechtliche Hinweise").click();
cy.get("h1").contains("Rechtliche Hinweise", {});
});

cy.get("h1").contains("Mentions légales", {});
cy.contains("Exclusion de la responsabilité");
cy.get("iframe").should("not.exist");
it("switches language", () => {
cy.visit("/unrestricted/?locale=de-CH&module=contact");
cy.get("h1").contains("Kontakt", {});

cy.get("bkd-language-switcher").find("a").contains("fr").click();
cy.get("h1").contains("Contact", {});
cy.url().should(
"include",
"/unrestricted/?locale=fr-CH&module=contact",
);
});
});

it("renders the static imprint page", () => {
cy.visitPortal("/index.html?locale=fr-CH");
cy.get("bkd-footer").find("a").contains("Impressum").click();
describe("fr", () => {
it("renders the static contact page", () => {
cy.visit("/unrestricted/?locale=fr-CH&module=contact");

cy.get("h1").contains("Contact", {});
cy.contains("contacter le service compétent de leur établissement");
});

it("renders the static legal page", () => {
cy.visit("/unrestricted/?locale=fr-CH&module=legal");

cy.get("h1").contains("Impressum", {});
cy.contains("Responsabilité du contenu");
cy.get("iframe").should("not.exist");
cy.get("h1").contains("Mentions légales", {});
cy.contains("Exclusion de la responsabilité");
});

it("renders the static imprint page", () => {
cy.visit("/unrestricted/?locale=fr-CH&module=imprint");

cy.get("h1").contains("Impressum", {});
cy.contains("Responsabilité du contenu");
});
});
});
});
17 changes: 17 additions & 0 deletions doc/unrestricted-content.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
[back](../README.md)

# Unrestricted Content Pages

The pages linked in the footer (contact, legal & imprint) are rendered by the _Evento Portal_, not within the `<iframe>`. These are "static" content, that is sourced from the i18n translations.

For the external OAuth login page to be able to link to these pages from its footer, there is an unrestricted version of them under the `/unrestricted` path which is accessible without being authenticated.

Technically it is implemented as follows:

- We have a second Vite entry point [unrestricted/index.html](../unrestricted/index.html) (see `build.rollupOptions.build` in [vite.config.ts](../vite.config.ts)).
- This version of the app uses a separate `<bkd-portal-unrestricted>` component, that works without authentication and uses the `<bkd-header-unrestricted>` and `<bkd-content-unrestricted` components for rendering the contents for unauthenticated users.
- The unrestricted variant has no navigation or service menu. It also does not initiate the OAuth login flow or the token renewal logic.
- The unrestricted pages are available under the following paths:
- `/unrestricted/?locale=de-CH&module=contact`
- `/unrestricted/?locale=de-CH&module=legal`
- `/unrestricted/?locale=de-CH&module=imprint`
3 changes: 3 additions & 0 deletions src/components/Content.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ import { StateController } from "@lit-app/state";
import { portalState } from "../state/portal-state";
import { tokenState } from "../state/token-state";
import { theme } from "../utils/theme";
import "./unrestricted/content/Contact";
import "./unrestricted/content/Imprint";
import "./unrestricted/content/Legal";

@customElement("bkd-content")
@localized()
Expand Down
7 changes: 5 additions & 2 deletions src/components/Header.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,11 @@ import { portalState } from "../state/portal-state";
import { buildUrl } from "../utils/routing";
import { theme } from "../utils/theme";
import { UserSettingsItem } from "../utils/user-settings";
import { MobileNav } from "./Header/MobileNav";
import { ServiceNav } from "./Header/ServiceNav";
import { MobileNav } from "./header/MobileNav";
import "./header/MobileNav";
import "./header/Nav";
import { ServiceNav } from "./header/ServiceNav";
import "./header/ServiceNav";

@customElement("bkd-header")
@localized()
Expand Down
32 changes: 0 additions & 32 deletions src/components/Header/NavItemLink.ts

This file was deleted.

5 changes: 4 additions & 1 deletion src/components/Portal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { localized } from "@lit/localize";
import { StateController, Unsubscribe } from "@lit-app/state";
import { settings } from "../settings";
import { portalState } from "../state/portal-state";
import { tokenState } from "../state/token-state.ts";
import { tokenState } from "../state/token-state";
import {
activateTokenForScope,
createOAuthClient,
Expand All @@ -21,6 +21,9 @@ import {
registerLightDomStyles,
theme,
} from "../utils/theme";
import "./Content";
import "./Footer";
import "./Header";

const oAuthClient = createOAuthClient();
const authReady = (async function () {
Expand Down
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,12 @@ import { StateController } from "@lit-app/state";
import arrowDownIcon from "../../assets/icons/arrow-down.svg?raw";
import arrowUpIcon from "../../assets/icons/arrow-up.svg?raw";
import { NavigationGroup, NavigationItem, settings } from "../../settings";
import { portalState } from "../../state/portal-state.ts";
import { portalState } from "../../state/portal-state";
import { getNavigationItem } from "../../utils/navigation";
import { buildUrl } from "../../utils/routing.ts";
import { buildUrl } from "../../utils/routing";
import { theme } from "../../utils/theme";
import {
UserSettingsItem,
userSettingsItems,
} from "../../utils/user-settings.ts";
import { UserSettingsItem, userSettingsItems } from "../../utils/user-settings";
import "./LanguageSwitcher";

@customElement("bkd-mobile-nav")
@localized()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { StateController } from "@lit-app/state";
import { NavigationGroup } from "../../settings";
import { portalState } from "../../state/portal-state";
import { theme } from "../../utils/theme";
import "./NavGroupToggle";

@customElement("bkd-nav")
@localized()
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { DropdownController } from "../../controllers/dropdown";
import { NavigationGroup } from "../../settings";
import { theme } from "../../utils/theme";
import { NavGroupDropdown } from "./NavGroupDropdown";
import "./NavGroupDropdown";

@customElement("bkd-nav-group-toggle")
@localized()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ import { unsafeHTML } from "lit/directives/unsafe-html.js";
import { localized, msg } from "@lit/localize";
import spinnerIcon from "../../assets/icons/spinner.svg?raw";
import trashIcon from "../../assets/icons/trash.svg?raw";
import { NotificationDataEntry } from "../../utils/fetch.ts";
import { sanitize } from "../../utils/sanitize.ts";
import { theme } from "../../utils/theme.ts";
import { NotificationsState } from "./NotificationsToggle.ts";
import { NotificationDataEntry } from "../../utils/fetch";
import { sanitize } from "../../utils/sanitize";
import { theme } from "../../utils/theme";
import { NotificationsState } from "./NotificationsToggle";

@customElement("bkd-notifications-dropdown")
@localized()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,17 @@ import { customElement, query, state } from "lit/decorators.js";
import { unsafeHTML } from "lit/directives/unsafe-html.js";
import { localized, msg } from "@lit/localize";
import bellIcon from "../../assets/icons/bell.svg?raw";
import { DropdownController } from "../../controllers/dropdown.ts";
import { getEnvSettings } from "../../env-settings.ts";
import { DropdownController } from "../../controllers/dropdown";
import { getEnvSettings } from "../../env-settings";
import {
NotificationDataEntry,
fetchNotifications,
updateNotifications,
} from "../../utils/fetch.ts";
import { log } from "../../utils/logging.ts";
import { theme } from "../../utils/theme.ts";
import { NotificationsDropdown } from "./NotificationsDropdown.ts";
} from "../../utils/fetch";
import { log } from "../../utils/logging";
import { theme } from "../../utils/theme";
import { NotificationsDropdown } from "./NotificationsDropdown";
import "./NotificationsDropdown";

const envSettings = getEnvSettings();
if (typeof envSettings?.notificationRefreshTime !== "number") {
Expand Down
Loading

0 comments on commit e4c0c86

Please sign in to comment.