Compare commits
1 Commits
feature/su
...
pkg/dev/ub
Author | SHA1 | Date | |
---|---|---|---|
1d526a37d0 |
@ -1,4 +0,0 @@
|
|||||||
[*.{ts,tsx,js,jsx}]
|
|
||||||
charset = utf-8
|
|
||||||
indent_size = 2
|
|
||||||
indent_style = space
|
|
7
Makefile
7
Makefile
@ -5,7 +5,7 @@ deps:
|
|||||||
cd frontend && npm install
|
cd frontend && npm install
|
||||||
|
|
||||||
up: build
|
up: build
|
||||||
( cd frontend && NODE_ENV=development npm run server ) & USER_ID=$(shell id -u) docker-compose up && wait
|
( cd frontend && npm run server ) & USER_ID=$(shell id -u) docker-compose up && wait
|
||||||
|
|
||||||
sg:
|
sg:
|
||||||
docker-compose exec -u $(shell id -u) super-graph sh
|
docker-compose exec -u $(shell id -u) super-graph sh
|
||||||
@ -17,7 +17,4 @@ down:
|
|||||||
docker-compose down -v --remove-orphans
|
docker-compose down -v --remove-orphans
|
||||||
|
|
||||||
db-shell:
|
db-shell:
|
||||||
docker-compose exec postgres psql -Udaddy
|
docker-compose exec postgres psql -Usupergraph
|
||||||
|
|
||||||
hydra-shell:
|
|
||||||
docker-compose exec hydra /bin/sh
|
|
11
README.md
11
README.md
@ -26,15 +26,10 @@ Les services suivants devraient être disponibles après démarrage de l'environ
|
|||||||
|Service|Type|Accès|Description|
|
|Service|Type|Accès|Description|
|
||||||
|-------|----|-----|-----------|
|
|-------|----|-----|-----------|
|
||||||
|Application React|HTTP (UI)|http://localhost:8081/|Page d'accueil de l'application React (serveur Webpack)|
|
|Application React|HTTP (UI)|http://localhost:8081/|Page d'accueil de l'application React (serveur Webpack)|
|
||||||
|Interface Web GraphQL|HTTP (UI)|http://localhost:8080/|Interface Web de développement de l'API GraphQL **\***|
|
|Interface Web GraphQL|HTTP (UI)|http://localhost:8080/|Interface Web de développement de l'API GraphQL|
|
||||||
|Serveur GraphQL|HTTP (GraphQL)|http://localhost:8080/api/v1/graphql|Point d'entrée de l'API GraphQL|
|
|Serveur GraphQL|HTTP (GraphQL)|http://localhost:8080/api/v1/graphql|Point d'entrée de l'API GraphQL|
|
||||||
|Serveur Hydra|HTTP (ReST)|http://localhost:4444|Point d'entrée pour l'API OAuth2 d'[Hydra](https://www.ory.sh/hydra/docs/)|
|
|
||||||
|Serveur Hydra Passwordless|HTTP|http://localhost:3000|Point d'entrée pour la ["Login/Consent App"](https://www.ory.sh/hydra/docs/implementing-consent) [hydra-passwordless](https://forge.cadoles.com/wpetit/hydra-passwordless)|
|
|
||||||
|Serveur FakeSMTP|HTTP|http://localhost:8082|Interface web du serveur [FakeSMTP](https://forge.cadoles.com/wpetit/fake-smtp)
|
|
||||||
|Serveur PostgreSQL|TCP/IP (PostgreSQL)|`127.0.0.1:5432`|Port de connexion à la base de données PostgreSQL de développement|
|
|Serveur PostgreSQL|TCP/IP (PostgreSQL)|`127.0.0.1:5432`|Port de connexion à la base de données PostgreSQL de développement|
|
||||||
|
|
||||||
**\*** Pensez à passer l'attribut `auth_fail_block: false` dans le fichier `backend/config/dev.yml` si vous voulez pouvoir utiliser cette interface sans avoir à définir l'entête `Authorization`.
|
|
||||||
|
|
||||||
#### Fichiers/répertoires notables
|
#### Fichiers/répertoires notables
|
||||||
|
|
||||||
|Chemin|Description|
|
|Chemin|Description|
|
||||||
@ -51,10 +46,6 @@ Les services suivants devraient être disponibles après démarrage de l'environ
|
|||||||
|`make down`|Stopper et supprimer l'environnement de développement.|
|
|`make down`|Stopper et supprimer l'environnement de développement.|
|
||||||
|`make db-shell`|Ouvrir une console `psql` sur la base de données de développement.|
|
|`make db-shell`|Ouvrir une console `psql` sur la base de données de développement.|
|
||||||
|
|
||||||
#### Ressources
|
|
||||||
|
|
||||||
- [Execute an Authorization Code Grant Flow with PKCE](https://auth0.com/docs/api-auth/tutorials/authorization-code-grant-pkce)
|
|
||||||
|
|
||||||
## Licence
|
## Licence
|
||||||
|
|
||||||
AGPL-3.0
|
AGPL-3.0
|
||||||
|
@ -1,18 +0,0 @@
|
|||||||
/* fetchUser */
|
|
||||||
|
|
||||||
variables {
|
|
||||||
"email": ""
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
query fetchUser {
|
|
||||||
user(where: {email: {eq: $email}}) {
|
|
||||||
id
|
|
||||||
created_at
|
|
||||||
updated_at
|
|
||||||
email,
|
|
||||||
full_name
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
app_name: "Daddy Dev"
|
app_name: "Test Development"
|
||||||
host_port: 0.0.0.0:8080
|
host_port: 0.0.0.0:8080
|
||||||
web_ui: true
|
web_ui: true
|
||||||
|
|
||||||
# debug, error, warn, info
|
# debug, error, warn, info
|
||||||
log_level: debug
|
log_level: "info"
|
||||||
|
|
||||||
# enable or disable http compression (uses gzip)
|
# enable or disable http compression (uses gzip)
|
||||||
http_compress: true
|
http_compress: true
|
||||||
@ -15,7 +15,7 @@ http_compress: true
|
|||||||
production: false
|
production: false
|
||||||
|
|
||||||
# Throw a 401 on auth failure for queries that need auth
|
# Throw a 401 on auth failure for queries that need auth
|
||||||
auth_fail_block: true
|
auth_fail_block: false
|
||||||
|
|
||||||
# Latency tracing for database queries and remote joins
|
# Latency tracing for database queries and remote joins
|
||||||
# the resulting latency information is returned with the
|
# the resulting latency information is returned with the
|
||||||
@ -42,8 +42,6 @@ secret_key: supercalifajalistics
|
|||||||
# An origin may contain a wildcard (*) to replace 0 or more
|
# An origin may contain a wildcard (*) to replace 0 or more
|
||||||
# characters (i.e.: http://*.domain.com).
|
# characters (i.e.: http://*.domain.com).
|
||||||
cors_allowed_origins: ["*"]
|
cors_allowed_origins: ["*"]
|
||||||
cors_allowed_headers: ["Authorization", "Content-Type", "Mode"]
|
|
||||||
cors_allowed_methods: ["POST"]
|
|
||||||
|
|
||||||
# Debug Cross Origin Resource Sharing requests
|
# Debug Cross Origin Resource Sharing requests
|
||||||
cors_debug: false
|
cors_debug: false
|
||||||
@ -67,16 +65,18 @@ cors_debug: false
|
|||||||
auth:
|
auth:
|
||||||
# Can be 'rails', 'jwt' or 'header'
|
# Can be 'rails', 'jwt' or 'header'
|
||||||
type: jwt
|
type: jwt
|
||||||
#cookie: _supergraph_session
|
cookie: _supergraph_session
|
||||||
|
|
||||||
# Comment this out if you want to disable setting
|
# Comment this out if you want to disable setting
|
||||||
# the user_id via a header for testing.
|
# the user_id via a header for testing.
|
||||||
# Disable in production
|
# Disable in production
|
||||||
#creds_in_header: false
|
creds_in_header: true
|
||||||
|
|
||||||
jwt:
|
# jwt:
|
||||||
provider: hydra
|
# provider: auth0
|
||||||
jwks_url: http://hydra:4444/.well-known/jwks.json
|
# secret: abc335bfcfdb04e50db5bb0a4d67ab9
|
||||||
|
# public_key_file: /secrets/public_key.pem
|
||||||
|
# public_key_type: ecdsa #rsa
|
||||||
|
|
||||||
# header:
|
# header:
|
||||||
# name: dnt
|
# name: dnt
|
||||||
@ -87,16 +87,16 @@ auth:
|
|||||||
# In this example actions using this auth can only be
|
# In this example actions using this auth can only be
|
||||||
# called from the Google Appengine Cron service that
|
# called from the Google Appengine Cron service that
|
||||||
# sets a special header to all it's requests
|
# sets a special header to all it's requests
|
||||||
# auths:
|
auths:
|
||||||
# - name: from_taskqueue
|
- name: from_taskqueue
|
||||||
# type: header
|
type: header
|
||||||
# header:
|
header:
|
||||||
# name: X-Appengine-Cron
|
name: X-Appengine-Cron
|
||||||
# exists: true
|
exists: true
|
||||||
|
|
||||||
database:
|
database:
|
||||||
type: postgres
|
type: postgres
|
||||||
host: localhost
|
host: db
|
||||||
port: 5432
|
port: 5432
|
||||||
dbname: daddy
|
dbname: daddy
|
||||||
user: daddy
|
user: daddy
|
||||||
@ -105,19 +105,19 @@ database:
|
|||||||
#schema: "public"
|
#schema: "public"
|
||||||
#pool_size: 10
|
#pool_size: 10
|
||||||
#max_retries: 0
|
#max_retries: 0
|
||||||
log_level: "debug"
|
#log_level: "debug"
|
||||||
|
|
||||||
# Set session variable "user.id" to the user id
|
# Set session variable "user.id" to the user id
|
||||||
# Enable this if you need the user id in triggers, etc
|
# Enable this if you need the user id in triggers, etc
|
||||||
set_user_id: true
|
set_user_id: false
|
||||||
|
|
||||||
# database ping timeout is used for db health checking
|
# database ping timeout is used for db health checking
|
||||||
ping_timeout: 1m
|
ping_timeout: 1m
|
||||||
|
|
||||||
# Define additional variables here to be used with filters
|
# Define additional variables here to be used with filters
|
||||||
variables:
|
variables:
|
||||||
# admin_account_id: "5"
|
#admin_account_id: "5"
|
||||||
# admin_account_id: "sql:select id from users where admin = true limit 1"
|
admin_account_id: "sql:select id from users where admin = true limit 1"
|
||||||
|
|
||||||
|
|
||||||
# Field and table names that you wish to block
|
# Field and table names that you wish to block
|
||||||
@ -135,89 +135,67 @@ database:
|
|||||||
# which in this case refreshes a materialized view in the database.
|
# which in this case refreshes a materialized view in the database.
|
||||||
# The auth_name is from one of the configured auths
|
# The auth_name is from one of the configured auths
|
||||||
actions:
|
actions:
|
||||||
# - name: refresh_leaderboard_users
|
- name: refresh_leaderboard_users
|
||||||
# sql: REFRESH MATERIALIZED VIEW CONCURRENTLY "leaderboard_users"
|
sql: REFRESH MATERIALIZED VIEW CONCURRENTLY "leaderboard_users"
|
||||||
# auth_name: from_taskqueue
|
auth_name: from_taskqueue
|
||||||
|
|
||||||
tables:
|
tables:
|
||||||
# - name: customers
|
- name: customers
|
||||||
# remotes:
|
remotes:
|
||||||
# - name: payments
|
- name: payments
|
||||||
# id: stripe_id
|
id: stripe_id
|
||||||
# url: http://rails_app:3000/stripe/$id
|
url: http://rails_app:3000/stripe/$id
|
||||||
# path: data
|
path: data
|
||||||
# # debug: true
|
# debug: true
|
||||||
# pass_headers:
|
pass_headers:
|
||||||
# - cookie
|
- cookie
|
||||||
# set_headers:
|
set_headers:
|
||||||
# - name: Host
|
- name: Host
|
||||||
# value: 0.0.0.0
|
value: 0.0.0.0
|
||||||
# - name: Authorization
|
# - name: Authorization
|
||||||
# value: Bearer <stripe_api_key>
|
# value: Bearer <stripe_api_key>
|
||||||
|
|
||||||
# - # You can create new fields that have a
|
- # You can create new fields that have a
|
||||||
# # real db table backing them
|
# real db table backing them
|
||||||
# name: me
|
name: me
|
||||||
# table: users
|
table: users
|
||||||
|
|
||||||
|
|
||||||
roles_query: "select * from users where users.email = $user_id"
|
#roles_query: "SELECT * FROM users WHERE id = $user_id"
|
||||||
|
|
||||||
roles:
|
roles:
|
||||||
# Rôle par défaut si l'utilisateur n'existe pas dans la table `users`
|
|
||||||
- name: anon
|
- name: anon
|
||||||
tables:
|
tables:
|
||||||
- name: users
|
- name: users
|
||||||
# insert:
|
query:
|
||||||
# block: true
|
limit: 10
|
||||||
# query:
|
|
||||||
# block: true
|
|
||||||
# update:
|
|
||||||
# block: true
|
|
||||||
# delete:
|
|
||||||
# block: true
|
|
||||||
|
|
||||||
# Rôle par défaut si l'utilisateur existe dans la table `users`
|
|
||||||
# mais que la valeur de la colonne `role` n'est pas définie
|
|
||||||
- name: user
|
- name: user
|
||||||
tables:
|
tables:
|
||||||
- name: users
|
- name: users
|
||||||
insert:
|
|
||||||
block: true
|
|
||||||
query:
|
query:
|
||||||
filters: ["{ email: { _eq: $user_id } }"]
|
filters: ["{ id: { _eq: $user_id } }"]
|
||||||
|
|
||||||
|
- name: products
|
||||||
|
query:
|
||||||
|
limit: 50
|
||||||
|
filters: ["{ user_id: { eq: $user_id } }"]
|
||||||
|
disable_functions: false
|
||||||
|
|
||||||
|
insert:
|
||||||
|
filters: ["{ user_id: { eq: $user_id } }"]
|
||||||
|
presets:
|
||||||
|
- user_id: "$user_id"
|
||||||
|
- created_at: "now"
|
||||||
|
|
||||||
update:
|
update:
|
||||||
columns:
|
filters: ["{ user_id: { eq: $user_id } }"]
|
||||||
- full_name
|
presets:
|
||||||
filters: ["{ email: { _eq: $user_id } }"]
|
- updated_at: "now"
|
||||||
|
|
||||||
delete:
|
delete:
|
||||||
block: true
|
block: true
|
||||||
|
|
||||||
- name: admin
|
|
||||||
match: role = 'admin'
|
|
||||||
tables:
|
|
||||||
- name: users
|
|
||||||
|
|
||||||
# - name: products
|
|
||||||
# query:
|
|
||||||
# limit: 50
|
|
||||||
# filters: ["{ user_id: { eq: $user_id } }"]
|
|
||||||
# disable_functions: false
|
|
||||||
|
|
||||||
# insert:
|
|
||||||
# filters: ["{ user_id: { eq: $user_id } }"]
|
|
||||||
# presets:
|
|
||||||
# - user_id: "$user_id"
|
|
||||||
# - created_at: "now"
|
|
||||||
|
|
||||||
# update:
|
|
||||||
# filters: ["{ user_id: { eq: $user_id } }"]
|
|
||||||
# presets:
|
|
||||||
# - updated_at: "now"
|
|
||||||
|
|
||||||
# delete:
|
|
||||||
# block: true
|
|
||||||
|
|
||||||
# - name: admin
|
# - name: admin
|
||||||
# match: id = 1000
|
# match: id = 1000
|
||||||
# tables:
|
# tables:
|
||||||
|
@ -5,8 +5,7 @@ CREATE TABLE public.users (
|
|||||||
full_name text,
|
full_name text,
|
||||||
email text UNIQUE NOT NULL CHECK (length(email) < 255),
|
email text UNIQUE NOT NULL CHECK (length(email) < 255),
|
||||||
created_at timestamptz NOT NULL NOT NULL DEFAULT NOW(),
|
created_at timestamptz NOT NULL NOT NULL DEFAULT NOW(),
|
||||||
updated_at timestamptz NOT NULL NOT NULL DEFAULT NOW(),
|
updated_at timestamptz NOT NULL NOT NULL DEFAULT NOW()
|
||||||
role varchar(64)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
---- create above / drop below ----
|
---- create above / drop below ----
|
||||||
@ -15,3 +14,4 @@ CREATE TABLE public.users (
|
|||||||
-- then delete the separator line above.
|
-- then delete the separator line above.
|
||||||
|
|
||||||
DROP TABLE public.users
|
DROP TABLE public.users
|
||||||
|
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
# so I only need to overwrite some values
|
# so I only need to overwrite some values
|
||||||
inherits: dev
|
inherits: dev
|
||||||
|
|
||||||
app_name: "Backend Production"
|
app_name: "Daddy Backend"
|
||||||
host_port: 0.0.0.0:8080
|
host_port: 127.0.0.1:8080
|
||||||
web_ui: false
|
web_ui: false
|
||||||
|
|
||||||
# debug, info, warn, error, fatal, panic, disable
|
# debug, info, warn, error, fatal, panic, disable
|
||||||
@ -50,18 +50,22 @@ enable_tracing: true
|
|||||||
|
|
||||||
database:
|
database:
|
||||||
type: postgres
|
type: postgres
|
||||||
host: db
|
host: 127.0.0.1
|
||||||
port: 5432
|
port: 5432
|
||||||
dbname: backend_development
|
dbname: daddy
|
||||||
user: postgres
|
user: daddy
|
||||||
password: postgres
|
#password: postgres
|
||||||
#pool_size: 10
|
#pool_size: 10
|
||||||
#max_retries: 0
|
#max_retries: 0
|
||||||
#log_level: "debug"
|
#log_level: "debug"
|
||||||
|
|
||||||
# Set session variable "user.id" to the user id
|
# Set session variable "user.id" to the user id
|
||||||
# Enable this if you need the user id in triggers, etc
|
# Enable this if you need the user id in triggers, etc
|
||||||
set_user_id: false
|
set_user_id: true
|
||||||
|
|
||||||
# database ping timeout is used for db health checking
|
# database ping timeout is used for db health checking
|
||||||
ping_timeout: 5m
|
ping_timeout: 5m
|
||||||
|
|
||||||
|
migrations_path: ./migrations
|
||||||
|
|
||||||
|
cors_allowed_origins: ["*"]
|
@ -1,33 +1,19 @@
|
|||||||
// Voir https://supergraph.dev/docs/seed
|
// Example script to seed database
|
||||||
|
|
||||||
var users = [
|
var users = [];
|
||||||
{
|
|
||||||
full_name: 'Admin',
|
for (i = 0; i < 10; i++) {
|
||||||
email: 'admin@cadoles.com',
|
var data = {
|
||||||
role: 'admin',
|
full_name: fake.name(),
|
||||||
},
|
email: fake.email()
|
||||||
{
|
|
||||||
full_name: 'User 1',
|
|
||||||
email: 'user1@cadoles.com',
|
|
||||||
role: 'user',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
full_name: 'User 2',
|
|
||||||
email: 'user2@cadoles.com',
|
|
||||||
role: 'user',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
full_name: 'User 3',
|
|
||||||
email: 'user3@cadoles.com',
|
|
||||||
role: 'user',
|
|
||||||
}
|
}
|
||||||
];
|
|
||||||
|
|
||||||
for (var user, i = 0; (user = users[i]); i++) {
|
|
||||||
var res = graphql(" \
|
var res = graphql(" \
|
||||||
mutation { \
|
mutation { \
|
||||||
user(insert: $data) { \
|
user(insert: $data) { \
|
||||||
id \
|
id \
|
||||||
} \
|
} \
|
||||||
}", { data: user });
|
}", { data: data })
|
||||||
|
|
||||||
|
users.push(res.user)
|
||||||
}
|
}
|
1
debian/compat
vendored
Normal file
1
debian/compat
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
9
|
14
debian/control
vendored
Normal file
14
debian/control
vendored
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
Source: daddy
|
||||||
|
Section: unknown
|
||||||
|
Priority: optional
|
||||||
|
Maintainer: Cadoles <contanct@cadoles.com>
|
||||||
|
Build-Depends: debhelper (>= 8.0.0), wget, ca-certificates, tar, curl
|
||||||
|
Standards-Version: 3.9.4
|
||||||
|
Homepage: http://forge.cadoles.com/Cadoles/daddy
|
||||||
|
Vcs-Git: http://forge.cadoles.com/Cadoles/daddy.git
|
||||||
|
Vcs-Browser: http://forge.cadoles.com/Cadoles/daddy
|
||||||
|
|
||||||
|
Package: daddy
|
||||||
|
Architecture: any
|
||||||
|
Depends: ${shlibs:Depends}, ${misc:Depends}, nginx-full, super-graph, postgresql
|
||||||
|
Description: Application de gestion des DADs à Cadoles
|
12
debian/daddy.service
vendored
Normal file
12
debian/daddy.service
vendored
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=Service "super-graph" pour l'application Daddy
|
||||||
|
After=network-online.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
EnvironmentFile=/etc/systemd/system/daddy.env
|
||||||
|
ExecStart=/usr/bin/super-graph serv --path /usr/share/daddy/server/config
|
||||||
|
Restart=on-failure
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
36
debian/rules
vendored
Normal file
36
debian/rules
vendored
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
#!/usr/bin/make -f
|
||||||
|
# -*- makefile -*-
|
||||||
|
|
||||||
|
# Uncomment this to turn on verbose mode.
|
||||||
|
export DH_VERBOSE=1
|
||||||
|
|
||||||
|
ifeq (, $(shell which node 2>/dev/null))
|
||||||
|
override_dh_auto_build: install-nodejs
|
||||||
|
endif
|
||||||
|
|
||||||
|
%:
|
||||||
|
dh $@ --with systemd
|
||||||
|
|
||||||
|
override_dh_auto_build:
|
||||||
|
cd frontend && npm install && npm run build
|
||||||
|
|
||||||
|
install-nodejs:
|
||||||
|
wget -O- https://deb.nodesource.com/setup_12.x | bash -
|
||||||
|
apt-get install -y nodejs
|
||||||
|
|
||||||
|
override_dh_auto_install:
|
||||||
|
mkdir -p debian/daddy/usr/share/daddy/client/public
|
||||||
|
mkdir -p debian/daddy/usr/share/daddy/server/config
|
||||||
|
mkdir -p debian/daddy/etc/nginx/sites-available
|
||||||
|
mkdir -p debian/daddy/etc/systemd/system
|
||||||
|
|
||||||
|
cp -r frontend/dist/* debian/daddy/usr/share/daddy/client/public/
|
||||||
|
cp -r backend/config/* debian/daddy/usr/share/daddy/server/config/
|
||||||
|
cp misc/debian/nginx/daddy.conf debian/daddy/etc/nginx/sites-available/
|
||||||
|
cp misc/debian/systemd/daddy.env debian/daddy/etc/systemd/system/
|
||||||
|
|
||||||
|
install -d debian/daddy
|
||||||
|
|
||||||
|
override_dh_strip:
|
||||||
|
|
||||||
|
override_dh_auto_test:
|
1
debian/source/format
vendored
Normal file
1
debian/source/format
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
3.0 (native)
|
@ -20,72 +20,11 @@ services:
|
|||||||
- postgres
|
- postgres
|
||||||
ports:
|
ports:
|
||||||
- 8080:8080
|
- 8080:8080
|
||||||
|
|
||||||
postgres:
|
postgres:
|
||||||
build:
|
image: postgres:12-alpine
|
||||||
context: ./misc/containers/postgres
|
|
||||||
args:
|
|
||||||
- HTTP_PROXY=${HTTP_PROXY}
|
|
||||||
- HTTPS_PROXY=${HTTPS_PROXY}
|
|
||||||
- http_proxy=${http_proxy}
|
|
||||||
- https_proxy=${https_proxy}
|
|
||||||
environment:
|
environment:
|
||||||
- POSTGRES_PASSWORD=postgres
|
- POSTGRES_PASSWORD=daddy
|
||||||
|
- POSTGRES_USER=daddy
|
||||||
|
- POSTGRES_DB=daddy
|
||||||
ports:
|
ports:
|
||||||
- 5432:5432
|
- 5432:5432
|
||||||
volumes:
|
|
||||||
- postgres_data:/var/lib/postgresql/data
|
|
||||||
|
|
||||||
hydra:
|
|
||||||
build:
|
|
||||||
context: ./misc/containers/hydra
|
|
||||||
environment:
|
|
||||||
DSN: postgres://hydra:hydra@postgres:5432/hydra
|
|
||||||
URLS_LOGIN: http://localhost:3000/login
|
|
||||||
URLS_CONSENT: http://localhost:3000/consent
|
|
||||||
URLS_LOGOUT: http://localhost:3000/logout
|
|
||||||
SUPPORTED_SCOPES: email
|
|
||||||
SUPPORTED_CLAIMS: email,email_verified
|
|
||||||
SECRETS_SYSTEM: fAAya66yXNib52lbXpo16bxy1jD4NZrX
|
|
||||||
HYDRA_ADMIN_URL: http://localhost:4445
|
|
||||||
SERVE_PUBLIC_CORS_ENABLED: "true"
|
|
||||||
SERVE_PUBLIC_CORS_ALLOWED_ORIGINS: http://localhost:8081
|
|
||||||
WEBFINGER_JWKS_BROADCAST_KEYS: hydra.openid.id-token,hydra.jwt.access-token
|
|
||||||
ports:
|
|
||||||
- 4444:4444
|
|
||||||
command: hydra serve all --dangerous-force-http
|
|
||||||
|
|
||||||
hydra-passwordless:
|
|
||||||
image: bornholm/hydra-passwordless
|
|
||||||
ports:
|
|
||||||
- 3000:3000
|
|
||||||
environment:
|
|
||||||
- HTTP_COOKIE_AUTHENTICATION_KEY=XNFEWQwYB9WiVSnkHoFnMtNDL6X88apR4DmDBwh7gVgdJ3LTdLRLwGZAALnVN2yg
|
|
||||||
- HTTP_COOKIE_ENCRYPTION_KEY=xtHEd36Uo4DFeS2JgPPm94fPBfinY3xi
|
|
||||||
- HTTP_TOKEN_AUTHENTICATION_KEY=sGToi4yiP5yWrZzKdKaDA3XNpkcg9CRAaycuhr5gy2XnPKzUS7N6wGEFhMq9WPuf
|
|
||||||
- HTTP_TOKEN_ENCRYPTION_KEY=LAbuEWUeNDCLniRcyjiBCZ8ecgwN9Van
|
|
||||||
- SMTP_HOST=smtp
|
|
||||||
- SMTP_PORT=2525
|
|
||||||
- SMTP_USE_START_TLS=false
|
|
||||||
- SMTP_USER=
|
|
||||||
- SMTP_PASSWORD=
|
|
||||||
- SMTP_INSECURE_SKIP_VERIFY=true
|
|
||||||
- HYDRA_BASE_URL=http://hydra:4445
|
|
||||||
- HYDRA_FAKE_SSL_TERMINATION=false
|
|
||||||
|
|
||||||
smtp:
|
|
||||||
image: bornholm/fake-smtp
|
|
||||||
ports:
|
|
||||||
- 8082:8080
|
|
||||||
- 2525:2525
|
|
||||||
environment:
|
|
||||||
- FAKESMTP_SMTP_ADDRESS=:2525
|
|
||||||
- FAKESMTP_SMTP_DEBUG=true
|
|
||||||
- FAKESMTP_SMTP_USERNAME=
|
|
||||||
- FAKESMTP_SMTP_PASSWORD=
|
|
||||||
- FAKESMTP_SMTP_ALLOWINSECUREAUTH=true
|
|
||||||
volumes:
|
|
||||||
- /etc/localtime:/etc/localtime:ro
|
|
||||||
- /etc/timezone:/etc/timezone:ro
|
|
||||||
volumes:
|
|
||||||
postgres_data:
|
|
708
frontend/package-lock.json
generated
708
frontend/package-lock.json
generated
@ -1033,6 +1033,15 @@
|
|||||||
"regenerator-runtime": "^0.13.4"
|
"regenerator-runtime": "^0.13.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@babel/runtime-corejs2": {
|
||||||
|
"version": "7.10.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@babel/runtime-corejs2/-/runtime-corejs2-7.10.2.tgz",
|
||||||
|
"integrity": "sha512-ZLwsFnNm3WpIARU1aLFtufjMHsmEnc8TjtrfAjmbgMbeoyR+LuQoyESoNdTfeDhL6IdY12SpeycXMgSgl8XGXA==",
|
||||||
|
"requires": {
|
||||||
|
"core-js": "^2.6.5",
|
||||||
|
"regenerator-runtime": "^0.13.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"@babel/template": {
|
"@babel/template": {
|
||||||
"version": "7.10.1",
|
"version": "7.10.1",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.1.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.1.tgz",
|
||||||
@ -1093,47 +1102,12 @@
|
|||||||
"integrity": "sha512-xKOeQEl5O47GPZYIMToj6uuA2syyFlq9EMSl2ui0uytjY9xbe8XS0pexNWmxrdcCyNGyDmLyYw5FtKsalBUeOg==",
|
"integrity": "sha512-xKOeQEl5O47GPZYIMToj6uuA2syyFlq9EMSl2ui0uytjY9xbe8XS0pexNWmxrdcCyNGyDmLyYw5FtKsalBUeOg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"@nodelib/fs.scandir": {
|
"@lourenci/react-kanban": {
|
||||||
"version": "2.1.3",
|
"version": "0.15.0",
|
||||||
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/@lourenci/react-kanban/-/react-kanban-0.15.0.tgz",
|
||||||
"integrity": "sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw==",
|
"integrity": "sha512-/2XjB26iXcvpwDwlT3sz8/ptQ7QyTpMGlrPf1f02+V1Z4jdbVMo6Luz1sGlHe/TP68N8yz69/YT9qwqHZ6YYmQ==",
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"@nodelib/fs.stat": "2.0.3",
|
"react-beautiful-dnd": "^11.0.0"
|
||||||
"run-parallel": "^1.1.9"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"@nodelib/fs.stat": {
|
|
||||||
"version": "2.0.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz",
|
|
||||||
"integrity": "sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"@nodelib/fs.walk": {
|
|
||||||
"version": "1.2.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz",
|
|
||||||
"integrity": "sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"@nodelib/fs.scandir": "2.1.3",
|
|
||||||
"fastq": "^1.6.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"@npmcli/move-file": {
|
|
||||||
"version": "1.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.0.1.tgz",
|
|
||||||
"integrity": "sha512-Uv6h1sT+0DrblvIrolFtbvM1FgWm+/sy4B3pvLp67Zys+thcukzS5ekn7HsZFGpWP4Q3fYJCljbWQE/XivMRLw==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"mkdirp": "^1.0.4"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"mkdirp": {
|
|
||||||
"version": "1.0.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
|
|
||||||
"integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
|
|
||||||
"dev": true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@redux-saga/core": {
|
"@redux-saga/core": {
|
||||||
@ -1183,12 +1157,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@redux-saga/types/-/types-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@redux-saga/types/-/types-1.1.0.tgz",
|
||||||
"integrity": "sha512-afmTuJrylUU/0OtqzaRkbyYFFNgCF73Bvel/sw90pvGrWIZ+vyoIJqA6eMSoA6+nb443kTmulmBtC9NerXboNg=="
|
"integrity": "sha512-afmTuJrylUU/0OtqzaRkbyYFFNgCF73Bvel/sw90pvGrWIZ+vyoIJqA6eMSoA6+nb443kTmulmBtC9NerXboNg=="
|
||||||
},
|
},
|
||||||
"@types/anymatch": {
|
|
||||||
"version": "1.3.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/anymatch/-/anymatch-1.3.1.tgz",
|
|
||||||
"integrity": "sha512-/+CRPXpBDpo2RK9C68N3b2cOvO0Cf5B9aPijHsoDQTHivnGSObdOF2BRQOYjojWTDy6nQvMjmqRXIxH55VjxxA==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"@types/glob": {
|
"@types/glob": {
|
||||||
"version": "7.1.2",
|
"version": "7.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.2.tgz",
|
||||||
@ -1239,11 +1207,6 @@
|
|||||||
"integrity": "sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw==",
|
"integrity": "sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"@types/qs": {
|
|
||||||
"version": "6.9.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.3.tgz",
|
|
||||||
"integrity": "sha512-7s9EQWupR1fTc2pSMtXRQ9w9gLOcrJn+h7HOXw4evxyvVqMi4f+q7d2tnFe3ng3SNHjtK+0EzGMGFUQX4/AQRA=="
|
|
||||||
},
|
|
||||||
"@types/react": {
|
"@types/react": {
|
||||||
"version": "16.9.36",
|
"version": "16.9.36",
|
||||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-16.9.36.tgz",
|
"resolved": "https://registry.npmjs.org/@types/react/-/react-16.9.36.tgz",
|
||||||
@ -1296,82 +1259,12 @@
|
|||||||
"@types/react-router": "*"
|
"@types/react-router": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@types/source-list-map": {
|
|
||||||
"version": "0.1.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz",
|
|
||||||
"integrity": "sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"@types/tapable": {
|
|
||||||
"version": "1.0.6",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/tapable/-/tapable-1.0.6.tgz",
|
|
||||||
"integrity": "sha512-W+bw9ds02rAQaMvaLYxAbJ6cvguW/iJXNT6lTssS1ps6QdrMKttqEAMEG/b5CR8TZl3/L7/lH0ZV5nNR1LXikA==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"@types/uglify-js": {
|
|
||||||
"version": "3.9.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/uglify-js/-/uglify-js-3.9.2.tgz",
|
|
||||||
"integrity": "sha512-d6dIfpPbF+8B7WiCi2ELY7m0w1joD8cRW4ms88Emdb2w062NeEpbNCeWwVCgzLRpVG+5e74VFSg4rgJ2xXjEiQ==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"source-map": "^0.6.1"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"source-map": {
|
|
||||||
"version": "0.6.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
|
||||||
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
|
|
||||||
"dev": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"@types/uuid": {
|
"@types/uuid": {
|
||||||
"version": "7.0.4",
|
"version": "7.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-7.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-7.0.4.tgz",
|
||||||
"integrity": "sha512-WGZCqBZZ0mXN2RxvLHL6/7RCu+OWs28jgQMP04LWfpyJlQUMTR6YU9CNJAKDgbw+EV/u687INXuLUc7FuML/4g==",
|
"integrity": "sha512-WGZCqBZZ0mXN2RxvLHL6/7RCu+OWs28jgQMP04LWfpyJlQUMTR6YU9CNJAKDgbw+EV/u687INXuLUc7FuML/4g==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"@types/webpack": {
|
|
||||||
"version": "4.41.17",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.17.tgz",
|
|
||||||
"integrity": "sha512-6FfeCidTSHozwKI67gIVQQ5Mp0g4X96c2IXxX75hYEQJwST/i6NyZexP//zzMOBb+wG9jJ7oO8fk9yObP2HWAw==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"@types/anymatch": "*",
|
|
||||||
"@types/node": "*",
|
|
||||||
"@types/tapable": "*",
|
|
||||||
"@types/uglify-js": "*",
|
|
||||||
"@types/webpack-sources": "*",
|
|
||||||
"source-map": "^0.6.0"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"source-map": {
|
|
||||||
"version": "0.6.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
|
||||||
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
|
|
||||||
"dev": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"@types/webpack-sources": {
|
|
||||||
"version": "1.4.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-1.4.0.tgz",
|
|
||||||
"integrity": "sha512-c88dKrpSle9BtTqR6ifdaxu1Lvjsl3C5OsfvuUbUwdXymshv1TkufUAXBajCCUM/f/TmnkZC/Esb03MinzSiXQ==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"@types/node": "*",
|
|
||||||
"@types/source-list-map": "*",
|
|
||||||
"source-map": "^0.7.3"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"source-map": {
|
|
||||||
"version": "0.7.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz",
|
|
||||||
"integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==",
|
|
||||||
"dev": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"@webassemblyjs/ast": {
|
"@webassemblyjs/ast": {
|
||||||
"version": "1.9.0",
|
"version": "1.9.0",
|
||||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.9.0.tgz",
|
"resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.9.0.tgz",
|
||||||
@ -1628,24 +1521,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"aggregate-error": {
|
|
||||||
"version": "3.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.0.1.tgz",
|
|
||||||
"integrity": "sha512-quoaXsZ9/BLNae5yiNoUz+Nhkwz83GhWwtYFglcjEQB2NDHCIpApbqXxIFnm4Pq/Nvhrsq5sYJFyohrrxnTGAA==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"clean-stack": "^2.0.0",
|
|
||||||
"indent-string": "^4.0.0"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"indent-string": {
|
|
||||||
"version": "4.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
|
|
||||||
"integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==",
|
|
||||||
"dev": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"ajv": {
|
"ajv": {
|
||||||
"version": "6.12.2",
|
"version": "6.12.2",
|
||||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.2.tgz",
|
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.2.tgz",
|
||||||
@ -3333,22 +3208,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"clean-stack": {
|
|
||||||
"version": "2.2.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz",
|
|
||||||
"integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"clean-webpack-plugin": {
|
|
||||||
"version": "3.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/clean-webpack-plugin/-/clean-webpack-plugin-3.0.0.tgz",
|
|
||||||
"integrity": "sha512-MciirUH5r+cYLGCOL5JX/ZLzOZbVr1ot3Fw+KcvbhUb6PM+yycqd9ZhIlcigQ5gl+XhppNmw3bEFuaaMNyLj3A==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"@types/webpack": "^4.4.31",
|
|
||||||
"del": "^4.1.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"cliui": {
|
"cliui": {
|
||||||
"version": "5.0.0",
|
"version": "5.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz",
|
||||||
@ -3609,263 +3468,10 @@
|
|||||||
"integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=",
|
"integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"copy-webpack-plugin": {
|
|
||||||
"version": "6.0.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-6.0.2.tgz",
|
|
||||||
"integrity": "sha512-9Gm8X0c6eXlKnmltMPFCBeGOKjtcRIyTt4VaO3k1TkNgVTe5Ov2lYsYVuyLp0kp8DItO3apewflM+1GYgh6V2Q==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"cacache": "^15.0.4",
|
|
||||||
"fast-glob": "^3.2.2",
|
|
||||||
"find-cache-dir": "^3.3.1",
|
|
||||||
"glob-parent": "^5.1.1",
|
|
||||||
"globby": "^11.0.1",
|
|
||||||
"loader-utils": "^2.0.0",
|
|
||||||
"normalize-path": "^3.0.0",
|
|
||||||
"p-limit": "^2.3.0",
|
|
||||||
"schema-utils": "^2.7.0",
|
|
||||||
"serialize-javascript": "^3.1.0",
|
|
||||||
"webpack-sources": "^1.4.3"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"array-union": {
|
|
||||||
"version": "2.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
|
|
||||||
"integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"cacache": {
|
|
||||||
"version": "15.0.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/cacache/-/cacache-15.0.4.tgz",
|
|
||||||
"integrity": "sha512-YlnKQqTbD/6iyoJvEY3KJftjrdBYroCbxxYXzhOzsFLWlp6KX4BOlEf4mTx0cMUfVaTS3ENL2QtDWeRYoGLkkw==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"@npmcli/move-file": "^1.0.1",
|
|
||||||
"chownr": "^2.0.0",
|
|
||||||
"fs-minipass": "^2.0.0",
|
|
||||||
"glob": "^7.1.4",
|
|
||||||
"infer-owner": "^1.0.4",
|
|
||||||
"lru-cache": "^5.1.1",
|
|
||||||
"minipass": "^3.1.1",
|
|
||||||
"minipass-collect": "^1.0.2",
|
|
||||||
"minipass-flush": "^1.0.5",
|
|
||||||
"minipass-pipeline": "^1.2.2",
|
|
||||||
"mkdirp": "^1.0.3",
|
|
||||||
"p-map": "^4.0.0",
|
|
||||||
"promise-inflight": "^1.0.1",
|
|
||||||
"rimraf": "^3.0.2",
|
|
||||||
"ssri": "^8.0.0",
|
|
||||||
"tar": "^6.0.2",
|
|
||||||
"unique-filename": "^1.1.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"chownr": {
|
|
||||||
"version": "2.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
|
|
||||||
"integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"find-cache-dir": {
|
|
||||||
"version": "3.3.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz",
|
|
||||||
"integrity": "sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"commondir": "^1.0.1",
|
|
||||||
"make-dir": "^3.0.2",
|
|
||||||
"pkg-dir": "^4.1.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"find-up": {
|
|
||||||
"version": "4.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
|
|
||||||
"integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"locate-path": "^5.0.0",
|
|
||||||
"path-exists": "^4.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"glob-parent": {
|
|
||||||
"version": "5.1.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz",
|
|
||||||
"integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"is-glob": "^4.0.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"globby": {
|
|
||||||
"version": "11.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/globby/-/globby-11.0.1.tgz",
|
|
||||||
"integrity": "sha512-iH9RmgwCmUJHi2z5o2l3eTtGBtXek1OYlHrbcxOYugyHLmAsZrPj43OtHThd62Buh/Vv6VyCBD2bdyWcGNQqoQ==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"array-union": "^2.1.0",
|
|
||||||
"dir-glob": "^3.0.1",
|
|
||||||
"fast-glob": "^3.1.1",
|
|
||||||
"ignore": "^5.1.4",
|
|
||||||
"merge2": "^1.3.0",
|
|
||||||
"slash": "^3.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"loader-utils": {
|
|
||||||
"version": "2.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz",
|
|
||||||
"integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"big.js": "^5.2.2",
|
|
||||||
"emojis-list": "^3.0.0",
|
|
||||||
"json5": "^2.1.2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"locate-path": {
|
|
||||||
"version": "5.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
|
|
||||||
"integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"p-locate": "^4.1.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"lru-cache": {
|
|
||||||
"version": "5.1.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
|
|
||||||
"integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"yallist": "^3.0.2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"make-dir": {
|
|
||||||
"version": "3.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
|
|
||||||
"integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"semver": "^6.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"mkdirp": {
|
|
||||||
"version": "1.0.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
|
|
||||||
"integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"p-limit": {
|
|
||||||
"version": "2.3.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
|
|
||||||
"integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"p-try": "^2.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"p-locate": {
|
|
||||||
"version": "4.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
|
|
||||||
"integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"p-limit": "^2.2.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"p-map": {
|
|
||||||
"version": "4.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz",
|
|
||||||
"integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"aggregate-error": "^3.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"p-try": {
|
|
||||||
"version": "2.2.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
|
|
||||||
"integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"path-exists": {
|
|
||||||
"version": "4.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
|
|
||||||
"integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"pkg-dir": {
|
|
||||||
"version": "4.2.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
|
|
||||||
"integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"find-up": "^4.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"rimraf": {
|
|
||||||
"version": "3.0.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
|
|
||||||
"integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"glob": "^7.1.3"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"semver": {
|
|
||||||
"version": "6.3.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
|
|
||||||
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"slash": {
|
|
||||||
"version": "3.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
|
|
||||||
"integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"ssri": {
|
|
||||||
"version": "8.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.0.tgz",
|
|
||||||
"integrity": "sha512-aq/pz989nxVYwn16Tsbj1TqFpD5LLrQxHf5zaHuieFV+R0Bbr4y8qUsOA45hXT/N4/9UNXTarBjnjVmjSOVaAA==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"minipass": "^3.1.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"tar": {
|
|
||||||
"version": "6.0.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/tar/-/tar-6.0.2.tgz",
|
|
||||||
"integrity": "sha512-Glo3jkRtPcvpDlAs/0+hozav78yoXKFr+c4wgw62NNMO3oo4AaJdCo21Uu7lcwr55h39W2XD1LMERc64wtbItg==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"chownr": "^2.0.0",
|
|
||||||
"fs-minipass": "^2.0.0",
|
|
||||||
"minipass": "^3.0.0",
|
|
||||||
"minizlib": "^2.1.0",
|
|
||||||
"mkdirp": "^1.0.3",
|
|
||||||
"yallist": "^4.0.0"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"yallist": {
|
|
||||||
"version": "4.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
|
|
||||||
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
|
|
||||||
"dev": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"yallist": {
|
|
||||||
"version": "3.1.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
|
|
||||||
"integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
|
|
||||||
"dev": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"core-js": {
|
"core-js": {
|
||||||
"version": "2.6.11",
|
"version": "2.6.11",
|
||||||
"resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz",
|
"resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz",
|
||||||
"integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==",
|
"integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"core-js-compat": {
|
"core-js-compat": {
|
||||||
"version": "3.6.5",
|
"version": "3.6.5",
|
||||||
@ -3985,6 +3591,14 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"css-box-model": {
|
||||||
|
"version": "1.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/css-box-model/-/css-box-model-1.2.1.tgz",
|
||||||
|
"integrity": "sha512-a7Vr4Q/kd/aw96bnJG332W9V9LkJO69JRcaCYDUqjp6/z0w6VcZjgAcTbgFxEPfBgdnAwlh3iwu+hLopa+flJw==",
|
||||||
|
"requires": {
|
||||||
|
"tiny-invariant": "^1.0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"css-color-keywords": {
|
"css-color-keywords": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz",
|
||||||
@ -4284,23 +3898,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dir-glob": {
|
|
||||||
"version": "3.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
|
|
||||||
"integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"path-type": "^4.0.0"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"path-type": {
|
|
||||||
"version": "4.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
|
|
||||||
"integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
|
|
||||||
"dev": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"dns-equal": {
|
"dns-equal": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz",
|
||||||
@ -4958,74 +4555,6 @@
|
|||||||
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
|
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"fast-glob": {
|
|
||||||
"version": "3.2.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.4.tgz",
|
|
||||||
"integrity": "sha512-kr/Oo6PX51265qeuCYsyGypiO5uJFgBS0jksyG7FUeCyQzNwYnzrNIMR1NXfkZXsMYXYLRAHgISHBz8gQcxKHQ==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"@nodelib/fs.stat": "^2.0.2",
|
|
||||||
"@nodelib/fs.walk": "^1.2.3",
|
|
||||||
"glob-parent": "^5.1.0",
|
|
||||||
"merge2": "^1.3.0",
|
|
||||||
"micromatch": "^4.0.2",
|
|
||||||
"picomatch": "^2.2.1"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"braces": {
|
|
||||||
"version": "3.0.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
|
|
||||||
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"fill-range": "^7.0.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"fill-range": {
|
|
||||||
"version": "7.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
|
|
||||||
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"to-regex-range": "^5.0.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"glob-parent": {
|
|
||||||
"version": "5.1.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz",
|
|
||||||
"integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"is-glob": "^4.0.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"is-number": {
|
|
||||||
"version": "7.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
|
|
||||||
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"micromatch": {
|
|
||||||
"version": "4.0.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz",
|
|
||||||
"integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"braces": "^3.0.1",
|
|
||||||
"picomatch": "^2.0.5"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"to-regex-range": {
|
|
||||||
"version": "5.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
|
||||||
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"is-number": "^7.0.0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"fast-json-stable-stringify": {
|
"fast-json-stable-stringify": {
|
||||||
"version": "2.1.0",
|
"version": "2.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
|
||||||
@ -5038,15 +4567,6 @@
|
|||||||
"integrity": "sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ==",
|
"integrity": "sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"fastq": {
|
|
||||||
"version": "1.8.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.8.0.tgz",
|
|
||||||
"integrity": "sha512-SMIZoZdLh/fgofivvIkmknUXyPnvxRE3DhtZ5Me3Mrsk5gyPL42F0xr51TdRXskBxHfMp+07bcYzfsYEsSQA9Q==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"reusify": "^1.0.4"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"faye-websocket": {
|
"faye-websocket": {
|
||||||
"version": "0.10.0",
|
"version": "0.10.0",
|
||||||
"resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz",
|
"resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz",
|
||||||
@ -5263,15 +4783,6 @@
|
|||||||
"readable-stream": "^2.0.0"
|
"readable-stream": "^2.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"fs-minipass": {
|
|
||||||
"version": "2.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
|
|
||||||
"integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"minipass": "^3.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"fs-write-stream-atomic": {
|
"fs-write-stream-atomic": {
|
||||||
"version": "1.0.10",
|
"version": "1.0.10",
|
||||||
"resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz",
|
"resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz",
|
||||||
@ -5499,11 +5010,6 @@
|
|||||||
"integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==",
|
"integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"graphql-request": {
|
|
||||||
"version": "2.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/graphql-request/-/graphql-request-2.0.0.tgz",
|
|
||||||
"integrity": "sha512-Ww3Ax+G3l2d+mPT8w7HC9LfrKjutnCKtnDq7ZZp2ghVk5IQDjwAk3/arRF1ix17Ky15rm0hrSKVKxRhIVlSuoQ=="
|
|
||||||
},
|
|
||||||
"handle-thing": {
|
"handle-thing": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz",
|
||||||
@ -5925,12 +5431,6 @@
|
|||||||
"integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=",
|
"integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"ignore": {
|
|
||||||
"version": "5.1.8",
|
|
||||||
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz",
|
|
||||||
"integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"import-local": {
|
"import-local": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz",
|
||||||
@ -6381,11 +5881,6 @@
|
|||||||
"verror": "1.10.0"
|
"verror": "1.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"jwt-decode": {
|
|
||||||
"version": "2.2.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-2.2.0.tgz",
|
|
||||||
"integrity": "sha1-fYa9VmefWM5qhHBKZX3TkruoGnk="
|
|
||||||
},
|
|
||||||
"killable": {
|
"killable": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz",
|
||||||
@ -6486,6 +5981,12 @@
|
|||||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
|
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
|
||||||
"integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A=="
|
"integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A=="
|
||||||
},
|
},
|
||||||
|
"lodash.union": {
|
||||||
|
"version": "4.6.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz",
|
||||||
|
"integrity": "sha1-SLtQiECfFvGCFmZkHETdGqrjzYg=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"loglevel": {
|
"loglevel": {
|
||||||
"version": "1.6.8",
|
"version": "1.6.8",
|
||||||
"resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.6.8.tgz",
|
"resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.6.8.tgz",
|
||||||
@ -6641,12 +6142,6 @@
|
|||||||
"integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=",
|
"integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"merge2": {
|
|
||||||
"version": "1.4.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
|
|
||||||
"integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"methods": {
|
"methods": {
|
||||||
"version": "1.1.2",
|
"version": "1.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
|
||||||
@ -6779,68 +6274,6 @@
|
|||||||
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
|
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"minipass": {
|
|
||||||
"version": "3.1.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz",
|
|
||||||
"integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"yallist": "^4.0.0"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"yallist": {
|
|
||||||
"version": "4.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
|
|
||||||
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
|
|
||||||
"dev": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"minipass-collect": {
|
|
||||||
"version": "1.0.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz",
|
|
||||||
"integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"minipass": "^3.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"minipass-flush": {
|
|
||||||
"version": "1.0.5",
|
|
||||||
"resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz",
|
|
||||||
"integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"minipass": "^3.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"minipass-pipeline": {
|
|
||||||
"version": "1.2.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.3.tgz",
|
|
||||||
"integrity": "sha512-cFOknTvng5vqnwOpDsZTWhNll6Jf8o2x+/diplafmxpuIymAjzoOolZG0VvQf3V2HgqzJNhnuKHYp2BqDgz8IQ==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"minipass": "^3.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"minizlib": {
|
|
||||||
"version": "2.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.0.tgz",
|
|
||||||
"integrity": "sha512-EzTZN/fjSvifSX0SlqUERCN39o6T40AMarPbv0MrarSFtIITCBh7bi+dU8nxGFHuqs9jdIAeoYoKuQAAASsPPA==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"minipass": "^3.0.0",
|
|
||||||
"yallist": "^4.0.0"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"yallist": {
|
|
||||||
"version": "4.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
|
|
||||||
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
|
|
||||||
"dev": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"mississippi": {
|
"mississippi": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz",
|
||||||
@ -7915,9 +7348,10 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"qs": {
|
"qs": {
|
||||||
"version": "6.9.4",
|
"version": "6.5.2",
|
||||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.9.4.tgz",
|
"resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
|
||||||
"integrity": "sha512-A1kFqHekCTM7cz0udomYUoYNWjBebHm/5wzU/XqrBRBNWectVH0QIiN+NEcZ0Dte5hvzHwbr8+XQmguPhJ6WdQ=="
|
"integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==",
|
||||||
|
"dev": true
|
||||||
},
|
},
|
||||||
"querystring": {
|
"querystring": {
|
||||||
"version": "0.2.0",
|
"version": "0.2.0",
|
||||||
@ -7937,6 +7371,11 @@
|
|||||||
"integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA==",
|
"integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"raf-schd": {
|
||||||
|
"version": "4.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/raf-schd/-/raf-schd-4.0.2.tgz",
|
||||||
|
"integrity": "sha512-VhlMZmGy6A6hrkJWHLNTGl5gtgMUm+xfGza6wbwnE914yeQ5Ybm18vgM734RZhMgfw4tacUrWseGZlpUrrakEQ=="
|
||||||
|
},
|
||||||
"randombytes": {
|
"randombytes": {
|
||||||
"version": "2.1.0",
|
"version": "2.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
|
||||||
@ -7992,6 +7431,21 @@
|
|||||||
"prop-types": "^15.6.2"
|
"prop-types": "^15.6.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"react-beautiful-dnd": {
|
||||||
|
"version": "11.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-beautiful-dnd/-/react-beautiful-dnd-11.0.5.tgz",
|
||||||
|
"integrity": "sha512-7llby9U+jIfkINcyxPHVWU0HFYzqxMemUYgGHsFsbx4fZo1n/pW6sYKYzhxGxR3Ap5HxqswcQkKUZX4uEUWhlw==",
|
||||||
|
"requires": {
|
||||||
|
"@babel/runtime-corejs2": "^7.4.5",
|
||||||
|
"css-box-model": "^1.1.2",
|
||||||
|
"memoize-one": "^5.0.4",
|
||||||
|
"raf-schd": "^4.0.0",
|
||||||
|
"react-redux": "^7.0.3",
|
||||||
|
"redux": "^4.0.1",
|
||||||
|
"tiny-invariant": "^1.0.4",
|
||||||
|
"use-memo-one": "^1.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"react-dom": {
|
"react-dom": {
|
||||||
"version": "16.13.1",
|
"version": "16.13.1",
|
||||||
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.13.1.tgz",
|
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.13.1.tgz",
|
||||||
@ -8139,6 +7593,12 @@
|
|||||||
"source-map": "~0.5.0"
|
"source-map": "~0.5.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"recursive-readdir-sync": {
|
||||||
|
"version": "1.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/recursive-readdir-sync/-/recursive-readdir-sync-1.0.6.tgz",
|
||||||
|
"integrity": "sha1-Hb9tMvPFu4083pemxYjVR6nhPVY=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"redent": {
|
"redent": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz",
|
||||||
@ -8340,14 +7800,6 @@
|
|||||||
"tough-cookie": "~2.5.0",
|
"tough-cookie": "~2.5.0",
|
||||||
"tunnel-agent": "^0.6.0",
|
"tunnel-agent": "^0.6.0",
|
||||||
"uuid": "^3.3.2"
|
"uuid": "^3.3.2"
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"qs": {
|
|
||||||
"version": "6.5.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
|
|
||||||
"integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==",
|
|
||||||
"dev": true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"require-directory": {
|
"require-directory": {
|
||||||
@ -8516,12 +7968,6 @@
|
|||||||
"integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=",
|
"integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"reusify": {
|
|
||||||
"version": "1.0.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
|
|
||||||
"integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"rework": {
|
"rework": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/rework/-/rework-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/rework/-/rework-1.0.1.tgz",
|
||||||
@ -8565,12 +8011,6 @@
|
|||||||
"inherits": "^2.0.1"
|
"inherits": "^2.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"run-parallel": {
|
|
||||||
"version": "1.1.9",
|
|
||||||
"resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.9.tgz",
|
|
||||||
"integrity": "sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"run-queue": {
|
"run-queue": {
|
||||||
"version": "1.0.3",
|
"version": "1.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz",
|
||||||
@ -9992,6 +9432,11 @@
|
|||||||
"integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==",
|
"integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"use-memo-one": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/use-memo-one/-/use-memo-one-1.1.1.tgz",
|
||||||
|
"integrity": "sha512-oFfsyun+bP7RX8X2AskHNTxu+R3QdE/RC5IefMbqptmACAA/gfol1KDD5KRzPsGMa62sWxGZw+Ui43u6x4ddoQ=="
|
||||||
|
},
|
||||||
"util": {
|
"util": {
|
||||||
"version": "0.10.3",
|
"version": "0.10.3",
|
||||||
"resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz",
|
"resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz",
|
||||||
@ -10040,8 +9485,7 @@
|
|||||||
"uuid": {
|
"uuid": {
|
||||||
"version": "3.4.0",
|
"version": "3.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
|
||||||
"integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==",
|
"integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"v8-compile-cache": {
|
"v8-compile-cache": {
|
||||||
"version": "2.0.3",
|
"version": "2.0.3",
|
||||||
@ -10283,6 +9727,28 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"webpack-cleanup-plugin": {
|
||||||
|
"version": "0.5.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/webpack-cleanup-plugin/-/webpack-cleanup-plugin-0.5.1.tgz",
|
||||||
|
"integrity": "sha1-3y1wa9dTZMBuZbBRGGMW1nTrlq8=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"lodash.union": "4.6.0",
|
||||||
|
"minimatch": "3.0.3",
|
||||||
|
"recursive-readdir-sync": "1.0.6"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"minimatch": {
|
||||||
|
"version": "3.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.3.tgz",
|
||||||
|
"integrity": "sha1-Kk5AkLlrLbBqnX3wEFWmKnfJt3Q=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"brace-expansion": "^1.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"webpack-cli": {
|
"webpack-cli": {
|
||||||
"version": "3.3.11",
|
"version": "3.3.11",
|
||||||
"resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-3.3.11.tgz",
|
"resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-3.3.11.tgz",
|
||||||
|
@ -32,8 +32,6 @@
|
|||||||
"@types/react-router-dom": "^5.1.5",
|
"@types/react-router-dom": "^5.1.5",
|
||||||
"@types/uuid": "^7.0.3",
|
"@types/uuid": "^7.0.3",
|
||||||
"babel-loader": "^8.0.6",
|
"babel-loader": "^8.0.6",
|
||||||
"clean-webpack-plugin": "^3.0.0",
|
|
||||||
"copy-webpack-plugin": "^6.0.2",
|
|
||||||
"css-loader": "^1.0.1",
|
"css-loader": "^1.0.1",
|
||||||
"extract-loader": "^3.1.0",
|
"extract-loader": "^3.1.0",
|
||||||
"file-loader": "^2.0.0",
|
"file-loader": "^2.0.0",
|
||||||
@ -47,16 +45,13 @@
|
|||||||
"style-loader": "^0.23.1",
|
"style-loader": "^0.23.1",
|
||||||
"ts-loader": "^7.0.2",
|
"ts-loader": "^7.0.2",
|
||||||
"webpack": "^4.25.0",
|
"webpack": "^4.25.0",
|
||||||
|
"webpack-cleanup-plugin": "^0.5.1",
|
||||||
"webpack-cli": "^3.1.2",
|
"webpack-cli": "^3.1.2",
|
||||||
"webpack-dev-server": "^3.11.0"
|
"webpack-dev-server": "^3.11.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/qs": "^6.9.3",
|
|
||||||
"bulma": "^0.7.2",
|
"bulma": "^0.7.2",
|
||||||
"bulma-switch": "^2.0.0",
|
"bulma-switch": "^2.0.0",
|
||||||
"graphql-request": "^2.0.0",
|
|
||||||
"jwt-decode": "^2.2.0",
|
|
||||||
"qs": "^6.9.4",
|
|
||||||
"react": "^16.12.0",
|
"react": "^16.12.0",
|
||||||
"react-dom": "^16.12.0",
|
"react-dom": "^16.12.0",
|
||||||
"react-redux": "^7.1.3",
|
"react-redux": "^7.1.3",
|
||||||
|
@ -1,22 +1,29 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { BrowserRouter, Route, Redirect, Switch } from "react-router-dom";
|
import { HashRouter as Router, Route, Redirect, Switch } from "react-router-dom";
|
||||||
import { HomePage } from './HomePage/HomePage';
|
import { HomePage } from './HomePage/HomePage';
|
||||||
import { store } from '../store/store';
|
import { store } from '../store/store';
|
||||||
import { Provider } from 'react-redux';
|
import { Provider } from 'react-redux';
|
||||||
import { OAuth2Page } from './OAuth2Page/OAuth2Page';
|
import { logout } from '../store/actions/logout';
|
||||||
|
|
||||||
export class App extends React.Component {
|
export class App extends React.Component {
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<Provider store={store}>
|
<Provider store={store}>
|
||||||
<BrowserRouter>
|
<Router>
|
||||||
<Switch>
|
<Switch>
|
||||||
<Route path="/" exact component={HomePage} />
|
<Route path="/" exact component={HomePage} />
|
||||||
<Route path="/oauth2/:action" exact component={OAuth2Page} />
|
<Route path="/logout" exact component={() => {
|
||||||
|
this.logout();
|
||||||
|
return <Redirect to="/" />;
|
||||||
|
}} />
|
||||||
<Route component={() => <Redirect to="/" />} />
|
<Route component={() => <Redirect to="/" />} />
|
||||||
</Switch>
|
</Switch>
|
||||||
</BrowserRouter>
|
</Router>
|
||||||
</Provider>
|
</Provider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
logout() {
|
||||||
|
store.dispatch(logout());
|
||||||
|
}
|
||||||
}
|
}
|
@ -1,27 +1,11 @@
|
|||||||
import React, { useEffect } from 'react';
|
import React from 'react';
|
||||||
import { Page } from '../Page';
|
import { Page } from '../Page';
|
||||||
import { useSelector, useDispatch } from 'react-redux';
|
|
||||||
import { RootState } from '../../store/reducers/root';
|
|
||||||
|
|
||||||
export function HomePage() {
|
export function HomePage() {
|
||||||
const currentUser = useSelector((state: RootState) => state.auth.currentUser);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Page title="Daddy - Accueil">
|
<Page title="Daddy - Accueil">
|
||||||
<div className="container is-fluid">
|
<div className="container is-fluid">
|
||||||
<section className="section">
|
|
||||||
<div className="columns">
|
|
||||||
<div className="column is-4 is-offset-4">
|
|
||||||
<div className="box">
|
|
||||||
{
|
|
||||||
currentUser && currentUser.full_name ?
|
|
||||||
<p>Bonjour <span className="has-text-weight-bold">{currentUser.full_name}</span> !</p> :
|
|
||||||
<p>Veuillez vous authentifier.</p>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</div>
|
</div>
|
||||||
</Page>
|
</Page>
|
||||||
);
|
);
|
||||||
|
@ -1,12 +1,8 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import logo from '../resources/logo.svg';
|
import logo from '../resources/logo.svg';
|
||||||
import { useSelector } from 'react-redux';
|
|
||||||
import { RootState } from '../store/reducers/root';
|
|
||||||
import { Link } from 'react-router-dom';
|
|
||||||
|
|
||||||
export function Navbar() {
|
|
||||||
const isAuthenticated = useSelector<RootState>(state => state.auth.isAuthenticated);
|
|
||||||
|
|
||||||
|
export class Navbar extends React.PureComponent {
|
||||||
|
render() {
|
||||||
return (
|
return (
|
||||||
<nav className="navbar" role="navigation" aria-label="main navigation">
|
<nav className="navbar" role="navigation" aria-label="main navigation">
|
||||||
<div className="container is-fluid">
|
<div className="container is-fluid">
|
||||||
@ -24,25 +20,17 @@ export function Navbar() {
|
|||||||
<div className="navbar-menu">
|
<div className="navbar-menu">
|
||||||
<div className="navbar-end">
|
<div className="navbar-end">
|
||||||
<div className="navbar-item">
|
<div className="navbar-item">
|
||||||
{
|
<a className="button is-small" href="#/logout">
|
||||||
isAuthenticated ?
|
|
||||||
<Link className="button is-small" to="/oauth2/logout">
|
|
||||||
<span className="icon">
|
<span className="icon">
|
||||||
<i className="fas fa-sign-out-alt"></i>
|
<i className="fas fa-sign-out-alt"></i>
|
||||||
</span>
|
</span>
|
||||||
<span>Se déconnecter</span>
|
<span>Se déconnecter</span>
|
||||||
</Link> :
|
</a>
|
||||||
<Link className="button is-small" to="/oauth2/login">
|
|
||||||
<span className="icon">
|
|
||||||
<i className="fas fa-sign-in-alt"></i>
|
|
||||||
</span>
|
|
||||||
<span>Se connecter</span>
|
|
||||||
</Link>
|
|
||||||
}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
);
|
);
|
||||||
};
|
}
|
||||||
|
}
|
@ -1,31 +0,0 @@
|
|||||||
import React, { useEffect } from 'react';
|
|
||||||
import { Page } from '../Page';
|
|
||||||
import { useDispatch } from 'react-redux';
|
|
||||||
import { logout, login, handleOAuth2Callback } from '../../store/actions/auth';
|
|
||||||
|
|
||||||
export function OAuth2Page({ match, location, history }) {
|
|
||||||
const dispatch = useDispatch();
|
|
||||||
const { action } = match.params;
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
switch(action) {
|
|
||||||
case 'logout':
|
|
||||||
dispatch(logout());
|
|
||||||
history.push("/");
|
|
||||||
break;
|
|
||||||
case 'login':
|
|
||||||
dispatch(login());
|
|
||||||
break;
|
|
||||||
case 'callback':
|
|
||||||
dispatch(handleOAuth2Callback(location.search));
|
|
||||||
history.push("/");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}, [action]);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Page title="Daddy - OAuth2">
|
|
||||||
|
|
||||||
</Page>
|
|
||||||
);
|
|
||||||
}
|
|
@ -1,21 +0,0 @@
|
|||||||
export const Config = {
|
|
||||||
// The OpenID Connect client_id
|
|
||||||
oauth2ClientId: get<string>("oauth2ClientId", "daddy"),
|
|
||||||
oauth2Scope: get<string>("oauth2Scope", "email email_verified openid offline_access"),
|
|
||||||
oauth2RedirectURI: get<string>("oauth2RedirectURI", "http://localhost:8081/oauth2/callback"),
|
|
||||||
oauth2Audience: get<string>("oauth2Audience", ""),
|
|
||||||
oauth2AuthorizeURL: get<string>("oauth2AuthorizeURL", "http://localhost:4444/oauth2/auth"),
|
|
||||||
oauth2TokenURL: get<string>("oauth2TokenURL", "http://localhost:4444/oauth2/token"),
|
|
||||||
oauth2LogoutURL: get<string>("oauth2LogoutURL", "http://localhost:4444/oauth2/sessions/logout"),
|
|
||||||
oauth2PostLogoutRedirectURI: get<string>("oauth2PostLogoutRedirectURI", "http://localhost:8081"),
|
|
||||||
graphQLEndpoint: get<string>("graphQLEndpoint", "http://localhost:8080/api/v1/graphql")
|
|
||||||
};
|
|
||||||
|
|
||||||
function get<T>(key: string, defaultValue: T):T {
|
|
||||||
const config = window['__CONFIG__'] || {};
|
|
||||||
if (config && config.hasOwnProperty(key)) {
|
|
||||||
return config[key] as T;
|
|
||||||
} else {
|
|
||||||
return defaultValue;
|
|
||||||
}
|
|
||||||
}
|
|
@ -5,18 +5,16 @@
|
|||||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||||
<title>Daddy</title>
|
<title>Daddy</title>
|
||||||
<% for (var css in htmlWebpackPlugin.files.css) { %>
|
<% for (var css in htmlWebpackPlugin.files.css) { %>
|
||||||
<link href="/<%= htmlWebpackPlugin.files.css[css] %>" rel="stylesheet">
|
<link href="<%= htmlWebpackPlugin.files.css[css] %>" rel="stylesheet">
|
||||||
<% } %>
|
<% } %>
|
||||||
<% if (htmlWebpackPlugin.files.favicon) { %>
|
<% if (htmlWebpackPlugin.files.favicon) { %>
|
||||||
<link rel="shortcut icon" href="/<%= htmlWebpackPlugin.files.favicon%>">
|
<link rel="shortcut icon" href="<%= htmlWebpackPlugin.files.favicon%>">
|
||||||
<% } %>
|
<% } %>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<div id="app" class="is-fullheight"></div>
|
<div id="app" class="is-fullheight"></div>
|
||||||
<script src="/config.js"></script>
|
|
||||||
<% for (var chunk in htmlWebpackPlugin.files.chunks) { %>
|
<% for (var chunk in htmlWebpackPlugin.files.chunks) { %>
|
||||||
<script type="text/javascript" src="/<%= htmlWebpackPlugin.files.chunks[chunk].entry %>"></script>
|
<script type="text/javascript" src="<%= htmlWebpackPlugin.files.chunks[chunk].entry %>"></script>
|
||||||
<% } %>
|
<% } %>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
@ -2,7 +2,6 @@ import './sass/_all.scss';
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import ReactDOM from 'react-dom';
|
import ReactDOM from 'react-dom';
|
||||||
import { App } from './components/App';
|
import { App } from './components/App';
|
||||||
import { Config } from './config';
|
|
||||||
|
|
||||||
import '@fortawesome/fontawesome-free/js/fontawesome'
|
import '@fortawesome/fontawesome-free/js/fontawesome'
|
||||||
import '@fortawesome/fontawesome-free/js/solid'
|
import '@fortawesome/fontawesome-free/js/solid'
|
||||||
|
@ -1,3 +0,0 @@
|
|||||||
// Use this file to customize client configuration.
|
|
||||||
// See frontend/src/config.ts for more informations.
|
|
||||||
window['__CONFIG__'] = {};
|
|
@ -1,69 +0,0 @@
|
|||||||
import { Action } from "redux";
|
|
||||||
import { AccessGrant } from "../../util/auth";
|
|
||||||
import { IdToken } from "../../types/idToken";
|
|
||||||
|
|
||||||
export const LOGOUT = "LOGOUT_REQUEST";
|
|
||||||
|
|
||||||
export function logout() {
|
|
||||||
return { type: LOGOUT };
|
|
||||||
};
|
|
||||||
|
|
||||||
export const LOGIN_REQUEST = "LOGIN_REQUEST";
|
|
||||||
export const LOGIN_SUCCESS = "LOGIN_SUCCESS";
|
|
||||||
export const LOGIN_FAILURE = "LOGIN_FAILURE";
|
|
||||||
|
|
||||||
export function login() {
|
|
||||||
return { type: LOGIN_REQUEST };
|
|
||||||
};
|
|
||||||
|
|
||||||
export const HANDLE_OAUTH2_CALLBACK_REQUEST = "HANDLE_OAUTH2_CALLBACK_REQUEST";
|
|
||||||
export const HANDLE_OAUTH2_CALLBACK_SUCCESS = "HANDLE_OAUTH2_CALLBACK_SUCCESS";
|
|
||||||
export const HANDLE_OAUTH2_CALLBACK_FAILURE = "HANDLE_OAUTH2_CALLBACK_FAILURE";
|
|
||||||
|
|
||||||
export interface handleOAuth2CallbackAction extends Action {
|
|
||||||
search: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export function handleOAuth2Callback(search: string): handleOAuth2CallbackAction {
|
|
||||||
return { type: HANDLE_OAUTH2_CALLBACK_REQUEST, search };
|
|
||||||
};
|
|
||||||
|
|
||||||
export interface handleOAuth2CallbackSuccessAction extends Action {
|
|
||||||
grant: AccessGrant
|
|
||||||
}
|
|
||||||
|
|
||||||
export function handleOAuth2CallbackSuccess(grant: AccessGrant): handleOAuth2CallbackSuccessAction {
|
|
||||||
return { type: HANDLE_OAUTH2_CALLBACK_SUCCESS, grant };
|
|
||||||
};
|
|
||||||
|
|
||||||
export const PARSE_ID_TOKEN_REQUEST = "PARSE_ID_TOKEN_REQUEST";
|
|
||||||
export const PARSE_ID_TOKEN_SUCCESS = "PARSE_ID_TOKEN_SUCCESS";
|
|
||||||
export const PARSE_ID_TOKEN_FAILURE = "PARSE_ID_TOKEN_FAILURE";
|
|
||||||
|
|
||||||
export interface parseIdTokenAction extends Action {
|
|
||||||
rawIdToken: string
|
|
||||||
};
|
|
||||||
|
|
||||||
export function parseIdToken(rawIdToken: string): parseIdTokenAction {
|
|
||||||
return { type: PARSE_ID_TOKEN_REQUEST, rawIdToken };
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
export interface parseIdTokenSuccessAction extends Action {
|
|
||||||
idToken: IdToken
|
|
||||||
}
|
|
||||||
|
|
||||||
export function parseIdTokenSuccess(idToken: IdToken): parseIdTokenSuccessAction {
|
|
||||||
return { type: PARSE_ID_TOKEN_SUCCESS, idToken };
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
export const SET_CURRENT_USER = 'SET_CURRENT_USER';
|
|
||||||
|
|
||||||
export interface setCurrentUserAction extends Action {
|
|
||||||
email: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export function setCurrentUser(email: string): setCurrentUserAction {
|
|
||||||
return { type: SET_CURRENT_USER, email };
|
|
||||||
}
|
|
7
frontend/src/store/actions/logout.ts
Normal file
7
frontend/src/store/actions/logout.ts
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
export const LOGOUT_REQUEST = "LOGOUT_REQUEST";
|
||||||
|
export const LOGOUT_SUCCESS = "LOGOUT_SUCCESS";
|
||||||
|
export const LOGOUT_FAILURE = "LOGOUT_FAILURE";
|
||||||
|
|
||||||
|
export function logout() {
|
||||||
|
return { type: LOGOUT_REQUEST };
|
||||||
|
};
|
@ -1,19 +0,0 @@
|
|||||||
import { Action } from "redux";
|
|
||||||
import { User } from "../../types/user";
|
|
||||||
|
|
||||||
export const FETCH_PROFILE_REQUEST = 'FETCH_PROFILE_REQUEST';
|
|
||||||
export const FETCH_PROFILE_SUCCESS = 'FETCH_PROFILE_SUCCESS';
|
|
||||||
export const FETCH_PROFILE_FAILURE = 'FETCH_PROFILE_FAILURE';
|
|
||||||
|
|
||||||
export interface fetchProfileRequestAction extends Action {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface fetchProfileSuccessAction extends Action {
|
|
||||||
profile: User
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
export function fetchProfile(): fetchProfileRequestAction {
|
|
||||||
return { type: FETCH_PROFILE_REQUEST }
|
|
||||||
}
|
|
@ -1,55 +0,0 @@
|
|||||||
import { Action } from "redux";
|
|
||||||
import { User } from "../../types/user";
|
|
||||||
import { SET_CURRENT_USER, setCurrentUserAction, LOGOUT } from "../actions/auth";
|
|
||||||
import { FETCH_PROFILE_SUCCESS, fetchProfileSuccessAction } from "../actions/profile";
|
|
||||||
|
|
||||||
export interface AuthState {
|
|
||||||
isAuthenticated: boolean
|
|
||||||
currentUser: User
|
|
||||||
}
|
|
||||||
|
|
||||||
const defaultState = {
|
|
||||||
isAuthenticated: false,
|
|
||||||
currentUser: null,
|
|
||||||
};
|
|
||||||
|
|
||||||
export function authReducer(state = defaultState, action: Action): AuthState {
|
|
||||||
switch (action.type) {
|
|
||||||
case SET_CURRENT_USER:
|
|
||||||
return handleSetCurrentUser(state, action as setCurrentUserAction);
|
|
||||||
case LOGOUT:
|
|
||||||
return handleLogout(state);
|
|
||||||
case FETCH_PROFILE_SUCCESS:
|
|
||||||
return handleFetchProfileSuccess(state, action as fetchProfileSuccessAction);
|
|
||||||
|
|
||||||
}
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleSetCurrentUser(state: AuthState, { email }: setCurrentUserAction): AuthState {
|
|
||||||
return {
|
|
||||||
...state,
|
|
||||||
isAuthenticated: true,
|
|
||||||
currentUser: {
|
|
||||||
email
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
function handleLogout(state: AuthState): AuthState {
|
|
||||||
return {
|
|
||||||
...state,
|
|
||||||
isAuthenticated: false,
|
|
||||||
currentUser: null,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
function handleFetchProfileSuccess(state: AuthState, { profile }: fetchProfileSuccessAction): AuthState {
|
|
||||||
return {
|
|
||||||
...state,
|
|
||||||
isAuthenticated: true,
|
|
||||||
currentUser: {
|
|
||||||
...profile,
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
@ -1,18 +1,8 @@
|
|||||||
import { Action } from "redux";
|
|
||||||
|
|
||||||
export interface FlagsState {
|
|
||||||
actions: { [actionName: string]: ActionState }
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ActionState {
|
|
||||||
isLoading: boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
const defaultState = {
|
const defaultState = {
|
||||||
actions: {}
|
actions: {}
|
||||||
};
|
};
|
||||||
|
|
||||||
export function flagsReducer(state = defaultState, action: Action): FlagsState {
|
export function flagsReducer(state = defaultState, action: any) {
|
||||||
const matches = (/^(.*)_((SUCCESS)|(FAILURE)|(REQUEST))$/).exec(action.type);
|
const matches = (/^(.*)_((SUCCESS)|(FAILURE)|(REQUEST))$/).exec(action.type);
|
||||||
|
|
||||||
if(!matches) return state;
|
if(!matches) return state;
|
||||||
|
@ -1,13 +1,6 @@
|
|||||||
import { combineReducers } from 'redux';
|
import { combineReducers } from 'redux';
|
||||||
import { flagsReducer, FlagsState } from './flags';
|
import { flagsReducer } from './flags';
|
||||||
import { authReducer, AuthState } from './auth';
|
|
||||||
|
|
||||||
export interface RootState {
|
|
||||||
auth: AuthState,
|
|
||||||
flags: FlagsState,
|
|
||||||
}
|
|
||||||
|
|
||||||
export const rootReducer = combineReducers({
|
export const rootReducer = combineReducers({
|
||||||
flags: flagsReducer,
|
flags: flagsReducer,
|
||||||
auth: authReducer,
|
|
||||||
});
|
});
|
@ -1,98 +0,0 @@
|
|||||||
import { put, takeLatest, all } from 'redux-saga/effects';
|
|
||||||
import {
|
|
||||||
LOGOUT, LOGIN_REQUEST,
|
|
||||||
HANDLE_OAUTH2_CALLBACK_REQUEST, handleOAuth2CallbackAction,
|
|
||||||
HANDLE_OAUTH2_CALLBACK_FAILURE, handleOAuth2CallbackSuccess,
|
|
||||||
parseIdTokenAction, parseIdToken,
|
|
||||||
PARSE_ID_TOKEN_REQUEST, PARSE_ID_TOKEN_FAILURE, parseIdTokenSuccess,
|
|
||||||
setCurrentUser, LOGIN_FAILURE,
|
|
||||||
} from '../actions/auth';
|
|
||||||
import {
|
|
||||||
createLoginSession, LoginSession,
|
|
||||||
createAccessTokenRequest, saveAccessGrant,
|
|
||||||
saveLoginSessionState, getSavedLoginSessionState,
|
|
||||||
getLogoutURL, getSavedAccessGrant, clearAccessGrant
|
|
||||||
} from '../../util/auth';
|
|
||||||
import qs from 'qs';
|
|
||||||
import { UnauthorizedError } from '../../util/daddy';
|
|
||||||
import jwtDecode from 'jwt-decode';
|
|
||||||
import { IdToken } from '../../types/idToken';
|
|
||||||
|
|
||||||
export function* authRootSaga() {
|
|
||||||
yield all([
|
|
||||||
takeLatest(LOGIN_REQUEST, loginSaga),
|
|
||||||
takeLatest(LOGOUT, logoutSaga),
|
|
||||||
takeLatest(HANDLE_OAUTH2_CALLBACK_REQUEST, handleOAuth2CallbackSaga),
|
|
||||||
takeLatest(PARSE_ID_TOKEN_REQUEST, parseIDTokenSaga),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function* loginSaga() {
|
|
||||||
try {
|
|
||||||
const loginSession: LoginSession = yield createLoginSession();
|
|
||||||
console.log('Code verifier is ', loginSession.verifier);
|
|
||||||
console.log('State is ', loginSession.state);
|
|
||||||
saveLoginSessionState(loginSession.verifier, loginSession.state);
|
|
||||||
window.location.replace(loginSession.redirectUrl);
|
|
||||||
} catch(err) {
|
|
||||||
yield put({ type: LOGIN_FAILURE, err });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function* logoutSaga() {
|
|
||||||
const accessGrant = getSavedAccessGrant();
|
|
||||||
const logoutURL = getLogoutURL(accessGrant.id_token);
|
|
||||||
clearAccessGrant();
|
|
||||||
window.location.replace(logoutURL);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function* handleOAuth2CallbackSaga({ search }: handleOAuth2CallbackAction) {
|
|
||||||
const query = search.substring(1);
|
|
||||||
const params = qs.parse(query);
|
|
||||||
|
|
||||||
const loginSession = getSavedLoginSessionState();
|
|
||||||
|
|
||||||
console.log('Stored state verifier is', loginSession.state);
|
|
||||||
if (loginSession.state !== params.state) {
|
|
||||||
yield put({ type: HANDLE_OAUTH2_CALLBACK_FAILURE, err: new Error("Invalid state") });
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log('Stored code verifier is', loginSession.verifier);
|
|
||||||
console.log('Authorization code is', params.code);
|
|
||||||
|
|
||||||
const req = createAccessTokenRequest(params.code as string, loginSession.verifier);
|
|
||||||
|
|
||||||
let grant;
|
|
||||||
try {
|
|
||||||
grant = yield fetch(req.url, { method: "POST", body: req.data })
|
|
||||||
.then(res => {
|
|
||||||
if (res.status === 401) return Promise.reject(new UnauthorizedError());
|
|
||||||
return res;
|
|
||||||
})
|
|
||||||
.then(res => res.json());
|
|
||||||
} catch(err) {
|
|
||||||
yield put({ type: HANDLE_OAUTH2_CALLBACK_FAILURE, err });
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log("Access grant is", grant);
|
|
||||||
saveAccessGrant(grant);
|
|
||||||
|
|
||||||
yield put(handleOAuth2CallbackSuccess(grant));
|
|
||||||
yield put(parseIdToken(grant.id_token));
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
export function* parseIDTokenSaga({ rawIdToken }: parseIdTokenAction) {
|
|
||||||
let idToken: IdToken;
|
|
||||||
try {
|
|
||||||
idToken = jwtDecode(rawIdToken);
|
|
||||||
} catch(err) {
|
|
||||||
yield put({ type: PARSE_ID_TOKEN_FAILURE, err });
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
yield put(parseIdTokenSuccess(idToken));
|
|
||||||
yield put(setCurrentUser(idToken.email));
|
|
||||||
};
|
|
@ -1,21 +1,9 @@
|
|||||||
import { UnauthorizedError } from "../../util/daddy";
|
import { UnauthorizedError } from "../../util/daddy";
|
||||||
import { put, all, takeEvery } from 'redux-saga/effects';
|
import { put } from 'redux-saga/effects';
|
||||||
import { logout } from '../actions/auth';
|
import { logout } from '../actions/logout';
|
||||||
|
|
||||||
export function* failureRootSaga() {
|
|
||||||
yield all([
|
|
||||||
takeEvery(patternFromRegExp(/^.*_FAILURE/), failuresSaga),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function* failuresSaga(action) {
|
export function* failuresSaga(action) {
|
||||||
if (action.error instanceof UnauthorizedError) {
|
if (action.error instanceof UnauthorizedError) {
|
||||||
yield put(logout());
|
yield put(logout());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function patternFromRegExp(re: any) {
|
|
||||||
return (action: any) => {
|
|
||||||
return re.test(action.type);
|
|
||||||
};
|
|
||||||
}
|
|
@ -1,18 +0,0 @@
|
|||||||
import { all, put } from "redux-saga/effects";
|
|
||||||
import { getSavedAccessGrant } from "../../util/auth";
|
|
||||||
import { parseIdToken } from "../actions/auth";
|
|
||||||
|
|
||||||
export function* initRootSaga() {
|
|
||||||
yield all([
|
|
||||||
retrieveSessionSaga(),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function* retrieveSessionSaga() {
|
|
||||||
console.log("Checking session status...");
|
|
||||||
|
|
||||||
const accessGrant = getSavedAccessGrant();
|
|
||||||
if (!accessGrant) return;
|
|
||||||
|
|
||||||
yield put(parseIdToken(accessGrant.id_token));
|
|
||||||
}
|
|
17
frontend/src/store/sagas/logout.ts
Normal file
17
frontend/src/store/sagas/logout.ts
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
import { call, put } from 'redux-saga/effects';
|
||||||
|
import { LOGOUT_FAILURE, LOGOUT_SUCCESS } from '../actions/logout';
|
||||||
|
|
||||||
|
export function* logoutSaga() {
|
||||||
|
try {
|
||||||
|
yield call(fetch, '/logout', { mode: 'no-cors', credentials: 'include' });
|
||||||
|
} catch(err) {
|
||||||
|
yield put({ type: LOGOUT_FAILURE, error: err });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
yield put({ type: LOGOUT_SUCCESS });
|
||||||
|
}
|
||||||
|
|
||||||
|
export function* logoutSuccessSaga() {
|
||||||
|
window.location.reload();
|
||||||
|
}
|
@ -1,14 +1,18 @@
|
|||||||
import { all } from 'redux-saga/effects';
|
import { all, takeEvery, takeLatest } from 'redux-saga/effects';
|
||||||
import { failureRootSaga } from './failure';
|
import { failuresSaga } from './failure';
|
||||||
import { authRootSaga } from './auth';
|
import { LOGOUT_REQUEST, LOGOUT_SUCCESS } from '../actions/logout';
|
||||||
import { initRootSaga } from './init';
|
import { logoutSaga, logoutSuccessSaga } from './logout';
|
||||||
import { usersRootSaga } from './users';
|
|
||||||
|
|
||||||
export function* rootSaga() {
|
export function* rootSaga() {
|
||||||
yield all([
|
yield all([
|
||||||
initRootSaga(),
|
takeEvery(patternFromRegExp(/^.*_FAILURE/), failuresSaga),
|
||||||
failureRootSaga(),
|
takeLatest(LOGOUT_REQUEST, logoutSaga),
|
||||||
authRootSaga(),
|
takeLatest(LOGOUT_SUCCESS, logoutSuccessSaga)
|
||||||
usersRootSaga(),
|
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function patternFromRegExp(re: any) {
|
||||||
|
return (action: any) => {
|
||||||
|
return re.test(action.type);
|
||||||
|
};
|
||||||
|
}
|
@ -1,37 +0,0 @@
|
|||||||
import { DaddyClient } from "../../util/daddy";
|
|
||||||
import { Config } from "../../config";
|
|
||||||
import { getSavedAccessGrant } from "../../util/auth";
|
|
||||||
import { all, takeLatest, put, select } from "redux-saga/effects";
|
|
||||||
import { FETCH_PROFILE_REQUEST, fetchProfile, FETCH_PROFILE_FAILURE, FETCH_PROFILE_SUCCESS } from "../actions/profile";
|
|
||||||
import { SET_CURRENT_USER } from "../actions/auth";
|
|
||||||
import { RootState } from "../reducers/root";
|
|
||||||
import { User } from "../../types/user";
|
|
||||||
|
|
||||||
export function* usersRootSaga() {
|
|
||||||
yield all([
|
|
||||||
takeLatest(SET_CURRENT_USER, onCurrentUserChangeSaga),
|
|
||||||
takeLatest(FETCH_PROFILE_REQUEST, fetchProfileSaga),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function* onCurrentUserChangeSaga() {
|
|
||||||
yield put(fetchProfile());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export function* fetchProfileSaga() {
|
|
||||||
const grant = getSavedAccessGrant();
|
|
||||||
const client = new DaddyClient(Config.graphQLEndpoint, grant.id_token);
|
|
||||||
|
|
||||||
let profile: User;
|
|
||||||
try {
|
|
||||||
const currentUser: User = yield select((state: RootState) => state.auth.currentUser);
|
|
||||||
profile = yield client.fetchUser(currentUser.email).then(result => result.user);
|
|
||||||
} catch(err) {
|
|
||||||
yield put({ type: FETCH_PROFILE_FAILURE, err });
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
yield put({type: FETCH_PROFILE_SUCCESS, profile });
|
|
||||||
}
|
|
@ -1,3 +0,0 @@
|
|||||||
export interface IdToken {
|
|
||||||
email: string
|
|
||||||
}
|
|
@ -1,6 +0,0 @@
|
|||||||
export interface User {
|
|
||||||
email: string
|
|
||||||
full_name?: string
|
|
||||||
updated_at?: Date
|
|
||||||
created_at?: Date
|
|
||||||
}
|
|
@ -1,126 +0,0 @@
|
|||||||
import { Config } from '../config';
|
|
||||||
|
|
||||||
export interface LoginSession {
|
|
||||||
state: string
|
|
||||||
redirectUrl: string
|
|
||||||
verifier: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export function generateRandomString() {
|
|
||||||
var array = new Uint32Array(28);
|
|
||||||
window.crypto.getRandomValues(array);
|
|
||||||
return Array.from(array, dec => ('0' + dec.toString(16)).substr(-2)).join('');
|
|
||||||
}
|
|
||||||
|
|
||||||
export function sha256(plain): PromiseLike<any> {
|
|
||||||
const encoder = new TextEncoder();
|
|
||||||
const data = encoder.encode(plain);
|
|
||||||
return window.crypto.subtle.digest('SHA-256', data);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function pkceChallengeFromVerifier(v): PromiseLike<string> {
|
|
||||||
return sha256(v)
|
|
||||||
.then(hashed => base64urlencode(hashed));
|
|
||||||
}
|
|
||||||
|
|
||||||
export function base64urlencode(str) {
|
|
||||||
return btoa(String.fromCharCode.apply(null, new Uint8Array(str)))
|
|
||||||
.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
|
|
||||||
}
|
|
||||||
|
|
||||||
export function createLoginSession(): Promise<LoginSession> {
|
|
||||||
// Based on https://auth0.com/docs/api-auth/tutorials/authorization-code-grant-pkce
|
|
||||||
const state = generateRandomString();
|
|
||||||
const verifier = generateRandomString();
|
|
||||||
|
|
||||||
return new Promise<LoginSession>((resolve, reject) => {
|
|
||||||
try {
|
|
||||||
pkceChallengeFromVerifier(verifier).then(challenge => {
|
|
||||||
console.log('Code challenge is', challenge);
|
|
||||||
|
|
||||||
let redirectUrl=`${Config.oauth2AuthorizeURL}`;
|
|
||||||
redirectUrl += `?audience=${encodeURIComponent(Config.oauth2Audience)}`;
|
|
||||||
redirectUrl += `&scope=${encodeURIComponent(Config.oauth2Scope)}`;
|
|
||||||
redirectUrl += `&response_type=code`;
|
|
||||||
redirectUrl += `&client_id=${encodeURIComponent(Config.oauth2ClientId)}`
|
|
||||||
redirectUrl += `&code_challenge=${encodeURIComponent(challenge)}`;
|
|
||||||
redirectUrl += `&code_challenge_method=S256`
|
|
||||||
redirectUrl += `&redirect_uri=${encodeURIComponent(Config.oauth2RedirectURI)}`;
|
|
||||||
redirectUrl += `&state=${encodeURIComponent(state)}`;
|
|
||||||
|
|
||||||
return resolve({
|
|
||||||
state,
|
|
||||||
redirectUrl,
|
|
||||||
verifier,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
} catch(err) {
|
|
||||||
return reject(err);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
export interface AccessTokenRequest {
|
|
||||||
data: FormData,
|
|
||||||
url: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export function createAccessTokenRequest(code: string, verifier: string): AccessTokenRequest {
|
|
||||||
const data = new FormData();
|
|
||||||
data.append('grant_type', 'authorization_code');
|
|
||||||
data.append('client_id', Config.oauth2ClientId);
|
|
||||||
data.append('code_verifier', verifier);
|
|
||||||
data.append('code', code);
|
|
||||||
data.append('redirect_uri', Config.oauth2RedirectURI);
|
|
||||||
return {
|
|
||||||
url: Config.oauth2TokenURL,
|
|
||||||
data,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export function getLogoutURL(rawIdToken: string): string {
|
|
||||||
let logoutURL = Config.oauth2LogoutURL;
|
|
||||||
logoutURL += `?post_logout_redirect_uri=${encodeURIComponent(Config.oauth2PostLogoutRedirectURI)}`;
|
|
||||||
logoutURL += `&id_token_hint=${encodeURIComponent(rawIdToken)}`;
|
|
||||||
return logoutURL;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface AccessGrant {
|
|
||||||
access_token: string
|
|
||||||
expires_in: number
|
|
||||||
id_token: string
|
|
||||||
refresh_token: string
|
|
||||||
scope: string
|
|
||||||
token_type: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export function saveLoginSessionState(verifier: string, state: string) {
|
|
||||||
window.localStorage.setItem('login_verifier', verifier);
|
|
||||||
window.localStorage.setItem('login_state', state);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getSavedLoginSessionState(cleanup = true) {
|
|
||||||
const loginSession = {
|
|
||||||
verifier: window.localStorage.getItem('login_verifier'),
|
|
||||||
state: window.localStorage.getItem('login_state')
|
|
||||||
};
|
|
||||||
if (cleanup) {
|
|
||||||
window.localStorage.removeItem('login_verifier');
|
|
||||||
window.localStorage.removeItem('login_state');
|
|
||||||
}
|
|
||||||
return loginSession;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function saveAccessGrant(grant: AccessGrant) {
|
|
||||||
window.localStorage.setItem('access_grant', JSON.stringify(grant));
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getSavedAccessGrant(): AccessGrant {
|
|
||||||
const raw = window.localStorage.getItem('access_grant');
|
|
||||||
if (raw === "") return null;
|
|
||||||
return JSON.parse(raw) as AccessGrant;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function clearAccessGrant() {
|
|
||||||
window.localStorage.removeItem('access_grant');
|
|
||||||
}
|
|
@ -1,6 +1,3 @@
|
|||||||
import { GraphQLClient } from 'graphql-request'
|
|
||||||
import { Config } from "../config";
|
|
||||||
|
|
||||||
export class UnauthorizedError extends Error {
|
export class UnauthorizedError extends Error {
|
||||||
constructor(...args: any[]) {
|
constructor(...args: any[]) {
|
||||||
super(...args)
|
super(...args)
|
||||||
@ -10,35 +7,16 @@ export class UnauthorizedError extends Error {
|
|||||||
|
|
||||||
export class DaddyClient {
|
export class DaddyClient {
|
||||||
|
|
||||||
gql: GraphQLClient
|
assertOk(res: any) {
|
||||||
|
if (!res.ok) return Promise.reject(new Error('Request failed'));
|
||||||
constructor(endpoint: string, idToken: string) {
|
return res;
|
||||||
this.gql = new GraphQLClient(endpoint, {
|
|
||||||
headers: {
|
|
||||||
Authorization: `Bearer ${idToken}`,
|
|
||||||
mode: 'cors',
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fetchUser(email: string) {
|
assertAuthorization(res: any) {
|
||||||
return this.gql.rawRequest(`
|
if (res.status === 401 || res.status === 404) return Promise.reject(new UnauthorizedError());
|
||||||
query fetchUser {
|
return res;
|
||||||
user(where: {email: {eq: $email}}) {
|
|
||||||
id
|
|
||||||
created_at
|
|
||||||
updated_at
|
|
||||||
email,
|
|
||||||
full_name
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`, { email })
|
|
||||||
.then(this.assertAuthorization)
|
|
||||||
}
|
|
||||||
|
|
||||||
assertAuthorization({ status, data }: any) {
|
|
||||||
if (status === 401) return Promise.reject(new UnauthorizedError());
|
|
||||||
return data;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const daddy = new DaddyClient();
|
@ -3,8 +3,7 @@ const path = require('path');
|
|||||||
// Plugins
|
// Plugins
|
||||||
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
|
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
|
||||||
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
||||||
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
|
const WebpackCleanupPlugin = require('webpack-cleanup-plugin');
|
||||||
const CopyPlugin = require('copy-webpack-plugin');
|
|
||||||
|
|
||||||
const env = process.env;
|
const env = process.env;
|
||||||
|
|
||||||
@ -13,7 +12,6 @@ module.exports = {
|
|||||||
entry: './src/index.tsx',
|
entry: './src/index.tsx',
|
||||||
devtool: 'inline-source-map',
|
devtool: 'inline-source-map',
|
||||||
output: {
|
output: {
|
||||||
filename: '[name].[contenthash].js',
|
|
||||||
path: path.join(__dirname, 'dist')
|
path: path.join(__dirname, 'dist')
|
||||||
},
|
},
|
||||||
resolve: {
|
resolve: {
|
||||||
@ -22,9 +20,7 @@ module.exports = {
|
|||||||
devServer: {
|
devServer: {
|
||||||
contentBase: path.join(__dirname, 'dist'),
|
contentBase: path.join(__dirname, 'dist'),
|
||||||
compress: true,
|
compress: true,
|
||||||
port: 8081,
|
port: 8081
|
||||||
historyApiFallback: true,
|
|
||||||
writeToDisk: true,
|
|
||||||
},
|
},
|
||||||
module: {
|
module: {
|
||||||
rules: [{
|
rules: [{
|
||||||
@ -52,7 +48,7 @@ module.exports = {
|
|||||||
use: [{
|
use: [{
|
||||||
loader: 'file-loader',
|
loader: 'file-loader',
|
||||||
options: {
|
options: {
|
||||||
name: '[name].[contenthash].[ext]',
|
name: '[name].[ext]',
|
||||||
outputPath: '/resources/'
|
outputPath: '/resources/'
|
||||||
}
|
}
|
||||||
}]
|
}]
|
||||||
@ -63,20 +59,17 @@ module.exports = {
|
|||||||
}]
|
}]
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
new CleanWebpackPlugin(),
|
|
||||||
new MiniCssExtractPlugin({
|
new MiniCssExtractPlugin({
|
||||||
filename: "css/[name].[contenthash].css",
|
filename: "css/[name].css",
|
||||||
chunkFilename: "css/[id].css"
|
chunkFilename: "css/[id].css"
|
||||||
}),
|
}),
|
||||||
new HtmlWebpackPlugin({
|
new HtmlWebpackPlugin({
|
||||||
template: './src/index.html',
|
template: './src/index.html',
|
||||||
inject: false,
|
inject: false,
|
||||||
favicon: "./src/resources/favicon.png",
|
favicon: "./src/resources/favicon.png"
|
||||||
}),
|
|
||||||
new CopyPlugin({
|
|
||||||
patterns: [
|
|
||||||
{ from: './src/resources/config.sample.js', to: 'config.js' },
|
|
||||||
],
|
|
||||||
}),
|
}),
|
||||||
|
new WebpackCleanupPlugin({
|
||||||
|
exclude: ['resources/logo.svg']
|
||||||
|
})
|
||||||
]
|
]
|
||||||
}
|
}
|
@ -1,18 +0,0 @@
|
|||||||
FROM oryd/hydra:v1.4.2-alpine
|
|
||||||
|
|
||||||
USER root
|
|
||||||
|
|
||||||
COPY docker-entrypoint.sh /usr/local/bin/docker-entrypoint
|
|
||||||
RUN chmod a+x /usr/local/bin/docker-entrypoint
|
|
||||||
|
|
||||||
COPY first-run.sh /usr/local/bin/docker-first-run
|
|
||||||
RUN chmod a+x /usr/local/bin/docker-first-run
|
|
||||||
|
|
||||||
COPY hydra-init.d /hydra-init.d
|
|
||||||
|
|
||||||
RUN mkdir -p /home/ory && chown -R ory: /home/ory
|
|
||||||
USER ory
|
|
||||||
|
|
||||||
ENTRYPOINT ["/usr/local/bin/docker-entrypoint"]
|
|
||||||
|
|
||||||
CMD ["hydra", "serve", "all"]
|
|
@ -1,14 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
set -xeo pipefail
|
|
||||||
|
|
||||||
LIFECYCLEFLAGS_DIR="$HOME/.container-lifecycle"
|
|
||||||
|
|
||||||
mkdir -p "$LIFECYCLEFLAGS_DIR"
|
|
||||||
|
|
||||||
if [ ! -f "$LIFECYCLEFLAGS_DIR/first-run" ]; then
|
|
||||||
/usr/local/bin/docker-first-run
|
|
||||||
touch "$LIFECYCLEFLAGS_DIR/first-run"
|
|
||||||
fi
|
|
||||||
|
|
||||||
exec "$@"
|
|
@ -1,8 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
hydra migrate sql -e -y
|
|
||||||
|
|
||||||
hydra serve all --dangerous-force-http &
|
|
||||||
HYDRA_PID=$!
|
|
||||||
run-parts --exit-on-error /hydra-init.d
|
|
||||||
kill $HYDRA_PID
|
|
@ -1,9 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
hydra clients create \
|
|
||||||
--id daddy \
|
|
||||||
-n Daddy \
|
|
||||||
-a email,email_verified,offline_access,openid \
|
|
||||||
--token-endpoint-auth-method none \
|
|
||||||
--post-logout-callbacks http://localhost:8081 \
|
|
||||||
-c http://localhost:8081/oauth2/callback
|
|
@ -1,3 +0,0 @@
|
|||||||
FROM postgres:12-alpine
|
|
||||||
|
|
||||||
COPY ./initdb.d /docker-entrypoint-initdb.d
|
|
@ -1,16 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL
|
|
||||||
CREATE USER hydra WITH ENCRYPTED PASSWORD 'hydra';
|
|
||||||
CREATE DATABASE hydra;
|
|
||||||
GRANT ALL PRIVILEGES ON DATABASE hydra TO hydra;
|
|
||||||
EOSQL
|
|
||||||
|
|
||||||
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL
|
|
||||||
CREATE USER daddy WITH ENCRYPTED PASSWORD 'daddy';
|
|
||||||
CREATE DATABASE daddy;
|
|
||||||
GRANT ALL PRIVILEGES ON DATABASE daddy TO daddy;
|
|
||||||
ALTER DATABASE daddy OWNER TO daddy;
|
|
||||||
EOSQL
|
|
@ -5,12 +5,12 @@ ARG HTTPS_PROXY=
|
|||||||
ARG http_proxy=
|
ARG http_proxy=
|
||||||
ARG https_proxy=
|
ARG https_proxy=
|
||||||
|
|
||||||
ARG SUPERGRAPH_VERSION=88ba105b70c60b2c7467dc1f76f041cec2614a04
|
ARG SUPERGRAPH_VERSION=v0.14.17
|
||||||
ARG WAITFORIT_VERSION=v2.4.1
|
ARG WAITFORIT_VERSION=v2.4.1
|
||||||
|
|
||||||
RUN apk add --no-cache go make git curl bash ca-certificates
|
RUN apk add --no-cache go make git curl bash ca-certificates
|
||||||
|
|
||||||
RUN git clone https://forge.cadoles.com/wpetit/super-graph.git \
|
RUN git clone https://github.com/dosco/super-graph \
|
||||||
&& export PATH="$PATH:/root/go/bin" \
|
&& export PATH="$PATH:/root/go/bin" \
|
||||||
&& export CGO_ENABLED=0 \
|
&& export CGO_ENABLED=0 \
|
||||||
&& cd super-graph \
|
&& cd super-graph \
|
||||||
|
15
misc/debian/nginx/daddy.conf
Normal file
15
misc/debian/nginx/daddy.conf
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
server {
|
||||||
|
listen 80 default_server;
|
||||||
|
server_name daddy.local;
|
||||||
|
|
||||||
|
root /usr/share/daddy/client/public;
|
||||||
|
index index.html;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
try_files $uri /index.html =404;
|
||||||
|
}
|
||||||
|
|
||||||
|
location /api/v1/graphql {
|
||||||
|
proxy_pass http://127.0.0.1:8080/api/v1/graphql;
|
||||||
|
}
|
||||||
|
}
|
1
misc/debian/systemd/daddy.env
Normal file
1
misc/debian/systemd/daddy.env
Normal file
@ -0,0 +1 @@
|
|||||||
|
GO_ENV=prod
|
Reference in New Issue
Block a user