Revert "Merge pull request #1797 from mozilla/1789-join-the-party-experiment"
This reverts commit978d4e1e3b
, reversing changes made to929381c880
.
This commit is contained in:
Родитель
b71a584ab3
Коммит
cddbf3d82c
|
@ -2,11 +2,8 @@
|
||||||
|
|
||||||
const HIBP = require("../hibp");
|
const HIBP = require("../hibp");
|
||||||
const DB = require("../db/DB");
|
const DB = require("../db/DB");
|
||||||
const AppConstants = require("../app-constants");
|
|
||||||
const { changePWLinks } = require("../lib/changePWLinks");
|
const { changePWLinks } = require("../lib/changePWLinks");
|
||||||
const { getAllEmailsAndBreaches } = require("./user");
|
const { getAllEmailsAndBreaches } = require("./user");
|
||||||
const { getExperimentFlags } = require("./utils");
|
|
||||||
const EXPERIMENTS_ENABLED = (AppConstants.EXPERIMENT_ACTIVE === "1");
|
|
||||||
|
|
||||||
async function getBreachDetail(req, res) {
|
async function getBreachDetail(req, res) {
|
||||||
const allBreaches = req.app.locals.breaches;
|
const allBreaches = req.app.locals.breaches;
|
||||||
|
@ -38,15 +35,11 @@ async function getBreachDetail(req, res) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const changePWLink = getChangePWLink(featuredBreach);
|
const changePWLink = getChangePWLink(featuredBreach);
|
||||||
|
|
||||||
const experimentFlags = getExperimentFlags(req, EXPERIMENTS_ENABLED);
|
|
||||||
|
|
||||||
res.render("breach-detail", {
|
res.render("breach-detail", {
|
||||||
title: req.fluentFormat("home-title"),
|
title: req.fluentFormat("home-title"),
|
||||||
featuredBreach,
|
featuredBreach,
|
||||||
changePWLink,
|
changePWLink,
|
||||||
affectedEmails,
|
affectedEmails,
|
||||||
experimentFlags,
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,12 +4,7 @@ const AppConstants = require("../app-constants");
|
||||||
const DB = require("../db/DB");
|
const DB = require("../db/DB");
|
||||||
const HIBP = require("../hibp");
|
const HIBP = require("../hibp");
|
||||||
const { scanResult } = require("../scan-results");
|
const { scanResult } = require("../scan-results");
|
||||||
const {
|
const { generatePageToken, getExperimentFlags } = require("./utils");
|
||||||
generatePageToken,
|
|
||||||
getExperimentBranch,
|
|
||||||
getExperimentFlags,
|
|
||||||
getUTMContents,
|
|
||||||
} = require("./utils");
|
|
||||||
|
|
||||||
const EXPERIMENTS_ENABLED = (AppConstants.EXPERIMENT_ACTIVE === "1");
|
const EXPERIMENTS_ENABLED = (AppConstants.EXPERIMENT_ACTIVE === "1");
|
||||||
|
|
||||||
|
@ -22,6 +17,7 @@ function _getFeaturedBreach(allBreaches, breachQueryValue) {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function home(req, res) {
|
async function home(req, res) {
|
||||||
|
|
||||||
const formTokens = {
|
const formTokens = {
|
||||||
pageToken: AppConstants.PAGE_TOKEN_TIMER > 0 ? generatePageToken(req) : "",
|
pageToken: AppConstants.PAGE_TOKEN_TIMER > 0 ? generatePageToken(req) : "",
|
||||||
csrfToken: req.csrfToken(),
|
csrfToken: req.csrfToken(),
|
||||||
|
@ -34,31 +30,9 @@ async function home(req, res) {
|
||||||
return res.redirect("/user/dashboard");
|
return res.redirect("/user/dashboard");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rewrites the /share/{COLOR} links to /
|
|
||||||
if (req.session.redirectHome) {
|
|
||||||
req.session.redirectHome = false;
|
|
||||||
return res.redirect("/");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Note - If utmOverrides get set, they are unenrolled from the experiment
|
|
||||||
const utmOverrides = getUTMContents(req);
|
|
||||||
const experimentFlags = getExperimentFlags(req, EXPERIMENTS_ENABLED);
|
const experimentFlags = getExperimentFlags(req, EXPERIMENTS_ENABLED);
|
||||||
|
|
||||||
// Growth Experiment
|
|
||||||
if (EXPERIMENTS_ENABLED) {
|
|
||||||
getExperimentBranch(req, false, ["en"], {
|
|
||||||
"va": 50,
|
|
||||||
"vb": 50,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (req.params && req.params.breach) {
|
|
||||||
req.query.breach = req.params.breach;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (req.query.breach) {
|
if (req.query.breach) {
|
||||||
|
|
||||||
featuredBreach = _getFeaturedBreach(req.app.locals.breaches, req.query.breach);
|
featuredBreach = _getFeaturedBreach(req.app.locals.breaches, req.query.breach);
|
||||||
|
|
||||||
if (!featuredBreach) {
|
if (!featuredBreach) {
|
||||||
|
@ -79,7 +53,6 @@ async function home(req, res) {
|
||||||
pageToken: formTokens.pageToken,
|
pageToken: formTokens.pageToken,
|
||||||
csrfToken: formTokens.csrfToken,
|
csrfToken: formTokens.csrfToken,
|
||||||
experimentFlags,
|
experimentFlags,
|
||||||
utmOverrides,
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,7 +63,6 @@ async function home(req, res) {
|
||||||
pageToken: formTokens.pageToken,
|
pageToken: formTokens.pageToken,
|
||||||
csrfToken: formTokens.csrfToken,
|
csrfToken: formTokens.csrfToken,
|
||||||
experimentFlags,
|
experimentFlags,
|
||||||
utmOverrides,
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,13 +14,6 @@ const sha1 = require("../sha1-utils");
|
||||||
|
|
||||||
const log = mozlog("controllers.oauth");
|
const log = mozlog("controllers.oauth");
|
||||||
|
|
||||||
// Growth Experiment
|
|
||||||
const utmArray = ["utm_source", "utm_medium", "utm_campaign", "utm_term", "utm_content"];
|
|
||||||
|
|
||||||
function getUTMNames() {
|
|
||||||
return utmArray;
|
|
||||||
}
|
|
||||||
|
|
||||||
function init(req, res, next, client = FxAOAuthClient) {
|
function init(req, res, next, client = FxAOAuthClient) {
|
||||||
// Set a random state string in a cookie so that we can verify
|
// Set a random state string in a cookie so that we can verify
|
||||||
// the user when they're redirected back to us after auth.
|
// the user when they're redirected back to us after auth.
|
||||||
|
@ -35,10 +28,6 @@ function init(req, res, next, client = FxAOAuthClient) {
|
||||||
url.searchParams.append("action", "email");
|
url.searchParams.append("action", "email");
|
||||||
|
|
||||||
for (const param of fxaParams.searchParams.keys()) {
|
for (const param of fxaParams.searchParams.keys()) {
|
||||||
// Growth Experiment
|
|
||||||
if (utmArray.includes(param)) {
|
|
||||||
req.session.utmContents[param] = fxaParams.searchParams.get(param);
|
|
||||||
}
|
|
||||||
url.searchParams.append(param, fxaParams.searchParams.get(param));
|
url.searchParams.append(param, fxaParams.searchParams.get(param));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,15 +57,6 @@ async function confirmed(req, res, next, client = FxAOAuthClient) {
|
||||||
|
|
||||||
const returnURL = new URL("/user/dashboard", AppConstants.SERVER_URL);
|
const returnURL = new URL("/user/dashboard", AppConstants.SERVER_URL);
|
||||||
|
|
||||||
// Growth Experiment
|
|
||||||
if (req.session.utmContents) {
|
|
||||||
getUTMNames().forEach(param => {
|
|
||||||
if (req.session.utmContents[param]) {
|
|
||||||
returnURL.searchParams.append(param, req.session.utmContents[param]);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if user is signing up or signing in,
|
// Check if user is signing up or signing in,
|
||||||
// then add new users to db and send email.
|
// then add new users to db and send email.
|
||||||
if (!existingUser || existingUser.fxa_refresh_token === null) {
|
if (!existingUser || existingUser.fxa_refresh_token === null) {
|
||||||
|
|
|
@ -12,7 +12,7 @@ const { resultsSummary } = require("../scan-results");
|
||||||
const sha1 = require("../sha1-utils");
|
const sha1 = require("../sha1-utils");
|
||||||
|
|
||||||
const EXPERIMENTS_ENABLED = (AppConstants.EXPERIMENT_ACTIVE === "1");
|
const EXPERIMENTS_ENABLED = (AppConstants.EXPERIMENT_ACTIVE === "1");
|
||||||
const { getExperimentFlags, getUTMContents } = require("./utils");
|
const { getExperimentFlags } = require("./utils");
|
||||||
|
|
||||||
const FXA_MONITOR_SCOPE = "https://identity.mozilla.com/apps/monitor";
|
const FXA_MONITOR_SCOPE = "https://identity.mozilla.com/apps/monitor";
|
||||||
|
|
||||||
|
@ -229,9 +229,7 @@ async function getDashboard(req, res) {
|
||||||
const user = req.user;
|
const user = req.user;
|
||||||
const allBreaches = req.app.locals.breaches;
|
const allBreaches = req.app.locals.breaches;
|
||||||
const { verifiedEmails, unverifiedEmails } = await getAllEmailsAndBreaches(user, allBreaches);
|
const { verifiedEmails, unverifiedEmails } = await getAllEmailsAndBreaches(user, allBreaches);
|
||||||
const utmOverrides = getUTMContents(req);
|
|
||||||
|
|
||||||
// Growth Experiment
|
|
||||||
const experimentFlags = getExperimentFlags(req, EXPERIMENTS_ENABLED);
|
const experimentFlags = getExperimentFlags(req, EXPERIMENTS_ENABLED);
|
||||||
|
|
||||||
let lastAddedEmail = null;
|
let lastAddedEmail = null;
|
||||||
|
@ -250,7 +248,6 @@ async function getDashboard(req, res) {
|
||||||
unverifiedEmails,
|
unverifiedEmails,
|
||||||
whichPartial: "dashboards/breaches-dash",
|
whichPartial: "dashboards/breaches-dash",
|
||||||
experimentFlags,
|
experimentFlags,
|
||||||
utmOverrides,
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -564,18 +561,6 @@ async function getBreachStats(req, res) {
|
||||||
|
|
||||||
|
|
||||||
function logout(req, res) {
|
function logout(req, res) {
|
||||||
// Growth Experiment
|
|
||||||
if (EXPERIMENTS_ENABLED && req.session.experimentFlags) {
|
|
||||||
// Persist experimentBranch across session reset
|
|
||||||
const sessionExperimentFlags = req.session.experimentFlags;
|
|
||||||
req.session.reset();
|
|
||||||
req.session.experimentFlags = sessionExperimentFlags;
|
|
||||||
|
|
||||||
// Return
|
|
||||||
res.redirect("/");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
req.session.reset();
|
req.session.reset();
|
||||||
res.redirect("/");
|
res.redirect("/");
|
||||||
}
|
}
|
||||||
|
|
|
@ -182,23 +182,9 @@ function getExperimentBranch(req, sorterNum = false, language = false, variation
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getUTMContents(req) {
|
|
||||||
if (!req) {
|
|
||||||
throw new Error("No request available");
|
|
||||||
}
|
|
||||||
|
|
||||||
// If UTMs are set previously, set them again.
|
|
||||||
if (req.session.utmOverrides) {
|
|
||||||
return req.session.utmOverrides;
|
|
||||||
}
|
|
||||||
|
|
||||||
req.session.utmOverrides = false;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getExperimentFlags(req, EXPERIMENTS_ENABLED) {
|
function getExperimentFlags(req, EXPERIMENTS_ENABLED) {
|
||||||
if (!req) {
|
if (!req) {
|
||||||
throw new Error("No request available");
|
throw new Error("No request availabe");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (req.session.experimentFlags && EXPERIMENTS_ENABLED) {
|
if (req.session.experimentFlags && EXPERIMENTS_ENABLED) {
|
||||||
|
@ -222,5 +208,4 @@ module.exports = {
|
||||||
hasUserSignedUpForRelay,
|
hasUserSignedUpForRelay,
|
||||||
getExperimentBranch,
|
getExperimentBranch,
|
||||||
getExperimentFlags,
|
getExperimentFlags,
|
||||||
getUTMContents,
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,20 +0,0 @@
|
||||||
_Last updated: Aug 8, 2020_
|
|
||||||
|
|
||||||
# Firefox Monitor Experiment Deployment Process
|
|
||||||
|
|
||||||
This is the experiment process plan for Firefox Monitor. It documents how to deploy experiments and take them down.
|
|
||||||
|
|
||||||
## ENV Variable
|
|
||||||
|
|
||||||
Use the variable `EXPERIMENT_ACTIVE` to enable experiments in your environment.
|
|
||||||
|
|
||||||
- If set to `1` - Experiment code is visible and active.
|
|
||||||
- If NOT set `1` – Experiment code is hidden and not active.
|
|
||||||
|
|
||||||
## Tagging System
|
|
||||||
|
|
||||||
To deploy with the ENV variable set to `1`, add `-exp` to your version tag.
|
|
||||||
|
|
||||||
Example: `v12.14.2-exp`
|
|
||||||
|
|
||||||
Any tag without the `-exp` will disable experiments at an ENV level.
|
|
|
@ -15,7 +15,6 @@ const { FXA } = require("./lib/fxa");
|
||||||
const { FluentError } = require("./locale-utils");
|
const { FluentError } = require("./locale-utils");
|
||||||
const mozlog = require("./log");
|
const mozlog = require("./log");
|
||||||
|
|
||||||
const HIBP = require("./hibp");
|
|
||||||
|
|
||||||
const log = mozlog("middleware");
|
const log = mozlog("middleware");
|
||||||
|
|
||||||
|
@ -174,63 +173,6 @@ async function requireSessionUser(req, res, next) {
|
||||||
next();
|
next();
|
||||||
}
|
}
|
||||||
|
|
||||||
function getShareUTMs(req, res, next) {
|
|
||||||
// Step 1: See if the user needs to be redirected to the homepage or to a breach-detail page.
|
|
||||||
const generalShareUrls = [
|
|
||||||
"/share/orange", //Header
|
|
||||||
"/share/purple", // Footer
|
|
||||||
"/share/blue", // user/dashboard
|
|
||||||
"/share/",
|
|
||||||
];
|
|
||||||
|
|
||||||
if (generalShareUrls.includes(req.url)) {
|
|
||||||
// If not breach specific, redirect to "/"
|
|
||||||
req.session.redirectHome = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
const inNotInActiveExperiment = (!req.session.experimentFlags);
|
|
||||||
|
|
||||||
// Excluse user from experiment if they don't have any experimentFlags set already.
|
|
||||||
if (inNotInActiveExperiment) {
|
|
||||||
|
|
||||||
// Step 2: Determine if user needs to have share-link UTMs set
|
|
||||||
const colors = [
|
|
||||||
"orange", //Header
|
|
||||||
"purple", // Footer
|
|
||||||
"blue", // user/dashboard
|
|
||||||
];
|
|
||||||
|
|
||||||
const urlArray = req.url.split("/");
|
|
||||||
const color = urlArray.slice(-1)[0];
|
|
||||||
|
|
||||||
req.session.utmOverrides = {
|
|
||||||
campaignName: "shareLinkTraffic",
|
|
||||||
campaignTerm: "default",
|
|
||||||
};
|
|
||||||
|
|
||||||
// Set Color Var in UTM
|
|
||||||
if (color.length && colors.includes(color)) {
|
|
||||||
req.session.utmOverrides.campaignTerm = color;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (color.length && !colors.includes(color)) {
|
|
||||||
const allBreaches = req.app.locals.breaches;
|
|
||||||
const breachName = color;
|
|
||||||
const featuredBreach = HIBP.getBreachByName(allBreaches, breachName);
|
|
||||||
|
|
||||||
if (featuredBreach) {
|
|
||||||
req.session.utmOverrides.campaignTerm = featuredBreach.Name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Exclude share users
|
|
||||||
req.session.experimentFlags = {
|
|
||||||
excludeFromExperiment: true,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
next();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
@ -243,5 +185,4 @@ module.exports = {
|
||||||
clientErrorHandler,
|
clientErrorHandler,
|
||||||
errorHandler,
|
errorHandler,
|
||||||
requireSessionUser,
|
requireSessionUser,
|
||||||
getShareUTMs,
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,232 +0,0 @@
|
||||||
.email-cards.experiment .share-monitor--dashboard {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.email-cards.experiment .share-monitor--dashboard ~ .share-monitor--dashboard {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.share-monitor--dashboard {
|
|
||||||
margin: 0 0 3rem;
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.share-monitor--dashboard h3 {
|
|
||||||
margin-bottom: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.share-monitor--dashboard ~ .share-monitor--dashboard {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.share-monitor--dashboard img {
|
|
||||||
display: block;
|
|
||||||
margin: 0 auto 1rem;
|
|
||||||
max-width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.share-monitor--dashboard a {
|
|
||||||
font-size: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.share-monitor--breach {
|
|
||||||
margin: calc(var(--padding) * 2.5) auto 0;
|
|
||||||
border-radius: 0.7rem;
|
|
||||||
background: var(--monitorGradient);
|
|
||||||
padding: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.share-monitor--breach img {
|
|
||||||
margin-right: 2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.share-monitor--breach .inset {
|
|
||||||
background: rgba(255, 255, 255, 1);
|
|
||||||
border-radius: 0.575rem;
|
|
||||||
padding: calc(var(--padding) * 1.5);
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: flex-start;
|
|
||||||
}
|
|
||||||
|
|
||||||
.share-monitor--breach h3 {
|
|
||||||
margin-bottom: 0.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.share-monitor--breach a {
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.share-monitor--modal {
|
|
||||||
padding: 0;
|
|
||||||
height: 100vh;
|
|
||||||
width: 100vw;
|
|
||||||
position: fixed;
|
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
z-index: 1000;
|
|
||||||
background: rgba(255, 255, 255, 0.8);
|
|
||||||
display: none;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
.share-monitor--modal-content {
|
|
||||||
background-color: var(--inkDark);
|
|
||||||
max-width: 800px;
|
|
||||||
width: 80vw;
|
|
||||||
position: absolute;
|
|
||||||
top: 50%;
|
|
||||||
left: 50%;
|
|
||||||
transform: translate(-50%, -50%);
|
|
||||||
border-radius: 4px;
|
|
||||||
padding: 2rem;
|
|
||||||
color: #ededf0;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
background-image: url("/img/modal-bg-left.png"), url("/img/modal-bg-right.png");
|
|
||||||
background-repeat: no-repeat, no-repeat;
|
|
||||||
background-position: bottom left, bottom right;
|
|
||||||
|
|
||||||
/* 6:10 ratio */
|
|
||||||
background-size: 120px auto, 200px auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.share-monitor--modal-text {
|
|
||||||
max-width: 560px;
|
|
||||||
width: 100%;
|
|
||||||
padding: 1em 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.share-monitor--modal-text .hidden {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.share-monitor--modal-text h2 {
|
|
||||||
color: #ffffff;
|
|
||||||
font-size: 32px;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.share-monitor--modal-text p {
|
|
||||||
text-align: left;
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.button-modal-close {
|
|
||||||
position: absolute;
|
|
||||||
top: 16px;
|
|
||||||
right: 16px;
|
|
||||||
height: 32px;
|
|
||||||
width: 32px;
|
|
||||||
border: none;
|
|
||||||
background-image: url("/img/svg/x-close-white.svg");
|
|
||||||
background-size: contain;
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
background-position: center center;
|
|
||||||
border-radius: 50%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.copy-form {
|
|
||||||
display: flex;
|
|
||||||
max-width: 400px;
|
|
||||||
width: 100%;
|
|
||||||
margin: 1em auto 0.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.copy-form-btn {
|
|
||||||
background: var(--blue3);
|
|
||||||
color: white;
|
|
||||||
appearance: none;
|
|
||||||
-moz-appearance: none;
|
|
||||||
border: none;
|
|
||||||
padding: 0 1rem;
|
|
||||||
font-size: 16px;
|
|
||||||
height: 50px;
|
|
||||||
line-height: 50px;
|
|
||||||
display: block;
|
|
||||||
width: 80px;
|
|
||||||
text-align: center;
|
|
||||||
border-radius: 0 4px 4px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.copy-form-btn span {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.copy-form-input {
|
|
||||||
background: #ffffff;
|
|
||||||
padding: 0 0 0 1em;
|
|
||||||
appearance: none;
|
|
||||||
-moz-appearance: none;
|
|
||||||
display: block;
|
|
||||||
width: calc(100% - 80px);
|
|
||||||
max-width: 320px;
|
|
||||||
font-size: 16px;
|
|
||||||
border: none;
|
|
||||||
outline: none;
|
|
||||||
height: 50px;
|
|
||||||
line-height: 50px;
|
|
||||||
border-radius: 4px 0 0 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.share-monitor--modal-content .disclaimer {
|
|
||||||
font-size: 0.75rem;
|
|
||||||
max-width: 340px;
|
|
||||||
margin-left: auto;
|
|
||||||
margin-right: auto;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (max-width: 600px) {
|
|
||||||
.share-monitor--dashboard img {
|
|
||||||
margin-top: 2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.share-monitor--dashboard h3 {
|
|
||||||
font-size: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.share-monitor--dashboard a {
|
|
||||||
font-size: 18px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.share-monitor--breach .inset {
|
|
||||||
display: block;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.share-monitor--breach img {
|
|
||||||
margin: 0 0 1rem;
|
|
||||||
}
|
|
||||||
.share-monitor--modal-content {
|
|
||||||
width: 90vw;
|
|
||||||
background-image: none;
|
|
||||||
}
|
|
||||||
.copy-form {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
.copy-form-input {
|
|
||||||
width: 100%;
|
|
||||||
border-radius: 4px;
|
|
||||||
padding: 1em;
|
|
||||||
height: auto;
|
|
||||||
line-height: normal;
|
|
||||||
max-width: 100%;
|
|
||||||
}
|
|
||||||
.copy-form-btn {
|
|
||||||
margin-top: 1rem;
|
|
||||||
width: 100%;
|
|
||||||
border-radius: 4px;
|
|
||||||
height: auto;
|
|
||||||
line-height: normal;
|
|
||||||
padding: 1em 12px;
|
|
||||||
}
|
|
||||||
.copy-form-btn span {
|
|
||||||
display: inline;
|
|
||||||
}
|
|
||||||
.share-monitor--modal-text h2 {
|
|
||||||
font-size: 28px;
|
|
||||||
}
|
|
||||||
}
|
|
Двоичные данные
public/img/modal-bg-left.png
Двоичные данные
public/img/modal-bg-left.png
Двоичный файл не отображается.
До Ширина: | Высота: | Размер: 6.1 KiB |
Двоичные данные
public/img/modal-bg-right.png
Двоичные данные
public/img/modal-bg-right.png
Двоичный файл не отображается.
До Ширина: | Высота: | Размер: 4.7 KiB |
|
@ -1,27 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<svg width="64px" height="64px" viewBox="0 0 64 64" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
||||||
<title>present</title>
|
|
||||||
<g id="Primary-Flow" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
|
||||||
<g id="Resolving-a-Breach---Return-Visit" transform="translate(-652.000000, -1337.000000)" fill-rule="nonzero">
|
|
||||||
<g id="Email-Addresses" transform="translate(273.000000, 753.000000)">
|
|
||||||
<g id="Breach-List" transform="translate(0.000000, 76.000000)">
|
|
||||||
<g id="Promo-/-Condensed-/-Lockwise" transform="translate(99.000000, 508.000000)">
|
|
||||||
<g id="Group" transform="translate(107.000000, 0.000000)">
|
|
||||||
<g id="firefox_illustrations-fullcolor_recommendation-64" transform="translate(173.000000, 0.000000)">
|
|
||||||
<path d="M64,20.5111111 C64,19.4310876 63.124468,18.5555556 62.0444444,18.5555556 L1.95555556,18.5555556 C0.879554894,18.5652064 0.00965081065,19.4351104 0,20.5111111 L0,32.7777778 L64,32.7777778 L64,20.5111111 Z" id="Path" fill="#FFEA80"></path>
|
|
||||||
<path d="M5.33332985,32.7777778 L5.33332985,61.3288889 C5.3323905,61.7912107 5.52301906,62.2332651 5.85988024,62.5499146 C6.19674143,62.8665641 6.64973114,63.0295109 7.11111111,63 L56.9955556,63 C57.9184847,63 58.6666667,62.2518181 58.6666667,61.3288889 L58.6666667,32.7777778 L5.33332985,32.7777778 Z" id="Path" fill="#FFD567"></path>
|
|
||||||
<polygon id="Path" fill="#FF8A50" points="23.1111111 18.5555556 40.8888889 18.5555556 40.8888889 32.7777778 23.1111111 32.7777778"></polygon>
|
|
||||||
<polygon id="Path" fill="#FF7139" points="23.1111111 32.7777778 40.8888889 32.7777778 40.8888889 63 23.1111111 63"></polygon>
|
|
||||||
<polygon id="Path" fill="#E25920" points="23.1111111 32.7777778 40.8888889 32.7777778 40.8888889 38.1111111 23.1111111 38.1111111"></polygon>
|
|
||||||
<polygon id="Path" fill="#FFBD4F" points="5.33333333 32.7777778 23.1111111 32.7777778 23.1111111 38.1111111 5.33333333 38.1111111"></polygon>
|
|
||||||
<polygon id="Path" fill="#FFBD4F" points="40.8888889 32.7777778 58.6666667 32.7777778 58.6666667 38.1111111 40.8888889 38.1111111"></polygon>
|
|
||||||
<path d="M33.1733333,17.1155556 C21.8666667,11.5866667 19.3955556,6.32444444 20.32,2.52 C16.96,6.07555556 16.3911111,12.9911111 31.3955556,20.2977778 C39.52,16.3155556 43.0755556,12.4933333 44.1066667,9.24 C41.0736406,12.6238459 37.3436905,15.310623 33.1733333,17.1155556 Z" id="Path" fill="#E31587"></path>
|
|
||||||
<path d="M33.1733333,17.1155556 C37.3403654,15.3209947 41.0700462,12.6465407 44.1066667,9.27555556 C44.9555031,6.60772154 44.080198,3.69239078 41.9022222,1.93333333 C38.0622222,-1.51555556 33.1911111,1.61333333 31.4311111,4.97333333 C29.6533333,1.61333333 24.7822222,-1.51555556 20.9422222,1.93333333 C20.7335743,2.11534289 20.5375651,2.31135203 20.3555556,2.52 C19.3955556,6.32444444 21.8666667,11.5866667 33.1733333,17.1155556 L33.1733333,17.1155556 Z" id="Path" fill="#FF298A"></path>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
До Ширина: | Высота: | Размер: 3.3 KiB |
|
@ -1 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="x-close" width="16" height="16" viewBox="0 0 16 16"><path fill="#ffffff" d="M9.061 8l3.47-3.47a.75.75 0 0 0-1.061-1.06L8 6.939 4.53 3.47a.75.75 0 1 0-1.06 1.06L6.939 8 3.47 11.47a.75.75 0 1 0 1.06 1.06L8 9.061l3.47 3.47a.75.75 0 0 0 1.06-1.061z"></path></svg>
|
|
До Ширина: | Высота: | Размер: 307 B |
|
@ -1,101 +0,0 @@
|
||||||
"use strict";
|
|
||||||
|
|
||||||
/* global ga */
|
|
||||||
|
|
||||||
function selectURL(e, skipAnalyticsPing = false) {
|
|
||||||
const shareModalInput = document.getElementById("shareModalInput");
|
|
||||||
|
|
||||||
// If an a user-init'd focus, send analytics ping
|
|
||||||
if (!skipAnalyticsPing) {
|
|
||||||
sendShareModalPing(shareModalInput);
|
|
||||||
}
|
|
||||||
|
|
||||||
shareModalInput.select();
|
|
||||||
shareModalInput.setSelectionRange(0, 99999);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function copyURL(e) {
|
|
||||||
sendShareModalPing(e.target);
|
|
||||||
const shareModalInput = document.getElementById("shareModalInput");
|
|
||||||
// Remove select listener after this event is fired. (Dup engagement)
|
|
||||||
shareModalInput.removeEventListener("focus", selectURL);
|
|
||||||
selectURL(null, true);
|
|
||||||
document.execCommand("copy");
|
|
||||||
}
|
|
||||||
|
|
||||||
function keyPress(e) {
|
|
||||||
if(e.key === "Escape") {
|
|
||||||
closeShareModal();
|
|
||||||
document.removeEventListener("keydown", keyPress);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function closeShareModal() {
|
|
||||||
const shareModal = document.getElementById("shareModal");
|
|
||||||
shareModal.style.display = "none";
|
|
||||||
}
|
|
||||||
|
|
||||||
function sendShareModalPing(el) {
|
|
||||||
if (typeof(ga) !== "undefined") {
|
|
||||||
const eventCategory = "[v2] exp5-share-modal";
|
|
||||||
const eventAction = el.dataset.eventAction;
|
|
||||||
const eventLabel = `Link ID: ${el.dataset.eventLabel}`;
|
|
||||||
const options = {};
|
|
||||||
return ga("send", "event", eventCategory, eventAction, eventLabel, options);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function initShareModal(target, breachText) {
|
|
||||||
const shareModal = document.getElementById("shareModal");
|
|
||||||
const shareModalInput = document.getElementById("shareModalInput");
|
|
||||||
const shareModalCopy = document.getElementById("shareModalCopy");
|
|
||||||
const btnCloseShareModal = document.getElementById("closeShareModal");
|
|
||||||
const shareTextBreach = document.getElementById("shareTextBreach");
|
|
||||||
const shareTextGeneral = document.getElementById("shareTextGeneral");
|
|
||||||
|
|
||||||
const shareModalLocation = target.dataset.eventLabel;
|
|
||||||
|
|
||||||
shareModalCopy.dataset.eventLabel = shareModalLocation;
|
|
||||||
shareModalInput.dataset.eventLabel = shareModalLocation;
|
|
||||||
|
|
||||||
// Set input to correct URL value;
|
|
||||||
shareModalInput.value = target.href;
|
|
||||||
|
|
||||||
// Make modal visible
|
|
||||||
shareModal.style.display = "block";
|
|
||||||
|
|
||||||
if (breachText) {
|
|
||||||
shareTextGeneral.classList.add("hidden");
|
|
||||||
shareTextBreach.classList.remove("hidden");
|
|
||||||
} else {
|
|
||||||
shareTextGeneral.classList.remove("hidden");
|
|
||||||
shareTextBreach.classList.add("hidden");
|
|
||||||
}
|
|
||||||
|
|
||||||
document.addEventListener("keydown", keyPress);
|
|
||||||
shareModalInput.addEventListener("focus", selectURL);
|
|
||||||
shareModalCopy.addEventListener("click", copyURL);
|
|
||||||
btnCloseShareModal.addEventListener("click", closeShareModal);
|
|
||||||
|
|
||||||
shareModal.addEventListener("click", (e)=>{
|
|
||||||
// If the click is INSIDE the modal, ignore it.
|
|
||||||
if (e.target !== shareModal) { return; }
|
|
||||||
closeShareModal();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function openShareModal(target, breach = false) {
|
|
||||||
initShareModal(target, breach);
|
|
||||||
}
|
|
||||||
|
|
||||||
const btnOpenShareModal = document.querySelectorAll(".js-share-modal");
|
|
||||||
|
|
||||||
if (btnOpenShareModal) {
|
|
||||||
btnOpenShareModal.forEach( el => {
|
|
||||||
el.addEventListener("click", (e)=> {
|
|
||||||
e.preventDefault();
|
|
||||||
openShareModal(e.target, e.target.dataset.breach);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
|
@ -155,29 +155,6 @@ function setGAListeners(){
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Growth Experiment
|
|
||||||
if (document.body.dataset.experiment) {
|
|
||||||
document.querySelectorAll(".ga-growth-ping").forEach((el) => {
|
|
||||||
el.addEventListener("click", async(e) => {
|
|
||||||
// Overwrite current event category for active OAuth buttons
|
|
||||||
if (el.dataset.eventCategory !== "fxa-oauth") {
|
|
||||||
el.dataset.eventCategory = "fxa-oauth";
|
|
||||||
}
|
|
||||||
await sendPing(el, "Click", el.dataset.eventLabel, {transport: "beacon"});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// Set Share Modal GA Params on individual elements
|
|
||||||
document.querySelectorAll(".js-share-modal, .js-share-modal-breach").forEach((el) => {
|
|
||||||
if (el.dataset.label) {
|
|
||||||
el.dataset.eventLabel = el.dataset.label;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (el.dataset.eventCategory !== "exp5-share-modal") {
|
|
||||||
el.dataset.eventCategory = "exp5-share-modal";
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
window.sessionStorage.setItem("gaInit", true);
|
window.sessionStorage.setItem("gaInit", true);
|
||||||
|
@ -224,29 +201,6 @@ function setGAListeners(){
|
||||||
ga("set", "anonymizeIp", true);
|
ga("set", "anonymizeIp", true);
|
||||||
ga("set", "dimension6", `${document.body.dataset.signedInUser}`);
|
ga("set", "dimension6", `${document.body.dataset.signedInUser}`);
|
||||||
|
|
||||||
|
|
||||||
// Set Share URL UTMs
|
|
||||||
if ( document.body.dataset.utm_campaign && !document.body.dataset.experiment ) {
|
|
||||||
// campaignName
|
|
||||||
ga("set", "campaignName", `${document.body.dataset.utm_campaign}`);
|
|
||||||
ga("set", "dimension9", `${document.body.dataset.utm_campaign}`);
|
|
||||||
// campaignKeyword / term
|
|
||||||
ga("set", "campaignKeyword", `${document.body.dataset.utm_term}`);
|
|
||||||
ga("set", "dimension8", `${document.body.dataset.utm_term}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Growth Experiment
|
|
||||||
if (document.body.dataset.experiment) {
|
|
||||||
// If an experiment is active, set the "Growth Experiment Version"
|
|
||||||
// Custom Dimension to whichever branch is active.
|
|
||||||
ga("set", "dimension7", `${document.body.dataset.experiment}`);
|
|
||||||
ga("set", "dimension8", `${document.body.dataset.experiment}`);
|
|
||||||
ga("set", "dimension9", `${document.body.dataset.utm_campaign}`);
|
|
||||||
ga("set", "campaignName", `${document.body.dataset.utm_campaign}`);
|
|
||||||
ga("set", "campaignKeyword", `${document.body.dataset.utm_term}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ga("send", "pageview", {
|
ga("send", "pageview", {
|
||||||
hitCallback: function() {
|
hitCallback: function() {
|
||||||
removeUtmsFromUrl();
|
removeUtmsFromUrl();
|
||||||
|
|
|
@ -6,8 +6,6 @@
|
||||||
/* global sendRecommendationPings */
|
/* global sendRecommendationPings */
|
||||||
/* global ga */
|
/* global ga */
|
||||||
|
|
||||||
const utmParams = ["utm_source", "utm_medium", "utm_campaign", "utm_term", "utm_content" ];
|
|
||||||
|
|
||||||
if (typeof TextEncoder === "undefined") {
|
if (typeof TextEncoder === "undefined") {
|
||||||
const cryptoScript = document.createElement("script");
|
const cryptoScript = document.createElement("script");
|
||||||
const scripts = document.getElementsByTagName("script")[0];
|
const scripts = document.getElementsByTagName("script")[0];
|
||||||
|
@ -64,35 +62,6 @@ function doOauth(el, {emailWatch = false} = {}) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Growth Experiment: OAuth Entry Point IDs are unique to the experiment.
|
|
||||||
const oAuthEntryPointIds = [
|
|
||||||
"fx-monitor-check-for-breaches-blue-btn",
|
|
||||||
"fx-monitor-find-out-blue-btn",
|
|
||||||
"fx-monitor-alert-me-blue-btn-top",
|
|
||||||
"fx-monitor-alert-me-blue-btn-bottom",
|
|
||||||
];
|
|
||||||
|
|
||||||
if (oAuthEntryPointIds.includes(el.dataset.entrypoint)) {
|
|
||||||
// Growth Experiment: Reset UTMs from in-line body tag data elements.
|
|
||||||
utmParams.forEach(key => {
|
|
||||||
if (document.body.dataset[key]) {
|
|
||||||
url.searchParams.delete(key);
|
|
||||||
url.searchParams.append(key, document.body.dataset[key]);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (typeof(ga) !== "undefined" && document.body.dataset.experiment) {
|
|
||||||
ga("send", {
|
|
||||||
hitType: "event",
|
|
||||||
eventCategory: document.body.dataset.utm_campaign,
|
|
||||||
eventAction: document.body.dataset.experiment,
|
|
||||||
eventLabel: el.dataset.entrypoint,
|
|
||||||
transport: "beacon",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!sessionStorage) {
|
if (!sessionStorage) {
|
||||||
window.location.assign(url);
|
window.location.assign(url);
|
||||||
return;
|
return;
|
||||||
|
@ -172,26 +141,6 @@ function handleFormSubmits(formEvent) {
|
||||||
|
|
||||||
const formClassList = thisForm.classList;
|
const formClassList = thisForm.classList;
|
||||||
|
|
||||||
// Growth Experiment
|
|
||||||
if (formClassList.contains("skip")) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Growth Experiment
|
|
||||||
if (document.body.dataset.experiment) {
|
|
||||||
const scanFormActionURL = new URL(thisForm.action);
|
|
||||||
|
|
||||||
utmParams.forEach(key => {
|
|
||||||
if (document.body.dataset[key]) {
|
|
||||||
scanFormActionURL.searchParams.append(key, document.body.dataset[key]);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const revisedActionURL = scanFormActionURL.pathname + scanFormActionURL.search;
|
|
||||||
|
|
||||||
thisForm.action = revisedActionURL.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (thisForm.email && !isValidEmail(email)) {
|
if (thisForm.email && !isValidEmail(email)) {
|
||||||
sendPing(thisForm, "Failure");
|
sendPing(thisForm, "Failure");
|
||||||
formClassList.add("invalid");
|
formClassList.add("invalid");
|
||||||
|
|
|
@ -5,17 +5,10 @@ const csrf = require("csurf");
|
||||||
|
|
||||||
const {home, getAboutPage, getAllBreaches, getBentoStrings, getSecurityTips, notFound} = require("../controllers/home");
|
const {home, getAboutPage, getAllBreaches, getBentoStrings, getSecurityTips, notFound} = require("../controllers/home");
|
||||||
|
|
||||||
const { getShareUTMs } = require("../middleware");
|
|
||||||
|
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
const csrfProtection = csrf();
|
const csrfProtection = csrf();
|
||||||
|
|
||||||
router.get("/", csrfProtection, home);
|
router.get("/", csrfProtection, home);
|
||||||
router.get("/share/orange", csrfProtection, getShareUTMs, home);
|
|
||||||
router.get("/share/purple", csrfProtection, getShareUTMs, home);
|
|
||||||
router.get("/share/blue", csrfProtection, getShareUTMs, home);
|
|
||||||
router.get("/share/:breach", csrfProtection, getShareUTMs, home);
|
|
||||||
router.get("/share/", csrfProtection, getShareUTMs, home);
|
|
||||||
router.get("/about", getAboutPage);
|
router.get("/about", getAboutPage);
|
||||||
router.get("/breaches", getAllBreaches);
|
router.get("/breaches", getAllBreaches);
|
||||||
router.get("/security-tips", getSecurityTips);
|
router.get("/security-tips", getSecurityTips);
|
||||||
|
|
|
@ -5,7 +5,6 @@ const { URL } = require("url");
|
||||||
const HIBP = require("./hibp");
|
const HIBP = require("./hibp");
|
||||||
const sha1 = require("./sha1-utils");
|
const sha1 = require("./sha1-utils");
|
||||||
|
|
||||||
// Growth Experiment
|
|
||||||
const AppConstants = require("./app-constants");
|
const AppConstants = require("./app-constants");
|
||||||
const EXPERIMENTS_ENABLED = (AppConstants.EXPERIMENT_ACTIVE === "1");
|
const EXPERIMENTS_ENABLED = (AppConstants.EXPERIMENT_ACTIVE === "1");
|
||||||
const { getExperimentFlags } = require("./controllers/utils");
|
const { getExperimentFlags } = require("./controllers/utils");
|
||||||
|
@ -15,7 +14,6 @@ const scanResult = async(req, selfScan=false) => {
|
||||||
const allBreaches = req.app.locals.breaches;
|
const allBreaches = req.app.locals.breaches;
|
||||||
let scannedEmail = null;
|
let scannedEmail = null;
|
||||||
|
|
||||||
// Growth Experiment
|
|
||||||
const experimentFlags = getExperimentFlags(req, EXPERIMENTS_ENABLED);
|
const experimentFlags = getExperimentFlags(req, EXPERIMENTS_ENABLED);
|
||||||
|
|
||||||
const title = req.fluentFormat("scan-title");
|
const title = req.fluentFormat("scan-title");
|
||||||
|
|
|
@ -62,12 +62,9 @@ function getBreachCategory(breach) {
|
||||||
function getSortedDataClasses(locales, breach, isUserBrowserFirefox=false, isUserLocaleEnUs=false, isUserLocalEn=false, changePWLink=false) {
|
function getSortedDataClasses(locales, breach, isUserBrowserFirefox=false, isUserLocaleEnUs=false, isUserLocalEn=false, changePWLink=false) {
|
||||||
const priorityDataClasses = getAllPriorityDataClasses(isUserBrowserFirefox, isUserLocaleEnUs, changePWLink);
|
const priorityDataClasses = getAllPriorityDataClasses(isUserBrowserFirefox, isUserLocaleEnUs, changePWLink);
|
||||||
|
|
||||||
const experimentFlags = breach.experimentFlags;
|
|
||||||
|
|
||||||
const sortedDataClasses = {
|
const sortedDataClasses = {
|
||||||
priority: [],
|
priority: [],
|
||||||
lowerPriority: [],
|
lowerPriority: [],
|
||||||
experimentFlags: experimentFlags,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const dataClasses = breach.DataClasses;
|
const dataClasses = breach.DataClasses;
|
||||||
|
@ -111,7 +108,6 @@ function getGenericFillerRecs(locales, numberOfRecsNeeded) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function getBreachDetail(args) {
|
function getBreachDetail(args) {
|
||||||
const experimentFlags = args.data.root.experimentFlags;
|
|
||||||
const acceptsLanguages = args.data.root.req.acceptsLanguages();
|
const acceptsLanguages = args.data.root.req.acceptsLanguages();
|
||||||
const { locales, breach, changePWLink, isUserBrowserFirefox } = getVars(args);
|
const { locales, breach, changePWLink, isUserBrowserFirefox } = getVars(args);
|
||||||
const { sortedDataClasses, recommendations } = getSortedDataClassesAndRecs(acceptsLanguages, locales, breach, isUserBrowserFirefox, changePWLink);
|
const { sortedDataClasses, recommendations } = getSortedDataClassesAndRecs(acceptsLanguages, locales, breach, isUserBrowserFirefox, changePWLink);
|
||||||
|
@ -146,8 +142,6 @@ function getBreachDetail(args) {
|
||||||
copy: breachExposedPasswords ? localize(locales, "rec-section-subhead") : localize(locales, "rec-section-subhead-no-pw"),
|
copy: breachExposedPasswords ? localize(locales, "rec-section-subhead") : localize(locales, "rec-section-subhead-no-pw"),
|
||||||
recommendationsList: recommendations,
|
recommendationsList: recommendations,
|
||||||
},
|
},
|
||||||
|
|
||||||
experimentFlags: experimentFlags,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Add correct "What is a ... breach" copy.
|
// Add correct "What is a ... breach" copy.
|
||||||
|
|
|
@ -13,7 +13,6 @@ function userIsOnRelayWaitList(args) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function getBreachesDashboard(args) {
|
function getBreachesDashboard(args) {
|
||||||
const experimentFlags = args.data.root.experimentFlags;
|
|
||||||
const verifiedEmails = args.data.root.verifiedEmails;
|
const verifiedEmails = args.data.root.verifiedEmails;
|
||||||
const locales = args.data.root.req.supportedLocales;
|
const locales = args.data.root.req.supportedLocales;
|
||||||
let breachesFound = false;
|
let breachesFound = false;
|
||||||
|
@ -73,7 +72,6 @@ function getBreachesDashboard(args) {
|
||||||
const emailCards = {
|
const emailCards = {
|
||||||
verifiedEmails: verifiedEmails,
|
verifiedEmails: verifiedEmails,
|
||||||
breachesFound: breachesFound,
|
breachesFound: breachesFound,
|
||||||
experimentFlags: experimentFlags,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return args.fn(emailCards);
|
return args.fn(emailCards);
|
||||||
|
|
|
@ -3,13 +3,8 @@
|
||||||
const { getStrings } = require("./hbs-helpers");
|
const { getStrings } = require("./hbs-helpers");
|
||||||
const { LocaleUtils } = require("./../locale-utils");
|
const { LocaleUtils } = require("./../locale-utils");
|
||||||
|
|
||||||
const AppConstants = require("../app-constants");
|
|
||||||
const EXPERIMENTS_ENABLED = (AppConstants.EXPERIMENT_ACTIVE === "1");
|
|
||||||
const { getExperimentFlags } = require("../controllers/utils");
|
|
||||||
|
|
||||||
function getFooterLinks(args) {
|
function getFooterLinks(args) {
|
||||||
const locales = args.data.root.req.supportedLocales;
|
const locales = args.data.root.req.supportedLocales;
|
||||||
|
|
||||||
const footerLinks = [
|
const footerLinks = [
|
||||||
{
|
{
|
||||||
title: "About Firefox Monitor",
|
title: "About Firefox Monitor",
|
||||||
|
@ -33,21 +28,6 @@ function getFooterLinks(args) {
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
// Growth Experiment: Only add the footer share line if user is on VB branch
|
|
||||||
const experimentFlags = getExperimentFlags(args.data.root.req, EXPERIMENTS_ENABLED);
|
|
||||||
if (EXPERIMENTS_ENABLED && experimentFlags.treatmentBranch) {
|
|
||||||
const shareMonitorFooter = {
|
|
||||||
title: "Share Monitor",
|
|
||||||
stringId: "share-monitor",
|
|
||||||
href: "/share/purple",
|
|
||||||
experiment: "js-share-modal",
|
|
||||||
label: "share-modal--footer",
|
|
||||||
};
|
|
||||||
|
|
||||||
footerLinks.splice(2, 0, shareMonitorFooter);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return getStrings(footerLinks, locales);
|
return getStrings(footerLinks, locales);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,12 +30,7 @@ function getString (id, args) {
|
||||||
function getStrings(stringArr, locales) {
|
function getStrings(stringArr, locales) {
|
||||||
stringArr.forEach(string => {
|
stringArr.forEach(string => {
|
||||||
const stringId = string.stringId;
|
const stringId = string.stringId;
|
||||||
// Growth Experiment: Catch EN* Experimental Strings
|
string.stringId =LocaleUtils.fluentFormat(locales, stringId);
|
||||||
if (stringId === "share-monitor") {
|
|
||||||
string.stringId = "Share Monitor";
|
|
||||||
} else {
|
|
||||||
string.stringId =LocaleUtils.fluentFormat(locales, stringId);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
return stringArr;
|
return stringArr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,9 +3,6 @@
|
||||||
const { getStrings, getFxaUrl } = require("./hbs-helpers");
|
const { getStrings, getFxaUrl } = require("./hbs-helpers");
|
||||||
const { LocaleUtils } = require("./../locale-utils");
|
const { LocaleUtils } = require("./../locale-utils");
|
||||||
|
|
||||||
const AppConstants = require("../app-constants");
|
|
||||||
const EXPERIMENTS_ENABLED = (AppConstants.EXPERIMENT_ACTIVE === "1");
|
|
||||||
|
|
||||||
function getSignedInAs(args) {
|
function getSignedInAs(args) {
|
||||||
const locales = args.data.root.req.supportedLocales;
|
const locales = args.data.root.req.supportedLocales;
|
||||||
const userEmail = args.data.root.req.session.user.primary_email;
|
const userEmail = args.data.root.req.session.user.primary_email;
|
||||||
|
@ -62,19 +59,6 @@ function fxaMenuLinks(args) {
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
// Growth Experiment: Only add the avatar share link if user is on VB branch
|
|
||||||
if (EXPERIMENTS_ENABLED && args.data.root.req.session.experimentFlags.treatmentBranch) {
|
|
||||||
const shareMonitorFooter = {
|
|
||||||
title: "Share Monitor",
|
|
||||||
stringId: "share-monitor",
|
|
||||||
href: "/share/orange",
|
|
||||||
experiment: "js-share-modal",
|
|
||||||
label: "share-modal--header",
|
|
||||||
};
|
|
||||||
|
|
||||||
fxaLinks.unshift(shareMonitorFooter);
|
|
||||||
}
|
|
||||||
|
|
||||||
return getStrings(fxaLinks, locales);
|
return getStrings(fxaLinks, locales);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
|
|
||||||
<!--Exposed Data Classes -->
|
<!--Exposed Data Classes -->
|
||||||
<section class="detail-section bg-white jst-cntr flx flx-col">
|
<section class="detail-section bg-white jst-cntr flx flx-col">
|
||||||
{{> breach-detail-content-group dataClasses sectionId="dataClasses" name=./breach.Name treatmentBranch=./experimentFlags.treatmentBranch}}
|
{{> breach-detail-content-group dataClasses sectionId="dataClasses"}}
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<!-- What to do tips -->
|
<!-- What to do tips -->
|
||||||
|
|
|
@ -21,9 +21,7 @@
|
||||||
<link rel="icon" href="/img/favicons/favicon-128.png" sizes="128x128" />
|
<link rel="icon" href="/img/favicons/favicon-128.png" sizes="128x128" />
|
||||||
<link rel="icon" href="/img/favicons/favicon-256.png" sizes="256x256" />
|
<link rel="icon" href="/img/favicons/favicon-256.png" sizes="256x256" />
|
||||||
</head>
|
</head>
|
||||||
<body {{> analytics/default_dataset }} data-bento-app-id="fx-monitor"
|
<body {{> analytics/default_dataset }} data-bento-app-id="fx-monitor">
|
||||||
{{#if experimentFlags.experimentBranch }} {{> analytics/experiment }} {{/if}}
|
|
||||||
{{#if utmOverrides.campaignName }} {{> analytics/share }} {{/if}} >
|
|
||||||
{{> header/header }}
|
{{> header/header }}
|
||||||
{{{ body }}}
|
{{{ body }}}
|
||||||
{{> footer }}
|
{{> footer }}
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
data-utm_term={{experimentFlags.experimentBranch}}
|
|
||||||
data-experiment={{experimentFlags.experimentBranch}}
|
|
||||||
data-utm_campaign="growthuserflow5"
|
|
|
@ -1,2 +0,0 @@
|
||||||
data-utm_term="{{utmOverrides.campaignTerm}}"
|
|
||||||
data-utm_campaign="{{utmOverrides.campaignName}}"
|
|
|
@ -48,8 +48,5 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{#if treatmentBranch}}
|
|
||||||
{{> experiment--share-promo-breach breachName=./breach }}
|
|
||||||
{{/if}}
|
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -38,10 +38,9 @@
|
||||||
<h2 class="pref-headline">{{ getString "email-addresses-title" }}</h2>
|
<h2 class="pref-headline">{{ getString "email-addresses-title" }}</h2>
|
||||||
{{> dashboards/manage-email-link variableClass="hide-mobile"}}
|
{{> dashboards/manage-email-link variableClass="hide-mobile"}}
|
||||||
</div>
|
</div>
|
||||||
<div class="email-cards flx flx-col jst-cntr {{#if experimentFlags.treatmentBranch}}experiment{{/if}}">
|
<div class="email-cards flx flx-col jst-cntr">
|
||||||
{{#each this.verifiedEmails }}
|
{{#each this.verifiedEmails }}
|
||||||
{{> email-card }}
|
{{> email-card }}
|
||||||
{{> experiment--share-promo-dashboard}}
|
|
||||||
{{/each}}
|
{{/each}}
|
||||||
{{#if breachesFound }}
|
{{#if breachesFound }}
|
||||||
{{> hibp-attribution variableClasses="dash-attribution txt-cntr"}}
|
{{> hibp-attribution variableClasses="dash-attribution txt-cntr"}}
|
||||||
|
|
|
@ -1,15 +0,0 @@
|
||||||
<div id="shareModal" class="share-monitor--modal">
|
|
||||||
<div class="share-monitor--modal-content txt-cntr">
|
|
||||||
<button class="button-modal-close" id="closeShareModal" type="button" name="button"></button>
|
|
||||||
<div class="share-monitor--modal-text">
|
|
||||||
<h2>Share Monitor</h2>
|
|
||||||
<p id="shareTextGeneral" class="share-monitor--modal-promo">Copy this link to share Monitor with people you care about. You can paste the link into email, text messages, social media - wherever you want.</p>
|
|
||||||
<p id="shareTextBreach" class="hidden share-monitor--modal-promo">Share this link with someone you know who may have been involved in this breach. You can paste the link into email, text messages, social media - wherever you want.</p>
|
|
||||||
<label class="copy-form" for="shareModalCopy">
|
|
||||||
<input class="copy-form-input" data-event-action="Focus/Select on URL Input" id="shareModalInput" type="text" name="" value="" readonly="readonly">
|
|
||||||
<button class="copy-form-btn" data-event-action="Click Copy URL Button" id="shareModalCopy" type="button" name="button">Copy <span>Link</span> </button>
|
|
||||||
</label>
|
|
||||||
<p class="disclaimer">Monitor won’t track whether or not you share this link. They can check their results for free. No account required.</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
|
@ -1,10 +0,0 @@
|
||||||
<!-- {{ name }} -->
|
|
||||||
<div class="share-monitor--breach">
|
|
||||||
<div class="inset">
|
|
||||||
<img src="/img/svg/present.svg" alt="Gift present with a bow">
|
|
||||||
<div class="text">
|
|
||||||
<h3 class="txt-purple7">Know someone who may have been affected by this breach?</h3>
|
|
||||||
<a class="blue-link js-share-modal" data-ga-link="" data-breach="true" data-event-category="exp5-share-modal" data-event-label="share-modal--breach-detail" href="/share/{{ name }}">Send them an invitation to check their email address</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
|
@ -1,5 +0,0 @@
|
||||||
<div class="share-monitor--dashboard txt-cntr">
|
|
||||||
<img class="" src="/img/svg/present.svg" alt="Gift present with a bow">
|
|
||||||
<h3 class="section-headline txt-purple7">Help protect your family and friends</h3>
|
|
||||||
<a class="blue-link js-share-modal" data-ga-link="" data-event-category="exp5-share-modal" data-event-label="share-modal--dashboard" href="/share/blue">Send them an invitation to check their email address</a>
|
|
||||||
</div>
|
|
|
@ -7,12 +7,10 @@
|
||||||
</li>
|
</li>
|
||||||
{{#each (getFooterLinks)}}
|
{{#each (getFooterLinks)}}
|
||||||
<li class="footer-link-wrapper">
|
<li class="footer-link-wrapper">
|
||||||
<a class="footer-link {{this.experiment}}" href="{{ this.href }}" {{> analytics/outbound-link eventLabel=this.title }} {{#if this.label}} data-label="{{ this.label }}" {{/if}} {{#if openNewWindow}} target="_blank" {{/if}} rel="noopener">
|
<a class="footer-link" href="{{ this.href }}" {{> analytics/outbound-link eventLabel=this.title }} {{#if openNewWindow}} target="_blank" {{/if}} rel="noopener">
|
||||||
{{ this.stringId }}
|
{{ this.stringId }}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
{{/each}}
|
{{/each}}
|
||||||
</ul>
|
</ul>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
{{> experiment--share-modal}}
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<div class="fxa-menu-wrapper">
|
<div class="fxa-menu-wrapper">
|
||||||
<div id="avatar-wrapper" data-ga-link="" data-event-category="avatar-menu" data-event-label="open-fxa-menu" class="avatar-wrapper {{ addClass }}" tabindex="0" aria-label="{{ getString "open-fxa-menu" }}">
|
<div id="avatar-wrapper" class="avatar-wrapper {{ addClass }}" tabindex="0" aria-label="{{ getString "open-fxa-menu" }}">
|
||||||
<img alt="{{ req.session.user.primary_email }}" class="avatar" src="{{ req.session.user.fxa_profile_json.avatar }}"/>
|
<img alt="{{ req.session.user.primary_email }}" class="avatar" src="{{ req.session.user.fxa_profile_json.avatar }}"/>
|
||||||
</div>
|
</div>
|
||||||
<div id="fxa-menu" class="fxa-menu">
|
<div id="fxa-menu" class="fxa-menu">
|
||||||
|
@ -8,7 +8,7 @@
|
||||||
<span class="signed-in-as">{{{ getSignedInAs }}}</span>
|
<span class="signed-in-as">{{{ getSignedInAs }}}</span>
|
||||||
</div>
|
</div>
|
||||||
{{#each (fxaMenuLinks)}}
|
{{#each (fxaMenuLinks)}}
|
||||||
<a class="fxa-menu-link {{this.experiment}}" {{> analytics/internal-link eventLabel=this.title }} {{#if this.label}} data-label="{{ this.label }}" {{/if}} href="{{ this.href }}">{{ this.stringId }}</a>
|
<a class="fxa-menu-link" {{> analytics/internal-link eventLabel=this.title }} href="{{ this.href }}">{{ this.stringId }}</a>
|
||||||
{{/each}}
|
{{/each}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -23,7 +23,6 @@
|
||||||
<link rel="stylesheet" href="/css/security-tips.css">
|
<link rel="stylesheet" href="/css/security-tips.css">
|
||||||
<link rel="stylesheet" href="/css/sign-up-banner.css">
|
<link rel="stylesheet" href="/css/sign-up-banner.css">
|
||||||
<link rel="stylesheet" href="/css/subpage.css">
|
<link rel="stylesheet" href="/css/subpage.css">
|
||||||
<link rel="stylesheet" href="/css/share.css">
|
|
||||||
|
|
||||||
<script type="text/javascript" src="/js/all-breaches/all-breaches.js"></script>
|
<script type="text/javascript" src="/js/all-breaches/all-breaches.js"></script>
|
||||||
<script type="text/javascript" src="/js/analytics_dnt-helper.js" defer></script>
|
<script type="text/javascript" src="/js/analytics_dnt-helper.js" defer></script>
|
||||||
|
@ -37,7 +36,6 @@
|
||||||
<script type="text/javascript" src="/js/privacy-defender.js" defer></script>
|
<script type="text/javascript" src="/js/privacy-defender.js" defer></script>
|
||||||
<script type="text/javascript" src="/js/scan-email.js" defer></script>
|
<script type="text/javascript" src="/js/scan-email.js" defer></script>
|
||||||
<script type="text/javascript" src="/js/scan-results.js" defer></script>
|
<script type="text/javascript" src="/js/scan-results.js" defer></script>
|
||||||
<script type="text/javascript" src="/js/experiment.js" defer></script>
|
|
||||||
|
|
||||||
{{else}}
|
{{else}}
|
||||||
<link rel="stylesheet" href="/dist/app.min.css">
|
<link rel="stylesheet" href="/dist/app.min.css">
|
||||||
|
|
Загрузка…
Ссылка в новой задаче