feat(fortress): add "fortress" relying party

- fixes #1894
This commit is contained in:
dave justice 2019-08-06 16:52:06 -04:00
Родитель 759e568f9d
Коммит 2ffe1334df
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 5E203B0B555E3466
43 изменённых файлов: 3009 добавлений и 5 удалений

Просмотреть файл

@ -302,6 +302,11 @@ workflows:
module: 123done
requires:
- install
- build-module:
name: fortress
module: fortress
requires:
- install
- build-module:
name: browserid-verifier
module: browserid-verifier
@ -395,6 +400,16 @@ workflows:
module: 123done
requires:
- install
- deploy-module:
filters:
tags:
only: /.*/
branches:
ignore: /.*/
name: fortress
module: fortress
requires:
- install
- deploy-module:
filters:
tags:

Просмотреть файл

@ -24,6 +24,7 @@ PATH=$PATH:$HOME/.cargo/bin
"cd fxa-profile-server; npm ci; mkdir -p var/public/" \
"cd fxa-basket-proxy; npm ci" \
"cd 123done; npm i" \
"cd fortress; npm i" \
"cd fxa-shared; npm ci" \
"cd fxa-geodb; npm i" \
"cd fxa-email-event-proxy; npm i" \

Просмотреть файл

@ -96,6 +96,17 @@
},
"min_uptime": "2m"
},
{
"name": "Fortress PORT 9292",
"script": "server.js",
"cwd": "packages/fortress",
"max_restarts": "1",
"env": {
"CONFIG_FORTRESS": "./config-local.json",
"NODE_ENV": "dev"
},
"min_uptime": "2m"
},
{
"name": "123done PORT 8080",
"script": "server.js",

Просмотреть файл

@ -46,6 +46,7 @@
"moduleDependencies": {
"fxa-content-server": [
"123done",
"fortress",
"fxa-auth-server",
"fxa-js-client",
"fxa-shared",

Просмотреть файл

@ -0,0 +1,3 @@
{
"directory": "static/bower_components"
}

Просмотреть файл

@ -0,0 +1,5 @@
*~
node_modules
public-key.json
secret-key.json
static/bower_components

Просмотреть файл

@ -0,0 +1,2 @@
static/**
node_modules/**

Просмотреть файл

@ -0,0 +1,6 @@
{
"extends": "prettier",
"parserOptions": {
"ecmaVersion": 2018
}
}

6
packages/fortress/.gitignore поставляемый Normal file
Просмотреть файл

@ -0,0 +1,6 @@
public-key.json
secret-key.json
/node_modules
static/bower_components
*~
*.log

Просмотреть файл

@ -0,0 +1,9 @@
LICENSE
.*
Dockerfile
*.sh
*.ico
*.txt
ansible/*
static/bower_components/*
static/img/*

Просмотреть файл

@ -0,0 +1,4 @@
{
"singleQuote": true,
"trailingComma": "es5"
}

Просмотреть файл

@ -0,0 +1,26 @@
FROM node:10-alpine
# as root
RUN apk update
RUN apk add g++ git
RUN npm install -g bower
RUN addgroup -g 10001 app && adduser -D -G app -h /app -u 10001 app
WORKDIR /app
USER app
# as app
COPY package.json package.json
COPY bower.json bower.json
COPY .bowerrc .bowerrc
RUN npm install
RUN /bin/rm -rf .npm
COPY . /app
USER root
RUN apk del -r g++ git
CMD node ./server.js

15
packages/fortress/README.md Executable file
Просмотреть файл

@ -0,0 +1,15 @@
## A demo of Product Relying party
## running locally
1. install [git] and [node]
1. get a local copy of the repository: `git clone https://github.com/mozilla/fxa`
1. `cd fxa/packages/fortress`
1. install dependencies: `npm install`
1. generate keys `node scripts/gen_keys.js`
1. run the server: `npm start`
1. visit it in your browser: `http://127.0.0.1:9292/`
1. hack and reload! (web resources don't require a server restart)
[git]: http://git-scm.org
[node]: http://nodejs.org

23
packages/fortress/bower.json Executable file
Просмотреть файл

@ -0,0 +1,23 @@
{
"name": "firefox-fortress",
"version": "0.0.0",
"homepage": "https://github.com/mozilla/123done",
"authors": ["johngruen <john.gruen@gmail.com>"],
"description": "fxa-oauth-demo",
"license": "MIT",
"ignore": [
"**/.*",
"node_modules",
"bower_components",
"app/bower_components",
"test",
"tests",
"static/bower_components"
],
"private": true,
"dependencies": {
"jquery": "2.1.0",
"normalize-css": "3.0.1",
"modernizr": "2.7.2"
}
}

Просмотреть файл

@ -0,0 +1,5 @@
{
"client_id": "dcdb5ae7add825d2",
"client_secret": "b93ef8a8f3e553a430d7e5b904c6132b2722633af9f03128029201d24a97f2a8",
"redirect_uri": "http://127.0.0.1:9292/download"
}

12
packages/fortress/config.js Executable file
Просмотреть файл

@ -0,0 +1,12 @@
var path = require('path');
var configTarget = process.env.CONFIG_FORTRESS || './config.json';
var configFile = path.resolve(__dirname, configTarget);
var now = '[' + new Date().toISOString() + ']';
console.log(now, 'loading configuration File', configFile); //eslint-disable-line no-console
var config = require(configFile);
console.log(now, 'config:', JSON.stringify(config, null, 2)); //eslint-disable-line no-console
module.exports = config;

5
packages/fortress/config.json Executable file
Просмотреть файл

@ -0,0 +1,5 @@
{
"client_id": "dcdb5ae7add825d2",
"client_secret": "b93ef8a8f3e553a430d7e5b904c6132b2722633af9f03128029201d24a97f2a8",
"redirect_uri": "http://127.0.0.1:9292/download"
}

2219
packages/fortress/package-lock.json сгенерированный Normal file

Разница между файлами не показана из-за своего большого размера Загрузить разницу

43
packages/fortress/package.json Executable file
Просмотреть файл

@ -0,0 +1,43 @@
{
"name": "firefox-fortress",
"description": "A simple tasklist app that demonstrates FxA Sign-In",
"version": "0.0.2",
"author": {
"name": "Mozilla",
"url": "https://mozilla.org/"
},
"licenses": [
{
"type": "MPL 2.0",
"url": "https://mozilla.org/MPL/2.0/"
}
],
"homepage": "http://fortress.firefox.org/",
"bugs": "https://github.com/mozilla/fxa/issues",
"repository": {
"type": "git",
"url": "https://github.com/mozilla/fxa.git"
},
"private": true,
"dependencies": {
"bower": "*",
"client-sessions": "0.6.x",
"express": "4.16.4",
"morgan": "1.9.1"
},
"engines": {
"node": ">=10",
"npm": ">=6.4.1"
},
"devDependencies": {
"eslint": "5.16.0",
"eslint-config-prettier": "^5.0.0",
"prettier": "^1.18.2"
},
"scripts": {
"postinstall": "bower install --config.interactive=false -s",
"start": "node server.js",
"test": "eslint .",
"format": "prettier '**' --write"
}
}

46
packages/fortress/server.js Executable file
Просмотреть файл

@ -0,0 +1,46 @@
const express = require('express');
const morgan = require('morgan');
const path = require('path');
const sessions = require('client-sessions');
const config = require('./config');
const logger = morgan('short');
const app = express();
app.use(logger, express.json());
app.use(function(req, res, next) {
if (/^\/api/.test(req.url)) {
res.setHeader('Cache-Control', 'no-cache, max-age=0');
return sessions({
cookieName: config.cookieName || 'fortress',
secret: process.env['COOKIE_SECRET'] || 'define a real secret, please',
requestKey: 'session',
cookie: {
path: '/api',
httpOnly: true,
},
})(req, res, next);
} else {
return next();
}
});
app.get('/download', function(req, res, next) {
req.url = '/download.html';
next();
});
app.get(/^\/iframe(:?\/(?:index.html)?)?$/, function(req, res, next) {
req.url = '/index.html';
next();
});
app.use(express.static(path.join(__dirname, 'static')));
const port = process.env['PORT'] || config.port || 9292;
app.listen(port, '0.0.0.0');
console.log('Firefox Fortress started on port', port); //eslint-disable-line no-console

Просмотреть файл

@ -0,0 +1,277 @@
*,
*:before,
*:after {
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
body {
background: #f2f2f2;
color: #424f59;
font-family: 'Open Sans', sans-serif;
font-size: 85%;
}
a {
color: #0095dd;
text-decoration: none;
}
.container {
margin: 0 auto;
max-width: 960px;
min-width: 320px;
padding: 0 40px;
}
h1,
h2,
h3,
h4,
h5,
h6 {
font-weight: lighter;
}
/* Reset `button` default styles */
button {
-webkit-box-sizing: content-box;
-moz-box-sizing: content-box;
box-sizing: content-box;
background: none;
border: 0;
color: inherit;
font: inherit;
line-height: normal;
overflow: visible;
padding: 0;
-webkit-user-select: none; /* for button */
-moz-user-select: none;
-ms-user-select: none;
}
button::-moz-focus-inner {
border: 0;
padding: 0;
}
.banner {
background: #304050;
position: fixed;
top: 0;
width: 100%;
padding: 20px;
display: flex;
align-items: center;
justify-content: center;
}
.btn {
background: #eef2f0;
border-radius: 2px;
margin: 10px;
padding: 10px;
color: black;
}
#splash .btn {
background: #5cae40;
color: white;
display: block;
margin: 20px auto 0px;
text-align: center;
width: 140px;
}
.btn:hover {
background: #fff;
}
#splash {
font-family: 'Alegreya Sans', sans-serif;
margin-bottom: 60px;
margin-top: 150px;
}
#splash header {
font-weight: 300;
background: #eef2f0;
margin: 0 0 60px 0;
width: 100%;
}
#splash-logo {
display: block;
margin: 20px auto 0 auto;
width: 72px;
}
#splash h1 {
font-size: 72px;
font-weight: 100;
margin: 0;
text-align: center;
}
#splash h2 {
font-size: 24px;
font-weight: 300;
margin: 0;
text-align: center;
}
.two-col {
border-bottom: 1px dotted #ccc;
clear: both;
margin: 50px auto;
padding: 0 0 50px 0;
text-align: center;
width: 720px;
}
.left-col {
float: left;
width: 50%;
}
.right-col {
float: left;
width: 50%;
}
.two-col h3 {
font-size: 42px;
font-weight: 300;
margin: 20px 0;
}
.two-col p {
font-size: 20px;
}
#header-main {
background: #fff;
box-shadow: 0px 2px 2px #ccc;
margin: 0;
padding: 10px 0;
position: fixed;
top: 0;
width: 100%;
}
#subscriptionCTA {
float: right;
margin: 7px 0;
padding: 5px 10px;
}
.is-subscribed #subscriptionCTA {
display: none;
}
#header-main h1 {
float: left;
font-size: 24px;
line-height: 1em;
margin: 0;
}
.title {
margin: 0 0 0 10px;
position: relative;
top: -8px;
}
#header-main h1 .pro-status {
display: none;
}
.is-subscribed #header-main h1 .pro-status {
display: inline;
}
.is-subscribed #header-main {
background-image: url(/img/pro-header-bg.gif);
}
#footer-main {
background: url(/img/grad@2x.png) repeat-x #304050;
background-size: 5px 20px;
bottom: 0;
color: #fff;
margin: 0;
padding: 10px 0 0 0;
position: fixed;
width: 100%;
}
#footer-main p {
font-size: 0.8em;
margin: 0;
padding: 10px 0;
text-align: center;
}
.logo {
background: url(/img/logo@2x.png) no-repeat center center;
background-size: 36px 34px;
display: inline-block;
height: 35px;
margin: 5px auto 0 auto;
position: relative;
width: 36px;
}
div.logo {
background-size: 26px 25px;
display: block;
}
@media only screen and (max-width: 960px) {
.container {
margin: 0 auto;
width: 96%;
}
}
@media only screen and (max-width: 500px) {
body {
background: #fff;
}
#header-main {
background: #f2f2f2;
box-shadow: none;
}
}
@media only screen and (-webkit-min-device-pixel-ratio: 2),
only screen and (min--moz-device-pixel-ratio: 2),
only screen and (-moz-min-device-pixel-ratio: 2),
only screen and (-o-min-device-pixel-ratio: 2/1),
only screen and (min-device-pixel-ratio: 2),
only screen and (min-resolution: 192dpi),
only screen and (min-resolution: 2dppx) {
#logo {
background-image: url(/img/logo@2x.png);
}
}
.clearfix:after {
visibility: hidden;
display: block;
font-size: 0;
content: ' ';
clear: both;
height: 0;
}
.clearfix {
display: inline-block;
}
/* start commented backslash hack \*/
* html .clearfix {
height: 1%;
}
.clearfix {
display: block;
}
/* close commented backslash hack */

