Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: embed settings #16629

Merged
merged 46 commits into from
Nov 25, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
eb05b82
initial setup for embed settings
akash-codemonk Sep 7, 2022
61175dc
fix parsing
akash-codemonk Sep 8, 2022
b0e14db
Merge branch 'release' of github.com:appsmithorg/appsmith into feat/e…
akash-codemonk Sep 16, 2022
01364c3
Merge branch 'release' of github.com:appsmithorg/appsmith into feat/e…
akash-codemonk Sep 19, 2022
b721a9b
Merge branch 'release' of github.com:appsmithorg/appsmith into feat/e…
akash-codemonk Sep 21, 2022
19f5fa8
fix: use replaceAll
akash-codemonk Sep 21, 2022
dda211e
chore: remove dummy value
akash-codemonk Sep 21, 2022
8f55818
Fix escaping single quotes in env variable values
sharat87 Sep 22, 2022
401d9f2
Fix parsing of shell-escaped values
sharat87 Sep 28, 2022
58c44f9
Commit missing tests
sharat87 Sep 28, 2022
82d5a18
chore: fixes
akash-codemonk Sep 28, 2022
3667cc2
Merge branch 'fix/single-quotes-escaping' of github.com:appsmithorg/a…
akash-codemonk Sep 28, 2022
8625d73
more fixes
akash-codemonk Sep 28, 2022
60a806f
chore: tests
akash-codemonk Sep 28, 2022
7340845
chore: tests
akash-codemonk Sep 28, 2022
f5d79fe
fix: warning
akash-codemonk Sep 28, 2022
a73bb5a
Merge branch 'release' of github.com:appsmithorg/appsmith into feat/e…
akash-codemonk Sep 28, 2022
3afa98a
Merge branch 'release' of github.com:appsmithorg/appsmith into feat/e…
akash-codemonk Sep 30, 2022
31dbf99
fix: update checked radio color
akash-codemonk Oct 3, 2022
0cdb9a6
Merge branch 'release' of github.com:appsmithorg/appsmith into feat/e…
akash-codemonk Oct 3, 2022
e40fc12
fix: design review comments
akash-codemonk Oct 4, 2022
7a67d6c
Merge branch 'release' of github.com:appsmithorg/appsmith into feat/e…
akash-codemonk Oct 5, 2022
75c9740
store sources in local storage
akash-codemonk Oct 5, 2022
41360ac
Merge branch 'release' of github.com:appsmithorg/appsmith into feat/e…
akash-codemonk Oct 6, 2022
659fd1c
Merge branch 'release' of github.com:appsmithorg/appsmith into feat/e…
akash-codemonk Oct 13, 2022
3131521
Merge branch 'release' of github.com:appsmithorg/appsmith into feat/e…
akash-codemonk Oct 17, 2022
23f44f5
fix: limit values not being saved
akash-codemonk Oct 17, 2022
eaa6805
Merge branch 'release' of github.com:appsmithorg/appsmith into feat/e…
akash-codemonk Oct 19, 2022
b9075da
Merge branch 'release' of github.com:appsmithorg/appsmith into feat/e…
akash-codemonk Oct 20, 2022
6ba6d77
fix: fix blank space and disappering values in input bugs
akash-codemonk Oct 21, 2022
e20f47a
fix: add cypress test
akash-codemonk Oct 21, 2022
f75373f
Merge branch 'release' of github.com:appsmithorg/appsmith into feat/e…
akash-codemonk Oct 21, 2022
1edc90d
Merge branch 'release' of github.com:appsmithorg/appsmith into feat/e…
akash-codemonk Oct 23, 2022
b183225
chore: test fix
akash-codemonk Oct 24, 2022
f5f76b2
Merge branch 'release' of github.com:appsmithorg/appsmith into feat/e…
akash-codemonk Nov 7, 2022
8326760
chore: colors from constants
akash-codemonk Nov 7, 2022
5a54f46
Merge branch 'release' of github.com:appsmithorg/appsmith into feat/e…
akash-codemonk Nov 8, 2022
bc083e5
Merge branch 'release' of github.com:appsmithorg/appsmith into feat/e…
akash-codemonk Nov 14, 2022
d327589
chore: fix review comments
akash-codemonk Nov 14, 2022
bef6c9f
chore: move test outside enterprise test folder
akash-codemonk Nov 14, 2022
d58b764
chore: Remove redundant test
akash-codemonk Nov 14, 2022
9a4197e
Merge branch 'release' of github.com:appsmithorg/appsmith into feat/e…
akash-codemonk Nov 18, 2022
0c5cc12
Merge branch 'release' of github.com:appsmithorg/appsmith into feat/e…
akash-codemonk Nov 21, 2022
d49eb62
fix: review comments
akash-codemonk Nov 21, 2022
614337b
Merge branch 'release' of github.com:appsmithorg/appsmith into feat/e…
akash-codemonk Nov 21, 2022
3a70471
Merge branch 'release' of github.com:appsmithorg/appsmith into feat/e…
akash-codemonk Nov 22, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
import { ObjectsRegistry } from "../../../../support/Objects/Registry";
const adminSettings = require("../../../../locators/AdminsSettings");

