Skip to content

Commit

Permalink
feat: Restrict access to "offline" flows (#3196)
Browse files Browse the repository at this point in the history
  • Loading branch information
DafyddLlyr authored Jun 1, 2024
1 parent ac9fb31 commit d9641ae
Show file tree
Hide file tree
Showing 13 changed files with 140 additions and 22 deletions.
2 changes: 1 addition & 1 deletion e2e/tests/api-driven/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
},
"dependencies": {
"@cucumber/cucumber": "^9.3.0",
"@opensystemslab/planx-core": "git+https://github.com/theopensystemslab/planx-core#550634a",
"@opensystemslab/planx-core": "git+https://github.com/theopensystemslab/planx-core#5710d52",
"axios": "^1.6.8",
"dotenv": "^16.3.1",
"dotenv-expand": "^10.0.0",
Expand Down
8 changes: 4 additions & 4 deletions e2e/tests/api-driven/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions e2e/tests/api-driven/src/invite-to-pay/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ export async function buildITPFlow({
const flowId: string = await $admin.flow.create({
teamId,
slug: `test-invite-to-pay-flow-with-send-to-${destination.toLowerCase()}`,
status: "online",
data: flowGraph,
});
const publishedFlowId = await $admin.flow.publish({
Expand Down
2 changes: 1 addition & 1 deletion e2e/tests/ui-driven/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"postinstall": "./install-dependencies.sh"
},
"dependencies": {
"@opensystemslab/planx-core": "git+https://github.com/theopensystemslab/planx-core#550634a",
"@opensystemslab/planx-core": "git+https://github.com/theopensystemslab/planx-core#5710d52",
"axios": "^1.6.8",
"dotenv": "^16.3.1",
"eslint": "^8.56.0",
Expand Down
8 changes: 4 additions & 4 deletions e2e/tests/ui-driven/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions e2e/tests/ui-driven/src/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ export async function setUpTestContext(
slug: context.flow.slug,
teamId: context.team.id,
data: context.flow!.data!,
status: "online",
});
context.flow.publishedId = await $admin.flow.publish({
flow: {
Expand Down
48 changes: 48 additions & 0 deletions e2e/tests/ui-driven/src/create-flow/create-flow.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,54 @@ test.describe("Navigation", () => {
await expect(previewLink).toBeVisible();
});

test("Cannot preview an offline flow", async ({
browser,
}: {
browser: Browser;
}) => {
const page = await createAuthenticatedSession({
browser,
userId: context.user!.id!,
});

await page.goto(
`/${context.team.slug}/${serviceProps.slug}/published?analytics=false`,
);

await expect(
page.getByRole("heading", { level: 1, name: "Offline" }),
).toBeVisible();
});

test("Turn a flow online", async ({ browser }) => {
const page = await createAuthenticatedSession({
browser,
userId: context.user!.id!,
});

await page.goto(`/${context.team.slug}/${serviceProps.slug}`);

// Open flow settings
// TODO: Access via sidebar when EDITOR_NAVIGATION flag is removed
page.getByLabel("Toggle Menu").click();
page.getByText("Flow Settings").click();

// Toggle flow online
page.getByLabel("Offline").click();
page.getByRole("button", { name: "Save", disabled: false }).click();
await expect(
page.getByText("Service settings updated successfully"),
).toBeVisible();

// Exit back to main Editor page
page.getByRole("link", { name: "Close" }).click();

const previewLink = page.getByRole("link", {
name: "Open published service",
});
await expect(previewLink).toBeVisible();
});

test("Can preview a published flow", async ({
browser,
}: {
Expand Down
7 changes: 5 additions & 2 deletions editor.planx.uk/src/pages/FlowEditor/lib/store/shared.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { CoreDomainClient } from "@opensystemslab/planx-core";
import { Auth } from "@opensystemslab/planx-core/dist/requests/graphql";
import { FlowStatus } from "@opensystemslab/planx-core/types";
import { ROOT_NODE_KEY } from "@planx/graph";
import { capitalize } from "lodash";
import { removeSessionIdSearchParam } from "utils";
Expand All @@ -23,10 +24,12 @@ export interface SharedStore extends Store.Store {
id,
flow,
flowSlug,
flowStatus,
}: {
id: string;
flow: Store.flow;
flowSlug: string;
flowStatus?: FlowStatus;
}) => void;
wasVisited: (id: Store.nodeId) => boolean;
previewEnvironment: PreviewEnvironment;
Expand Down Expand Up @@ -88,9 +91,9 @@ export const sharedStore: StateCreator<
removeSessionIdSearchParam();
},

setFlow({ id, flow, flowSlug }) {
setFlow({ id, flow, flowSlug, flowStatus }) {
this.setFlowNameFromSlug(flowSlug);
set({ id, flow, flowSlug });
set({ id, flow, flowSlug, flowStatus });
get().initNavigationStore();
},

Expand Down
16 changes: 16 additions & 0 deletions editor.planx.uk/src/pages/OfflinePage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import Typography from "@mui/material/Typography";
import StatusPage from "pages/Preview/StatusPage";
import React from "react";

export const OfflinePage: React.FC = () => (
<StatusPage bannerHeading="Offline">
<Typography variant="body2">
This service is not currently available to new applicants. Please check
back later.
</Typography>
<Typography variant="body2">
If you're resuming an application you previously started, please use the
link sent to you via email.
</Typography>
</StatusPage>
);
16 changes: 16 additions & 0 deletions editor.planx.uk/src/pages/layout/OfflineLayout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { useStore } from "pages/FlowEditor/lib/store";
import { OfflinePage } from "pages/OfflinePage";
import React, { PropsWithChildren } from "react";

const OfflineLayout = ({ children }: PropsWithChildren) => {
const isFlowOnline = useStore.getState().flowStatus === "online";
const searchParams = new URLSearchParams(window.location.search);
const isUserResuming = Boolean(searchParams.get("sessionId"));

// Allow users to complete Save & Return journeys, even if a flow is offline
const isFlowAccessible = isFlowOnline || isUserResuming;

return isFlowAccessible ? children : <OfflinePage />;
};

export default OfflineLayout;
17 changes: 13 additions & 4 deletions editor.planx.uk/src/routes/views/published.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { NaviRequest } from "navi";
import { NotFoundError } from "navi";
import { useStore } from "pages/FlowEditor/lib/store";
import { Store } from "pages/FlowEditor/lib/store";
import OfflineLayout from "pages/layout/OfflineLayout";
import PublicLayout from "pages/layout/PublicLayout";
import SaveAndReturnLayout from "pages/layout/SaveAndReturnLayout";
import React from "react";
Expand Down Expand Up @@ -43,16 +44,23 @@ export const publishedView = async (req: NaviRequest) => {
const state = useStore.getState();
// XXX: necessary as long as not every flow is published; aim to remove dataMergedHotfix.ts in future
// load pre-flattened published flow if exists, else load & flatten flow
state.setFlow({ id: flow.id, flow: publishedFlow, flowSlug });
state.setFlow({
id: flow.id,
flow: publishedFlow,
flowSlug,
flowStatus: flow.status,
});
state.setGlobalSettings(data.globalSettings[0]);
state.setFlowSettings(flow.settings);
state.setTeam(flow.team);

return (
<PublicLayout>
<SaveAndReturnLayout>
<View />
</SaveAndReturnLayout>
<OfflineLayout>
<SaveAndReturnLayout>
<View />
</SaveAndReturnLayout>
</OfflineLayout>
</PublicLayout>
);
};
Expand Down Expand Up @@ -94,6 +102,7 @@ export const fetchSettingsForPublishedView = async (
boundaryBBox: boundary_bbox
}
settings
status
publishedFlows: published_flows(
limit: 1
order_by: { created_at: desc }
Expand Down
6 changes: 4 additions & 2 deletions editor.planx.uk/src/types.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import {
FlowStatus,
GovUKPayment,
NotifyPersonalisation,
Team,
} from "@opensystemslab/planx-core/types";
import { OT } from "@planx/graph/types";
import { useFormik } from "formik";

import { Store } from "./pages/FlowEditor/lib/store/index";
import { SharedStore } from "./pages/FlowEditor/lib/store/shared";
import { OT } from "@planx/graph/types";

export type Maybe<T> = T | undefined;

Expand All @@ -18,6 +19,7 @@ export interface Flow {
slug: string;
team: Team;
settings?: FlowSettings;
status?: FlowStatus;
}
export interface GlobalSettings {
footerContent?: { [key: string]: TextContent };
Expand Down Expand Up @@ -133,4 +135,4 @@ export interface Operation {
lastName: string;
};
data: Array<OT.Op>;
}
}
30 changes: 26 additions & 4 deletions hasura.planx.uk/metadata/tables.yaml
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
- table:
name: analytics
schema: public
object_relationships:
- name: flow
using:
foreign_key_constraint_on: flow_id
insert_permissions:
- role: public
permission:
check: {}
check:
flow:
status:
_eq: online
columns:
- created_at
- flow_id
Expand All @@ -23,15 +30,26 @@
permission:
columns:
- ended_at
filter: {}
filter:
flow:
status:
_eq: online
check: null
- table:
name: analytics_logs
schema: public
object_relationships:
- name: analytic
using:
foreign_key_constraint_on: analytics_id
insert_permissions:
- role: public
permission:
check: {}
check:
analytic:
flow:
status:
_eq: online
columns:
- analytics_id
- created_at
Expand Down Expand Up @@ -65,7 +83,11 @@
- metadata
- next_log_created_at
- user_exit
filter: {}
filter:
analytic:
flow:
status:
_eq: online
check: null
- table:
name: analytics_summary
Expand Down

0 comments on commit d9641ae

Please sign in to comment.