Просмотреть файл

@ -0,0 +1,96 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Firefox Fortress</title>
<meta type="description" content="" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="firefox-accounts" content="supported" />
<link
rel="stylesheet"
href="/bower_components/normalize-css/normalize.css"
type="text/css"
/>
<link rel="stylesheet" href="/css/main.css" type="text/css" />
<script src="/bower_components/modernizr/modernizr.js"></script>
<script src="/bower_components/jquery/dist/jquery.min.js"></script>
</head>
<body>
<div id="splash">
<header>
<img
src="/img/transparent-logo.png"
id="splash-logo"
alt="123done-logo"
width="72"
height="70"
/>
<h1>Firefox Fortress</h1>
<a
href="#"
class="btn btn-subscribe"
>Download Firefox Fortress</a>
</header>
<section>
<div class="container">
<div class="two-col clearfix">
<div class="left-col">
<h3>Download Firefox Fortress</h3>
<a
href="#"
class="btn btn-subscribe"
>Click Here</a>
</div>
<div class="right-col">
<img src="/img/list@2x.png" alt="list-logo" />
</div>
</div>
</div>
</section>
</div>
<div id="lists">
<header id="header-main">
<div class="container">
<h1>
<span class="logo"></span
><span class="title"
>Firefox Fortress <span class="pro-status">Pro!</span></span
>
</h1>
<div id="subscriptionCTA">
<a
href="#"
class="btn btn-subscribe"
>Download Firefox Fortress</a
>
</div>
</div>
</header>
<section class="todo">
<div class="container">
<div class="preroll">
<div id="subscriptionCTA">
<span
>Subscribe for pro! LINK TBD!
productId=fortressProProduct&amp;</span
>
</div>
</div>
</div>
</section>
</div>
<footer id="footer-main">
<div class="container">
<div class="logo"></div>
<p>
<strong>Firefox Fortress</strong>
<a href="/about.html">Learn more!</a>
</p>
</div>
</footer>
</body>
</html>