describe("Embed settings options", function() {
const {
AggregateHelper: agHelper,
DeployMode: deployMode,
EntityExplorer: ee,
HomePage: homePage,
} = ObjectsRegistry;

const getIframeBody = () => {
// get the iframe > document > body
// and retry until the body element is not empty
return (
cy
.get(".t--widget-iframewidget iframe")
.its("0.contentDocument.body")
.should("not.be.empty")
// wraps "body" DOM element to allow
// chaining more Cypress commands, like ".find(...)"
// https://on.cypress.io/wrap
.then(cy.wrap)
);
};

before(() => {
ee.DragDropWidgetNVerify("buttonwidget", 100, 100);
deployMode.DeployApp();
cy.get("[data-cy='viewmode-share']").click();
cy.get(".t--deployed-url input")
.invoke("attr", "value")
.as("embeddedAppUrl");
cy.enablePublicAccess();
cy.get(".t--back-to-home").click();
homePage.CreateNewApplication();
ee.DragDropWidgetNVerify("iframewidget", 100, 100);
cy.get("@embeddedAppUrl").then((url) => {
cy.testJsontext("url", url);
});
// cy.testJsontext("url", this.embeddedAppUrl);
deployMode.DeployApp();
cy.get("[data-cy='viewmode-share']").click();
cy.get(".t--deployed-url input")
.invoke("attr", "value")
.as("deployUrl");
cy.enablePublicAccess();
cy.wait(6000);
getIframeBody()
.contains("Submit")
.should("exist");
});

beforeEach(() => {
agHelper.RestoreLocalStorageCache();
});

afterEach(() => {
agHelper.SaveLocalStorageCache();
});

describe("Wrapper to get access to the alias in all tests", () => {
it("1. Allow embedding everywhere", function() {
cy.log(this.deployUrl);
cy.get(".t--back-to-home").click();
cy.get(".admin-settings-menu-option").click();
cy.get(".t--admin-settings-APPSMITH_ALLOWED_FRAME_ANCESTORS").within(
() => {
cy.get("input")
.eq(0)
.click();
},
);
cy.get(adminSettings.saveButton).click();
cy.wait(60000);
cy.wait(["@getEnvVariables", "@getEnvVariables"]).then((interception) => {
const {
APPSMITH_ALLOWED_FRAME_ANCESTORS,
} = interception[1].response.body.data;
expect(APPSMITH_ALLOWED_FRAME_ANCESTORS).to.equal("*");
});
cy.get(adminSettings.restartNotice).should("not.exist");
cy.visit(this.deployUrl);
getIframeBody()
.contains("Submit")
.should("exist");
});

it("2. Limit embedding", function() {
cy.log(this.deployUrl);
cy.get(".t--back-to-home").click();
cy.get(".admin-settings-menu-option").click();
cy.get(".t--admin-settings-APPSMITH_ALLOWED_FRAME_ANCESTORS").within(
() => {
cy.get("input")
.eq(1)
.click();
cy.get(".bp3-tag-remove")
.eq(1)
.click();
cy.get(".bp3-tag-remove")
.eq(0)
.click();
cy.get(".bp3-input-ghost")
.type(window.location.origin)
.blur();
},
);
cy.get(adminSettings.saveButton).click();
cy.wait(50000);
cy.get(adminSettings.restartNotice).should("not.exist");
cy.visit(this.deployUrl);
getIframeBody()
.contains("Submit")
.should("exist");
});
it("3. Disable everywhere", function() {
cy.log(this.deployUrl);
cy.get(".t--back-to-home").click();
cy.get(".admin-settings-menu-option").click();
cy.get(".t--admin-settings-APPSMITH_ALLOWED_FRAME_ANCESTORS").within(
() => {
cy.get("input")
.last()
.click();
},
);
cy.get(adminSettings.saveButton).click();
cy.wait(60000);
cy.get(adminSettings.restartNotice).should("not.exist");
cy.visit(this.deployUrl);
cy.wait(["@getEnvVariables", "@getEnvVariables"]).then((interception) => {
const {
APPSMITH_ALLOWED_FRAME_ANCESTORS,
} = interception[1].response.body.data;
expect(APPSMITH_ALLOWED_FRAME_ANCESTORS).to.equal("'none'");
});
getIframeBody()
.contains("Submit")
.should("not.exist");
});
});
});
1 change: 1 addition & 0 deletions app/client/cypress/locators/AdminsSettings.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,5 @@ export default {
disconnectBtn: "[data-testid='disconnect-service-button']",
formSignupDisabled: "[data-cy='APPSMITH_SIGNUP_DISABLED']",
formLoginDisabled: "[data-cy='APPSMITH_FORM_LOGIN_DISABLED']",
embedSettings: ".t--admin-settings-APPSMITH_ALLOWED_FRAME_ANCESTORS",
};
82 changes: 82 additions & 0 deletions app/client/src/ce/pages/AdminSettings/config/general.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ import {
Setting,
} from "@appsmith/pages/AdminSettings/config/types";
import BrandingBadge from "pages/AppViewer/BrandingBadge";
import { TagInput } from "design-system";
import QuestionFillIcon from "remixicon-react/QuestionFillIcon";
import localStorage from "utils/localStorage";
import isUndefined from "lodash/isUndefined";

