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

Add infrastructure for consent banner and link #3191

Merged
merged 61 commits into from
May 13, 2023
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
ee22baa
parent 9149f2f211cfea68bfa9f5c770fec3a79d31744b
eastandwestwind Apr 25, 2023
06e46cb
fixing some conflicts from rebase
eastandwestwind May 8, 2023
d4bef32
Refactor ConsentBannerButton into a Preact FunctionComponent function
NevilleS May 8, 2023
7655725
Move ConsentBannerButton to a new "components" folder
NevilleS May 8, 2023
88e12ef
adds duplicate banner demo page that allows for config to be injected…
eastandwestwind May 8, 2023
19ffcbd
cypress tests are working for consent banner
eastandwestwind May 9, 2023
69f672a
regenerate package-lock, add back turbo output cache
eastandwestwind May 9, 2023
cfa8110
fix eslint configs
eastandwestwind May 9, 2023
92c7e85
remove public/lib file, rename css vars
eastandwestwind May 9, 2023
71ee51e
restructure some components to functional, removes link component
eastandwestwind May 9, 2023
55eccc0
inject accept/reject events from fides parent for the banner
eastandwestwind May 9, 2023
bf59c50
Add note about aliasing react imports
NevilleS May 9, 2023
39b1618
Update tsconfig to include tsx
allisonking May 9, 2023
af0282e
Swap href instead of using onClick for anchor component
allisonking May 9, 2023
e5723b5
Export debugLog as a function instead of default
allisonking May 9, 2023
a815fd2
clarify diff between banner demo pages
eastandwestwind May 9, 2023
878e00c
Update clients/fides-js/src/lib/cookie.ts
eastandwestwind May 9, 2023
5f64996
Fix accept all and reject all logic
allisonking May 9, 2023
1acf4ae
Run prettier
allisonking May 9, 2023
b6f8e26
Run prettier on privacy center
allisonking May 9, 2023
db0ce36
Run prettier on PC README
allisonking May 9, 2023
902ae80
refactor to inject legacy consent, consent experience, geolocation, a…
eastandwestwind May 10, 2023
675eff9
banner props should default properly
eastandwestwind May 10, 2023
9c26448
move eslint config, update banner to support banner title
eastandwestwind May 10, 2023
fe992d7
remove unneeded npm dev dependency in fides-js
eastandwestwind May 10, 2023
5ac8512
re-enable some eslint rules
eastandwestwind May 10, 2023
482b7ec
Get cypress to run again
allisonking May 10, 2023
1962cd4
Update cypress test to use win.fidesConfig
allisonking May 10, 2023
d33ffab
Allow visitConsentDemo to hang out with its friends
allisonking May 10, 2023
333adaa
Merge branch 'main' into banner-infra
allisonking May 10, 2023
83d2271
Format
allisonking May 10, 2023
6cb4b2e
Update package-lock.json
allisonking May 10, 2023
fb407ed
remove unneeded tslint config
eastandwestwind May 10, 2023
4e2866d
remove passing consent defaults into init, fix circular deps
eastandwestwind May 10, 2023
d8f7377
Patch package-lock for turbo in different architectures
allisonking May 10, 2023
428b183
Autoformat
allisonking May 10, 2023
f3755b2
fix jest in fides-js
eastandwestwind May 10, 2023
21b7883
Only render ConsentBanner after mount
allisonking May 11, 2023
5fd0574
do not render banner by default
eastandwestwind May 11, 2023
7be8b35
config.options is required by package
eastandwestwind May 11, 2023
48d4a21
Merge branch 'main' of github.com:ethyca/fides into banner-infra
eastandwestwind May 12, 2023
c9ca6da
add to changelog
eastandwestwind May 12, 2023
7fa2e94
remove unneeded deps
eastandwestwind May 12, 2023
f0cac32
remove unneeded todo, update privacy center readme
eastandwestwind May 12, 2023
d66c260
rename isDisabled to isOverlayDisabled
eastandwestwind May 12, 2023
2bca847
small renaming, refactor todos into callback func
eastandwestwind May 12, 2023
fc31dc4
Refactor consent.tsx to render App
allisonking May 11, 2023
409d3f3
cleanup after cherry-picking to add new App component
eastandwestwind May 12, 2023
8d1627b
prettier
eastandwestwind May 12, 2023
d461a27
add logic to prevent retrieving geolocation under certain conditions,…
eastandwestwind May 12, 2023
bd35fe9
add check for DOM loaded before adding listener
eastandwestwind May 12, 2023
1b50997
Make the CHANGELOG entry more exciting!
NevilleS May 12, 2023
15160ee
Unbundle the FidesConfig and pass explicit props to initOverlay
NevilleS May 12, 2023
0f8769e
Rename App -> Overlay
NevilleS May 12, 2023
adfee4e
Add a prop for manage preferences link label
NevilleS May 12, 2023
bfb7461
Fix gitignore
NevilleS May 12, 2023
077db9a
Add tests for makeConsentDefaults
NevilleS May 13, 2023
bdf9ab5
Add tests for setConsentCookie
NevilleS May 13, 2023
6d06ab2
Remove TODO
NevilleS May 13, 2023
590c826
Format
NevilleS May 13, 2023
6920461
Merge branch 'main' of github.com:ethyca/fides into banner-infra
NevilleS May 13, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 5 additions & 0 deletions clients/fides-js/.eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,15 @@
"project": "./tsconfig.json"
},
"rules": {
"react/jsx-filename-extension": [2, { "extensions": [",.js", ".jsx", ".ts", ".tsx"] }],
"curly": ["error", "all"],
"nonblock-statement-body-position": ["error", "below"],
"import/prefer-default-export": "off",
"import/extensions": "off",
"react/react-in-jsx-scope": "off",
"react/prop-types": "off",
"react/button-has-type": "off",
"react/function-component-definition": "off",
eastandwestwind marked this conversation as resolved.
Show resolved Hide resolved
"no-param-reassign": [
"error",
{
Expand Down
2 changes: 1 addition & 1 deletion clients/fides-js/__tests__/lib/cookie.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
getOrMakeFidesCookie,
makeFidesCookie,
saveFidesCookie,
} from "~/lib/cookie";
} from "../../src/lib/cookie";
allisonking marked this conversation as resolved.
Show resolved Hide resolved

// Setup mock date
const MOCK_DATE = "2023-01-01T12:00:00.000Z";
Expand Down
14 changes: 13 additions & 1 deletion clients/fides-js/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"directory": "clients/fides-js"
},
"dependencies": {
"preact": "^10.13.2",
"typescript-cookie": "^1.0.6",
"uuid": "^9.0.0"
},
Expand All @@ -37,17 +38,28 @@
"eslint": "^8.36.0",
"eslint-config-airbnb": "^19.0.4",
"eslint-config-airbnb-typescript": "^17.0.0",
"eslint-config-preact": "^1.3.0",
"eslint-config-prettier": "^8.8.0",
"eslint-plugin-import": "^2.27.5",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-promise": "^6.1.1",
eastandwestwind marked this conversation as resolved.
Show resolved Hide resolved
"eslint-plugin-react": "^7.32.2",
"jest": "^29.5.0",
"jest-environment-jsdom": "^29.5.0",
"js-cookie": "^3.0.5",
"npm": "^9.6.5",
eastandwestwind marked this conversation as resolved.
Show resolved Hide resolved
"prettier": "^2.8.8",
"rollup": "^3.21.3",
"rollup-plugin-copy": "^3.4.0",
"rollup-plugin-dts": "^5.3.0",
"rollup-plugin-esbuild": "^5.0.0",
"rollup-plugin-filesize": "^10.0.0",
"rollup-plugin-import-css": "^3.2.1",
"ts-jest": "^29.1.0",
"typescript": "^4.9.5"
"typescript": "^4.9.5",
"typescript-plugin-css-modules": "^5.0.1"
},
"eslintConfig": {
"extends": "preact"
eastandwestwind marked this conversation as resolved.
Show resolved Hide resolved
eastandwestwind marked this conversation as resolved.
Show resolved Hide resolved
}
}
14 changes: 12 additions & 2 deletions clients/fides-js/rollup.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import dts from "rollup-plugin-dts";
import esbuild from "rollup-plugin-esbuild";
import filesize from "rollup-plugin-filesize";
import nodeResolve from "@rollup/plugin-node-resolve";
import css from "rollup-plugin-import-css";