Двоичные данные
packages/fortress/static/favicon.ico Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.1 KiB

Двоичные данные
packages/fortress/static/img/grad.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 147 B

Двоичные данные
packages/fortress/static/img/grad@2x.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 164 B

Двоичные данные
packages/fortress/static/img/growth.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 3.0 KiB

Двоичные данные
packages/fortress/static/img/growth@2x.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 6.5 KiB

Двоичные данные
packages/fortress/static/img/loading.gif Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 2.5 KiB

Двоичные данные
packages/fortress/static/img/logo.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 873 B

Двоичные данные
packages/fortress/static/img/logo100.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.8 KiB

Двоичные данные
packages/fortress/static/img/logo@2x.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.5 KiB

Двоичные данные
packages/fortress/static/img/pro-header-bg.gif Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 80 KiB

Двоичные данные
packages/fortress/static/img/rocket.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 3.3 KiB

Двоичные данные
packages/fortress/static/img/rocket@2x.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 7.2 KiB

Двоичные данные
packages/fortress/static/img/transparent-logo.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 7.2 KiB

Просмотреть файл

@ -0,0 +1,117 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Firefox Fortress</title>
<meta type="description" content="" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="firefox-accounts" content="supported" />
<link
rel="stylesheet"
href="/bower_components/normalize-css/normalize.css"
type="text/css"
/>
<link rel="stylesheet" href="/css/main.css" type="text/css" />
<script src="/bower_components/modernizr/modernizr.js"></script>
<script src="/bower_components/jquery/dist/jquery.min.js"></script>
</head>
<body>
<div id="splash">
<header>
<img
src="/img/transparent-logo.png"
id="splash-logo"
alt="123done-logo"
width="72"
height="70"
/>
<h1>Firefox Fortress</h1>
<a
href="//127.0.0.1:3030/subscriptions/products/fortressProProduct"
class="btn btn-subscribe"
>Subscribe for Pro</a>
</header>
<section>
<div class="container">
<div class="two-col clearfix">
<div class="left-col">
<h3>Protect your data</h3>
<p>
With Firefox Fortress, you can protect your data.
</p>
</div>
<div class="right-col">
<img src="/img/list@2x.png" alt="list-logo" />
</div>
</div>
<div class="two-col clearfix">
<div class="left-col">
<img src="/img/growth@2x.png" alt="growth-logo" />
</div>
<div class="right-col">
<h3>Discover Yourself</h3>
<p>
Explore patterns in the way you work and improve your routines.
</p>
</div>
</div>
<div class="two-col clearfix">
<div class="right-col">
<h3>Do The Impossible</h3>
<p>Achieve your dreams.</p>
</div>
<div class="right-col">
<img src="/img/rocket@2x.png" alt="rocket-logo" />
</div>
</div>
</div>
</section>
</div>
<div id="lists">
<header id="header-main">
<div class="container">
<h1>
<span class="logo"></span
><span class="title"
>Firefox Fortress <span class="pro-status">Pro!</span></span
>
</h1>
<div id="subscriptionCTA">
<a
href="//127.0.0.1:3030/subscriptions/products/fortressProProduct"
class="btn btn-subscribe"
>Subscribe for Pro</a
>
</div>
</div>
</header>
<section class="todo">
<div class="container">
<div class="preroll">
<div id="subscriptionCTA">
<span
>Subscribe for pro! LINK TBD!
productId=fortressProProduct&amp;</span
>
</div>
</div>
</div>
</section>
</div>
<footer id="footer-main">
<div class="container">
<div class="logo"></div>
<p>
<strong>Firefox Fortress</strong>
<a href="/about.html">Learn more!</a>
</p>
</div>
</footer>
<script src="/js/fortress.js"></script>
</body>
</html>