export const APPSMITH_INSTANCE_NAME_SETTING_SETTING: Setting = {
id: "APPSMITH_INSTANCE_NAME",
Expand Down Expand Up @@ -81,6 +85,83 @@ export const APPSMITH_HIDE_WATERMARK_SETTING: Setting = {
"Hello, I would like to upgrade and remove the watermark.",
};

export const APPSMITH_ALLOWED_FRAME_ANCESTORS_SETTING: Setting = {
id: "APPSMITH_ALLOWED_FRAME_ANCESTORS",
name: "APPSMITH_ALLOWED_FRAME_ANCESTORS",
category: SettingCategories.GENERAL,
controlType: SettingTypes.RADIO,
label: "Embed Settings",
controlTypeProps: {
options: [
{
badge: "NOT RECOMMENDED",
tooltip: {
icon: <QuestionFillIcon />,
text:
"Lets all domains, including malicious ones, embed your Appsmith apps. ",
linkText: "SEE WHY THIS IS RISKY",
link:
"https://docs.appsmith.com/getting-started/setup/instance-configuration/frame-ancestors#why-should-i-control-this",
},
label: "Allow embedding everywhere",
value: "ALLOW_EMBEDDING_EVERYWHERE",
},
{
label: "Limit embedding to certain URLs",
value: "LIMIT_EMBEDDING",
nodeLabel: "You can add one or more URLs",
node: <TagInput input={{}} placeholder={""} type={"text"} />,
nodeInputPath: "input",
nodeParentClass: "tag-input",
},
{
label: "Disable embedding everywhere",
value: "DISABLE_EMBEDDING_EVERYWHERE",
},
],
},
format: (value: string) => {
if (value === "*") {
return {
value: "ALLOW_EMBEDDING_EVERYWHERE",
};
} else if (value === "'none'") {
return {
value: "DISABLE_EMBEDDING_EVERYWHERE",
};
} else {
return {
value: "LIMIT_EMBEDDING",
additionalData: value ? value.replaceAll(" ", ",") : "",
};
}
},
parse: (value: { value: string; additionalData?: any }) => {
// Retrieve values from local storage while switching to limit by url option
const sources = isUndefined(value.additionalData)
? localStorage.getItem("ALLOWED_FRAME_ANCESTORS") ?? ""
: value.additionalData.replaceAll(",", " ");
// If they are one of the other options we don't store it in storage since it will
// set in the env variable on save
if (sources !== "*" && sources !== "'none'") {
localStorage.setItem("ALLOWED_FRAME_ANCESTORS", sources);
}

if (value.value === "ALLOW_EMBEDDING_EVERYWHERE") {
return "*";
} else if (value.value === "DISABLE_EMBEDDING_EVERYWHERE") {
return "'none'";
} else {
return sources;
}
},
validate: (value: string) => {
if (!value) {
return "This field cannot be empty";
}
},
};

export const config: AdminConfigType = {
icon: "settings-2-line",
type: SettingCategories.GENERAL,
Expand All @@ -93,5 +174,6 @@ export const config: AdminConfigType = {
APPSMITH_DOWNLOAD_DOCKER_COMPOSE_FILE_SETTING,
APPSMITH_DISABLE_TELEMETRY_SETTING,
APPSMITH_HIDE_WATERMARK_SETTING,
APPSMITH_ALLOWED_FRAME_ANCESTORS_SETTING,
],
} as AdminConfigType;
31 changes: 28 additions & 3 deletions app/client/src/ce/pages/AdminSettings/config/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,32 @@ import React from "react";
import { ReduxAction } from "@appsmith/constants/ReduxActionConstants";
import { Dispatch } from "react";
import { EventName } from "utils/AnalyticsUtil";
import { RadioProps } from "pages/Settings/FormGroup/Radio";

type ControlType = {
[K in keyof ControlPropsType]: {
controlType: K;
controlTypeProps?: ControlPropsType[K];
};
}[keyof ControlPropsType];

type ControlPropsType = {
[SettingTypes.RADIO]: RadioProps;
[SettingTypes.TEXTINPUT]: unknown;
[SettingTypes.TOGGLE]: unknown;
[SettingTypes.LINK]: unknown;
[SettingTypes.BUTTON]: unknown;
[SettingTypes.GROUP]: unknown;
[SettingTypes.TEXT]: unknown;
[SettingTypes.UNEDITABLEFIELD]: unknown;
[SettingTypes.ACCORDION]: unknown;
[SettingTypes.TAGINPUT]: unknown;
[SettingTypes.DROPDOWN]: unknown;
[SettingTypes.CHECKBOX]: unknown;
};

export enum SettingTypes {
RADIO = "RADIO",
TEXTINPUT = "TEXTINPUT",
TOGGLE = "TOGGLE",
LINK = "LINK",
Expand All @@ -25,11 +49,12 @@ export enum SettingSubtype {
PASSWORD = "password",
}

export interface Setting {
export type Setting = ControlType & {
id: string;
category?: string;
controlType: SettingTypes;
controlSubType?: SettingSubtype;
format?: (value: string) => any;
parse?: (value: any) => any;
helpText?: string;
label?: string;
name?: string;
Expand Down Expand Up @@ -60,7 +85,7 @@ export interface Setting {
needsUpgrade?: boolean;
upgradeLogEventName?: EventName;
upgradeIntercomMessage?: string;
}
};

export interface Category {
title: string;
Expand Down
1 change: 1 addition & 0 deletions app/client/src/pages/AppViewer/AppViewerHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ export function AppViewerHeader(props: AppViewerHeaderProps) {
}
buttonVariant="SECONDARY"
className="h-8"
data-cy="viewmode-share"
text="Share"
/>
}
Expand Down
6 changes: 4 additions & 2 deletions app/client/src/pages/Settings/FormGroup/Accordion.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@ import React from "react";
import {
SettingTypes,
SettingSubtype,
Setting,
} from "@appsmith/pages/AdminSettings/config/types";
import Accordion from "./Accordion";
import { SETTINGS_FORM_NAME } from "@appsmith/constants/forms";
import { reduxForm } from "redux-form";

let container: any = null;
const setting = {
const setting: Setting = {
id: "SETTING_TOGGLE_ID",
name: "SETTING_TOGGLE_ID",
category: "test category",
Expand Down Expand Up @@ -53,7 +54,8 @@ function renderComponent() {
form: {
[SETTINGS_FORM_NAME]: {
values: {
[setting.advanced[0].id]: false,
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
[setting.advanced![0].id]: false,
akash-codemonk marked this conversation as resolved.
Show resolved Hide resolved
},
},
},
Expand Down
7 changes: 5 additions & 2 deletions app/client/src/pages/Settings/FormGroup/Button.test.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import { render, screen } from "test/testUtils";
import React from "react";
import { SettingTypes } from "@appsmith/pages/AdminSettings/config/types";
import {
Setting,
SettingTypes,
} from "@appsmith/pages/AdminSettings/config/types";
import ButtonComponent from "./Button";

let container: any = null;
const buttonClickHandler = jest.fn();
const buttonIsDisabled = jest.fn();
const setting = {
const setting: Setting = {
id: "SETTING_ID",
text: "download",
action: buttonClickHandler,
Expand Down
7 changes: 5 additions & 2 deletions app/client/src/pages/Settings/FormGroup/Group.test.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import { render, screen } from "test/testUtils";
import React from "react";
import { SettingTypes } from "@appsmith/pages/AdminSettings/config/types";
import {
Setting,
SettingTypes,
} from "@appsmith/pages/AdminSettings/config/types";
import Group from "./group";
import { SETTINGS_FORM_NAME } from "@appsmith/constants/forms";
import { reduxForm } from "redux-form";

let container: any = null;
const settings = [
const settings: Setting[] = [
{
id: "test",
name: "test",
Expand Down
7 changes: 5 additions & 2 deletions app/client/src/pages/Settings/FormGroup/Link.test.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import { render, screen } from "test/testUtils";
import React from "react";
import { SettingTypes } from "@appsmith/pages/AdminSettings/config/types";
import {
Setting,
SettingTypes,
} from "@appsmith/pages/AdminSettings/config/types";
import Link from "./Link";

let container: any = null;
const linkClickHandler = jest.fn();
const setting = {
const setting: Setting = {
id: "SETTING_ID",
isHidden: false,
label: "setting label",
Expand Down
Loading
Loading