const name = "fides";
const isDev = process.env.NODE_ENV === "development";
Expand All @@ -17,6 +18,7 @@ export default [
input: `src/${name}.ts`,
plugins: [
nodeResolve(),
css(),
esbuild({
minify: !isDev,
}),
Expand All @@ -28,6 +30,14 @@ export default [
verbose: true,
hook: "writeBundle",
}),
copy({
// Automatically add the built css to the privacy center's static files for bundling:
targets: [
{ src: `dist/${name}.css`, dest: "../privacy-center/public/lib/" },
],
verbose: true,
eastandwestwind marked this conversation as resolved.
Show resolved Hide resolved
hook: "writeBundle",
}),
filesize({
reporter: [
"boxen", // default reporter, which prints a nice CLI output
Expand Down Expand Up @@ -70,7 +80,7 @@ export default [
},
{
input: `src/${name}.ts`,
plugins: [nodeResolve(), esbuild()],
plugins: [nodeResolve(), css(), esbuild()],
output: [
{
// Compatible with ES module imports. Apps in this repo may be able to share the code.
Expand All @@ -82,7 +92,7 @@ export default [
},
{
input: `src/${name}.ts`,
plugins: [dts()],
plugins: [dts(), css()],
output: [
{
file: `dist/${name}.d.ts`,
Expand Down
82 changes: 82 additions & 0 deletions clients/fides-js/src/components/ConsentBanner.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import {h, FunctionComponent} from "preact";
import {useState, useEffect} from "preact/hooks";
import {ButtonType, ConsentBannerOptions} from "../lib/consent-types";
import debugLog from "../lib/consent-utils";
import ConsentBannerButton from "./ConsentBannerButton";
import "../lib/banner.module.css";

interface BannerProps {
options: ConsentBannerOptions;
onAcceptAll: () => void;
onRejectAll: () => void;
waitBeforeShow: number;
}

const ConsentBanner: FunctionComponent<BannerProps> = (
{ options, onAcceptAll, onRejectAll, waitBeforeShow }
) => {
const [isShown, setIsShown] = useState(false)
useEffect(() => {
const delayBanner = setTimeout(() => {
setIsShown(true)
}, waitBeforeShow)
return () => clearTimeout(delayBanner)
}, [setIsShown, waitBeforeShow])
const navigateToPrivacyCenter = (): void => {
debugLog("Navigate to Privacy Center URL:", options.privacyCenterUrl);
if (options.privacyCenterUrl) {
window.location.assign(options.privacyCenterUrl);
}
};
// TODO: support option to specify top/bottom
return (
<div
id="fides-consent-banner"
className={`fides-consent-banner fides-consent-banner-bottom ${
isShown ? "" : "fides-consent-banner-hidden"
} `}
>
<div
id="fides-consent-banner-description"
className="fides-consent-banner-description"
>
{options.labels?.bannerDescription || ""}
</div>
<div
id="fides-consent-banner-buttons"
className="fides-consent-banner-buttons"
>
<ConsentBannerButton
buttonType={ButtonType.TERTIARY}
label={options.labels?.tertiaryButton}
onClick={navigateToPrivacyCenter} />
<ConsentBannerButton
buttonType={ButtonType.SECONDARY}
label={options.labels?.secondaryButton}
onClick={() => {
onRejectAll();
setIsShown(false);
// TODO: save to Fides consent request API
// eslint-disable-next-line no-console
console.error(
"Could not save consent record to Fides API, not implemented!"
);
}} />
<ConsentBannerButton
buttonType={ButtonType.PRIMARY}
label={options.labels?.primaryButton}
onClick={() => {
onAcceptAll();
setIsShown(false);
// TODO: save to Fides consent request API
// eslint-disable-next-line no-console
console.error(
"Could not save consent record to Fides API, not implemented!"
);
}} />
</div>
</div>
);
}

export default ConsentBanner;
20 changes: 20 additions & 0 deletions clients/fides-js/src/components/ConsentBannerButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import {h, FunctionComponent} from "preact";
import {ButtonType} from "../lib/consent-types";

interface ButtonProps {
buttonType: ButtonType;
label?: string,
onClick?: () => void
}

const ConsentBannerButton: FunctionComponent<ButtonProps> = ({ buttonType, label, onClick }) => (
<button
id={`fides-consent-banner-button-${buttonType.valueOf()}`}
className={`fides-consent-banner-button fides-consent-banner-button-${buttonType.valueOf()}`}
eastandwestwind marked this conversation as resolved.
Show resolved Hide resolved
onClick={onClick}
>
{label || ""}
</button>
);

export default ConsentBannerButton;
Empty file.
20 changes: 18 additions & 2 deletions clients/fides-js/src/fides.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,21 +38,26 @@ import { meta } from "./integrations/meta";
import { shopify } from "./integrations/shopify";
import { ConsentConfig } from "./lib/consent-config";
import { getConsentContext } from "./lib/consent-context";
import { initFidesConsent } from "./lib/consent";
import {
CookieKeyConsent,
CookieIdentity,
CookieMeta,
getOrMakeFidesCookie,
makeConsentDefaults,
} from "./lib/cookie";
import { ConsentBannerOptions } from "./lib/consent-types";
import { getBannerOptions } from "./lib/consent-utils";

export interface FidesConfig {
consent: ConsentConfig;
bannerOptions?: ConsentBannerOptions;
}
eastandwestwind marked this conversation as resolved.
Show resolved Hide resolved

type Fides = {
consent: CookieKeyConsent;
fides_meta: CookieMeta;
getBannerOptions: () => ConsentBannerOptions;
gtm: typeof gtm;
identity: CookieIdentity;
init: typeof init;
Expand All @@ -71,8 +76,10 @@ declare global {
// eslint-disable-next-line no-underscore-dangle,@typescript-eslint/naming-convention
let _Fides: Fides;

// Initialize the global Fides object with the given configuration values
const init = (config: FidesConfig) => {
/**
* Initialize the global Fides object with the given configuration values
*/
const init = async (config: FidesConfig) => {
// Configure the default values
const context = getConsentContext();
const defaults = makeConsentDefaults({
Expand All @@ -83,17 +90,21 @@ const init = (config: FidesConfig) => {
// Load any existing user preferences from the browser cookie
const cookie = getOrMakeFidesCookie(defaults);

await initFidesConsent(defaults, config.bannerOptions);
eastandwestwind marked this conversation as resolved.
Show resolved Hide resolved
// Initialize the window.Fides object
_Fides.consent = cookie.consent;
_Fides.getBannerOptions = getBannerOptions;
_Fides.fides_meta = cookie.fides_meta;
_Fides.identity = cookie.identity;

_Fides.initialized = true;
};

// The global Fides object; this is bound to window.Fides if available
_Fides = {
consent: {},
fides_meta: {},
getBannerOptions,
identity: {},
gtm,
init,
Expand All @@ -107,8 +118,13 @@ if (typeof window !== "undefined") {
}

// Export everything from ./lib/* to use when importing fides.mjs as a module
export * from "./lib/consent";
export * from "./components/ConsentBanner";
export * from "./lib/consent-config";
export * from "./lib/consent-context";
export * from "./lib/consent-types";
export * from "./lib/consent-utils";
export * from "./lib/consent-value";
export * from "./lib/cookie";

export default Fides;