Просмотреть файл

@ -0,0 +1,15 @@
q$(document).ready(function() {
let paymentURL;
switch (window.location.host) {
case 'fortress-latest.dev.lcip.org':
paymentURL =
'https://latest.dev.lcip.org/subscriptions/products/plan_FUUOYlhpIhWtoo';
break;
default:
paymentURL = '//127.0.0.1:3030/subscriptions/products/fortressProProduct';
break;
}
$('.btn-subscribe').each(function(index) {
$(this).attr('href', paymentURL);
});
});

Просмотреть файл

@ -0,0 +1,7 @@
This is a Privacy Policy document for Firefox Fortress. If this were a
real site, it would give you the policies which we adhere to as we
deal with your personal, private data. Policies that you must accept
in order to use the site.
But this is not a real site, it's a demonstration. So this document
isn't really all that useful.

Просмотреть файл

@ -0,0 +1,6 @@
This is a Terms Of Service document for Firefox Fortress. If this were a
real site, it would give you the terms of service that you must accept
to use the site.
But this is not a real site, it's a demonstration. So this document
isn't really all that useful.

Просмотреть файл

@ -69,6 +69,15 @@
"amount": 50,
"currency": "usd"
},
{
"plan_id": "fortressProMonthly",
"plan_name": "Fortress Pro Monthly",
"product_id": "fortressProProduct",
"product_name": "Fortress Pro",
"interval": "month",
"amount": 50,
"currency": "usd"
},
{
"plan_id": "321doneProWeekly",
"plan_name": "321done Pro Weekly",

Просмотреть файл

@ -101,8 +101,11 @@ const conf = convict({
productRedirectURLs: {
default: {
'123doneProProduct': 'http://127.0.0.1:8080/',
fortressProProduct: 'http://127.0.0.1:9292/download',
prod_FUUNYnlDso7FeB: 'https://fortress-latest.dev.lcip.org/',
prod_Ex9Z1q5yVydhyk: 'https://123done-latest.dev.lcip.org/',
prod_FUUNYnlDso7FeB: 'https://123done-stage.dev.lcip.org',
// todo get new prod_id for 123done stage
prod_FfiuDs9u11ESbD: 'https://123done-stage.dev.lcip.org',
},
doc: 'Mapping between product IDs and post-subscription redirect URLs',
env: 'PRODUCT_REDIRECT_URLS',

Просмотреть файл

@ -11,11 +11,17 @@ type availableDetailsType = {
(props: PlanDetailsProps) => JSX.Element
>;
};
const loadDetails123DonePro =
/* istanbul ignore next */
() => import('./Details123DonePro');
const availableDetails: availableDetailsType = {
// Examples:
// '123doneProProduct': React.lazy(() => import('./Details123donePro')),
// '321doneProProduct': React.lazy(() => import('./Details321donePro')),
plan_F4bof27uz71Vk7: React.lazy(() => import('./Details123DonePro')),
'fortressProMonthly': React.lazy(loadDetails123DonePro),
'plan_FUUOYlhpIhWtoo': React.lazy(loadDetails123DonePro),
'plan_F4bof27uz71Vk7': React.lazy(loadDetails123DonePro),
'prod_FfiuDs9u11ESbD': React.lazy(loadDetails123DonePro),
};
const defaultDetails = React.lazy(() => import('./DetailsDefault'));

Просмотреть файл

@ -88,6 +88,17 @@
},
"min_uptime": "2m"
},
{
"name": "Fortress PORT 9292",
"script": "server.js",
"cwd": "packages/fortress",
"max_restarts": "1",
"env": {
"CONFIG_FORTRESS": "./config-local.json",
"NODE_ENV": "dev"
},
"min_uptime": "2m"
},
{
"name": "123done PORT 8080",
"script": "server.js",