Compare commits
57 Commits
v0.2.0
...
6a6ff84ff2
| Author | SHA1 | Date | |
|---|---|---|---|
| 6a6ff84ff2 | |||
|
b6949acc96
|
|||
|
814633034f
|
|||
| 260dedb6cf | |||
|
656c887811
|
|||
|
7e9af716ac
|
|||
|
58cc6811f9
|
|||
|
8ad85636d9
|
|||
|
35e2c8cd30
|
|||
| 4526c941b8 | |||
| 4f5ebd5330 | |||
|
d7e4c6f3ae
|
|||
|
14caefe2d1
|
|||
|
0110f27ada
|
|||
|
dc7cf107c2
|
|||
| 4fbfaadb44 | |||
|
a01cb9ae21
|
|||
|
698e4381c2
|
|||
|
8997349186
|
|||
|
92bfc33bf0
|
|||
|
c6eb21faad
|
|||
| 2d9bc90b16 | |||
|
a0c579e319
|
|||
|
f289ee9365
|
|||
| 46a7345ce9 | |||
|
e12d02a988
|
|||
| 5e8618f25a | |||
|
2bdf08a523
|
|||
|
9ddd36c414
|
|||
|
9372ea7343
|
|||
|
c62ce00184
|
|||
|
4d8cd740ba
|
|||
|
9858572a2f
|
|||
|
51edf55ae9
|
|||
| 75485ce8e9 | |||
|
fcbfcc4007
|
|||
|
cdcb7b3aef
|
|||
| bcf5172956 | |||
|
26c6c5a3b2
|
|||
|
4a65573934
|
|||
|
5e2d5c3b28
|
|||
|
2f70bae523
|
|||
|
40f3e8327a
|
|||
|
f3d6e29e4e
|
|||
| 8903ae2624 | |||
|
26e9073674
|
|||
| 73a89c2601 | |||
|
7d4dee17b7
|
|||
| 602ca6ee94 | |||
|
69fc1ca57e
|
|||
|
ee72a32c7e
|
|||
|
8a0d89ef60
|
|||
|
54af949c7d
|
|||
|
6dac732a7f
|
|||
|
e8c1a6066a
|
|||
| 44fadb12d6 | |||
|
533452469b
|
@@ -1,8 +1 @@
|
|||||||
LDAP_HOST=192.168.33.10
|
EJABBERD_API_URL='https://xmpp.kosmos.org/api'
|
||||||
LDAP_PORT=389
|
|
||||||
#
|
|
||||||
# Production LDAP server:
|
|
||||||
#
|
|
||||||
# LDAP_HOST=ldap.kosmos.org
|
|
||||||
# LDAP_PORT=636
|
|
||||||
# LDAP_USE_TLS=true
|
|
||||||
|
|||||||
1
.env.production
Normal file
1
.env.production
Normal file
@@ -0,0 +1 @@
|
|||||||
|
EJABBERD_API_URL='https://xmpp.kosmos.org:5443/api'
|
||||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -39,3 +39,6 @@ yarn-debug.log*
|
|||||||
|
|
||||||
# Ignore local dotenv config file
|
# Ignore local dotenv config file
|
||||||
.env
|
.env
|
||||||
|
|
||||||
|
# Ignore redis dumps from sidekiq
|
||||||
|
dump.rdb
|
||||||
|
|||||||
12
Gemfile
12
Gemfile
@@ -21,13 +21,22 @@ gem 'jbuilder', '~> 2.7'
|
|||||||
# Reduces boot times through caching; required in config/boot.rb
|
# Reduces boot times through caching; required in config/boot.rb
|
||||||
gem 'bootsnap', '>= 1.4.2', require: false
|
gem 'bootsnap', '>= 1.4.2', require: false
|
||||||
|
|
||||||
gem 'dotenv-rails', groups: [:development, :test]
|
# Configuration
|
||||||
|
gem 'dotenv-rails'
|
||||||
|
|
||||||
|
# Authentication
|
||||||
gem 'warden'
|
gem 'warden'
|
||||||
gem 'devise'
|
gem 'devise'
|
||||||
gem 'devise_ldap_authenticatable'
|
gem 'devise_ldap_authenticatable'
|
||||||
gem 'net-ldap'
|
gem 'net-ldap'
|
||||||
|
|
||||||
|
# HTTP requests
|
||||||
|
gem 'faraday'
|
||||||
|
|
||||||
|
# Background/scheduled jobs
|
||||||
|
gem 'sidekiq'
|
||||||
|
gem 'sidekiq-scheduler'
|
||||||
|
|
||||||
group :development, :test do
|
group :development, :test do
|
||||||
# Use sqlite3 as the database for Active Record
|
# Use sqlite3 as the database for Active Record
|
||||||
gem 'sqlite3', '~> 1.4'
|
gem 'sqlite3', '~> 1.4'
|
||||||
@@ -51,6 +60,7 @@ group :test do
|
|||||||
gem 'factory_bot_rails'
|
gem 'factory_bot_rails'
|
||||||
gem 'capybara'
|
gem 'capybara'
|
||||||
gem 'database_cleaner'
|
gem 'database_cleaner'
|
||||||
|
gem 'webmock'
|
||||||
end
|
end
|
||||||
|
|
||||||
group :production do
|
group :production do
|
||||||
|
|||||||
42
Gemfile.lock
42
Gemfile.lock
@@ -73,6 +73,9 @@ GEM
|
|||||||
regexp_parser (~> 1.5)
|
regexp_parser (~> 1.5)
|
||||||
xpath (~> 3.2)
|
xpath (~> 3.2)
|
||||||
concurrent-ruby (1.1.7)
|
concurrent-ruby (1.1.7)
|
||||||
|
connection_pool (2.2.3)
|
||||||
|
crack (0.4.3)
|
||||||
|
safe_yaml (~> 1.0.0)
|
||||||
crass (1.0.6)
|
crass (1.0.6)
|
||||||
database_cleaner (1.8.5)
|
database_cleaner (1.8.5)
|
||||||
devise (4.7.3)
|
devise (4.7.3)
|
||||||
@@ -89,15 +92,24 @@ GEM
|
|||||||
dotenv-rails (2.7.2)
|
dotenv-rails (2.7.2)
|
||||||
dotenv (= 2.7.2)
|
dotenv (= 2.7.2)
|
||||||
railties (>= 3.2, < 6.1)
|
railties (>= 3.2, < 6.1)
|
||||||
|
e2mmap (0.1.0)
|
||||||
erubi (1.9.0)
|
erubi (1.9.0)
|
||||||
|
et-orbi (1.2.4)
|
||||||
|
tzinfo
|
||||||
factory_bot (6.1.0)
|
factory_bot (6.1.0)
|
||||||
activesupport (>= 5.0.0)
|
activesupport (>= 5.0.0)
|
||||||
factory_bot_rails (6.1.0)
|
factory_bot_rails (6.1.0)
|
||||||
factory_bot (~> 6.1.0)
|
factory_bot (~> 6.1.0)
|
||||||
railties (>= 5.0.0)
|
railties (>= 5.0.0)
|
||||||
|
faraday (0.17.0)
|
||||||
|
multipart-post (>= 1.2, < 3)
|
||||||
ffi (1.13.1)
|
ffi (1.13.1)
|
||||||
|
fugit (1.4.2)
|
||||||
|
et-orbi (~> 1.1, >= 1.1.8)
|
||||||
|
raabro (~> 1.4)
|
||||||
globalid (0.4.2)
|
globalid (0.4.2)
|
||||||
activesupport (>= 4.2.0)
|
activesupport (>= 4.2.0)
|
||||||
|
hashdiff (0.4.0)
|
||||||
i18n (1.8.5)
|
i18n (1.8.5)
|
||||||
concurrent-ruby (~> 1.0)
|
concurrent-ruby (~> 1.0)
|
||||||
jbuilder (2.10.1)
|
jbuilder (2.10.1)
|
||||||
@@ -126,6 +138,7 @@ GEM
|
|||||||
mini_portile2 (2.4.0)
|
mini_portile2 (2.4.0)
|
||||||
minitest (5.14.2)
|
minitest (5.14.2)
|
||||||
msgpack (1.3.3)
|
msgpack (1.3.3)
|
||||||
|
multipart-post (2.1.1)
|
||||||
net-ldap (0.16.3)
|
net-ldap (0.16.3)
|
||||||
nio4r (2.5.4)
|
nio4r (2.5.4)
|
||||||
nokogiri (1.10.10)
|
nokogiri (1.10.10)
|
||||||
@@ -135,6 +148,7 @@ GEM
|
|||||||
public_suffix (4.0.6)
|
public_suffix (4.0.6)
|
||||||
puma (4.3.6)
|
puma (4.3.6)
|
||||||
nio4r (~> 2.0)
|
nio4r (~> 2.0)
|
||||||
|
raabro (1.4.0)
|
||||||
rack (2.2.3)
|
rack (2.2.3)
|
||||||
rack-proxy (0.6.5)
|
rack-proxy (0.6.5)
|
||||||
rack
|
rack
|
||||||
@@ -170,6 +184,7 @@ GEM
|
|||||||
rb-fsevent (0.10.4)
|
rb-fsevent (0.10.4)
|
||||||
rb-inotify (0.10.1)
|
rb-inotify (0.10.1)
|
||||||
ffi (~> 1.0)
|
ffi (~> 1.0)
|
||||||
|
redis (4.2.5)
|
||||||
regexp_parser (1.8.2)
|
regexp_parser (1.8.2)
|
||||||
responders (3.0.1)
|
responders (3.0.1)
|
||||||
actionpack (>= 5.0)
|
actionpack (>= 5.0)
|
||||||
@@ -191,6 +206,9 @@ GEM
|
|||||||
rspec-mocks (~> 3.9)
|
rspec-mocks (~> 3.9)
|
||||||
rspec-support (~> 3.9)
|
rspec-support (~> 3.9)
|
||||||
rspec-support (3.10.0)
|
rspec-support (3.10.0)
|
||||||
|
rufus-scheduler (3.7.0)
|
||||||
|
fugit (~> 1.1, >= 1.1.6)
|
||||||
|
safe_yaml (1.0.5)
|
||||||
sass-rails (6.0.0)
|
sass-rails (6.0.0)
|
||||||
sassc-rails (~> 2.1, >= 2.1.1)
|
sassc-rails (~> 2.1, >= 2.1.1)
|
||||||
sassc (2.4.0)
|
sassc (2.4.0)
|
||||||
@@ -201,6 +219,17 @@ GEM
|
|||||||
sprockets (> 3.0)
|
sprockets (> 3.0)
|
||||||
sprockets-rails
|
sprockets-rails
|
||||||
tilt
|
tilt
|
||||||
|
sidekiq (6.1.3)
|
||||||
|
connection_pool (>= 2.2.2)
|
||||||
|
rack (~> 2.0)
|
||||||
|
redis (>= 4.2.0)
|
||||||
|
sidekiq-scheduler (3.0.1)
|
||||||
|
e2mmap
|
||||||
|
redis (>= 3, < 5)
|
||||||
|
rufus-scheduler (~> 3.2)
|
||||||
|
sidekiq (>= 3)
|
||||||
|
thwait
|
||||||
|
tilt (>= 1.4.0)
|
||||||
spring (2.1.1)
|
spring (2.1.1)
|
||||||
spring-watcher-listen (2.0.1)
|
spring-watcher-listen (2.0.1)
|
||||||
listen (>= 2.7, < 4.0)
|
listen (>= 2.7, < 4.0)
|
||||||
@@ -215,6 +244,8 @@ GEM
|
|||||||
sqlite3 (1.4.2)
|
sqlite3 (1.4.2)
|
||||||
thor (1.0.1)
|
thor (1.0.1)
|
||||||
thread_safe (0.3.6)
|
thread_safe (0.3.6)
|
||||||
|
thwait (0.2.0)
|
||||||
|
e2mmap
|
||||||
tilt (2.0.10)
|
tilt (2.0.10)
|
||||||
turbolinks (5.2.1)
|
turbolinks (5.2.1)
|
||||||
turbolinks-source (~> 5.2)
|
turbolinks-source (~> 5.2)
|
||||||
@@ -228,6 +259,10 @@ GEM
|
|||||||
activemodel (>= 6.0.0)
|
activemodel (>= 6.0.0)
|
||||||
bindex (>= 0.4.0)
|
bindex (>= 0.4.0)
|
||||||
railties (>= 6.0.0)
|
railties (>= 6.0.0)
|
||||||
|
webmock (3.6.0)
|
||||||
|
addressable (>= 2.3.6)
|
||||||
|
crack (>= 0.3.2)
|
||||||
|
hashdiff (>= 0.4.0, < 2.0.0)
|
||||||
webpacker (4.3.0)
|
webpacker (4.3.0)
|
||||||
activesupport (>= 4.2)
|
activesupport (>= 4.2)
|
||||||
rack-proxy (>= 0.6.1)
|
rack-proxy (>= 0.6.1)
|
||||||
@@ -241,6 +276,7 @@ GEM
|
|||||||
|
|
||||||
PLATFORMS
|
PLATFORMS
|
||||||
ruby
|
ruby
|
||||||
|
x86_64-linux
|
||||||
|
|
||||||
DEPENDENCIES
|
DEPENDENCIES
|
||||||
bootsnap (>= 1.4.2)
|
bootsnap (>= 1.4.2)
|
||||||
@@ -251,6 +287,7 @@ DEPENDENCIES
|
|||||||
devise_ldap_authenticatable
|
devise_ldap_authenticatable
|
||||||
dotenv-rails
|
dotenv-rails
|
||||||
factory_bot_rails
|
factory_bot_rails
|
||||||
|
faraday
|
||||||
jbuilder (~> 2.7)
|
jbuilder (~> 2.7)
|
||||||
letter_opener
|
letter_opener
|
||||||
letter_opener_web
|
letter_opener_web
|
||||||
@@ -261,6 +298,8 @@ DEPENDENCIES
|
|||||||
rails (~> 6.0.3, >= 6.0.3.4)
|
rails (~> 6.0.3, >= 6.0.3.4)
|
||||||
rspec-rails
|
rspec-rails
|
||||||
sass-rails (>= 6)
|
sass-rails (>= 6)
|
||||||
|
sidekiq
|
||||||
|
sidekiq-scheduler
|
||||||
spring
|
spring
|
||||||
spring-watcher-listen (~> 2.0.0)
|
spring-watcher-listen (~> 2.0.0)
|
||||||
sqlite3 (~> 1.4)
|
sqlite3 (~> 1.4)
|
||||||
@@ -268,7 +307,8 @@ DEPENDENCIES
|
|||||||
tzinfo-data
|
tzinfo-data
|
||||||
warden
|
warden
|
||||||
web-console (>= 3.3.0)
|
web-console (>= 3.3.0)
|
||||||
|
webmock
|
||||||
webpacker (~> 4.0)
|
webpacker (~> 4.0)
|
||||||
|
|
||||||
BUNDLED WITH
|
BUNDLED WITH
|
||||||
2.0.2
|
2.2.2
|
||||||
|
|||||||
11
README.md
11
README.md
@@ -11,7 +11,7 @@ credentials, invites, donations, etc..
|
|||||||
* [x] Log in with admin permissions
|
* [x] Log in with admin permissions
|
||||||
* [x] View LDAP users as admin
|
* [x] View LDAP users as admin
|
||||||
* [x] Sign up for a new account via invitation
|
* [x] Sign up for a new account via invitation
|
||||||
* [ ] List my donations
|
* [x] List my donations
|
||||||
* [ ] Invite new users from your account
|
* [ ] Invite new users from your account
|
||||||
* [ ] Sign up for a new account by donating upfront
|
* [ ] Sign up for a new account by donating upfront
|
||||||
* [ ] Sign up for a new account via proving contributions (via cryptographic signature)
|
* [ ] Sign up for a new account via proving contributions (via cryptographic signature)
|
||||||
@@ -38,6 +38,10 @@ Running the dev server:
|
|||||||
|
|
||||||
bundle exec rails server
|
bundle exec rails server
|
||||||
|
|
||||||
|
Running the background workers (requires Redis):
|
||||||
|
|
||||||
|
bundle exec sidekiq -C config/sidekiq.yml
|
||||||
|
|
||||||
Running all specs:
|
Running all specs:
|
||||||
|
|
||||||
bundle exec rspec
|
bundle exec rspec
|
||||||
@@ -62,6 +66,11 @@ manual LDIF imports etc. (or provide a staging instance)
|
|||||||
* [devise_ldap_authenticatable](https://github.com/cschiewek/devise_ldap_authenticatable)
|
* [devise_ldap_authenticatable](https://github.com/cschiewek/devise_ldap_authenticatable)
|
||||||
* [net/ldap](https://www.rubydoc.info/gems/net-ldap/Net/LDAP)
|
* [net/ldap](https://www.rubydoc.info/gems/net-ldap/Net/LDAP)
|
||||||
|
|
||||||
|
### Asynchronous jobs/workers
|
||||||
|
|
||||||
|
* [Sidekiq](https://github.com/mperham/sidekiq/wiki/)
|
||||||
|
* [ActiveJob](https://github.com/mperham/sidekiq/wiki/Active-Job)
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
[GNU Affero General Public License v3.0](https://choosealicense.com/licenses/agpl-3.0/)
|
[GNU Affero General Public License v3.0](https://choosealicense.com/licenses/agpl-3.0/)
|
||||||
|
|||||||
@@ -1,13 +0,0 @@
|
|||||||
html, body, h1, h2, h3, h4, h5, h6, p, pre, a, dl, dt, dd, ol, ul, li {
|
|
||||||
font-size: 100%;
|
|
||||||
vertical-align: baseline;
|
|
||||||
background: transparent;
|
|
||||||
box-sizing: border-box;
|
|
||||||
overflow: visible;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
line-height: 1;
|
|
||||||
}
|
|
||||||
13
app/assets/stylesheets/_variables.scss
Normal file
13
app/assets/stylesheets/_variables.scss
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
$content-width: 800px;
|
||||||
|
$content-max-width: 100%;
|
||||||
|
|
||||||
|
$text-color-body: #222;
|
||||||
|
$text-color-discreet: #888;
|
||||||
|
|
||||||
|
$background-color-notice: #efffc4;
|
||||||
|
$background-color-alert: #fff4c2;
|
||||||
|
|
||||||
|
$color-blue: #0d4f99;
|
||||||
|
$color-purple: #8955a0;
|
||||||
|
$color-red-bright: #c00;
|
||||||
|
$color-red-dark: #990c0e;
|
||||||
25
app/assets/stylesheets/admin.scss
Normal file
25
app/assets/stylesheets/admin.scss
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
@import "variables";
|
||||||
|
|
||||||
|
body#admin-panel {
|
||||||
|
#wrapper {
|
||||||
|
> header {
|
||||||
|
background: $color-red-bright;
|
||||||
|
background: linear-gradient(35deg, rgba(255,0,255,0.2) 0, rgba(153,12,14,0.9) 100%),
|
||||||
|
url('/img/bg-1.jpg');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#main-nav {
|
||||||
|
ul {
|
||||||
|
grid-template-columns: repeat(4, 1fr);
|
||||||
|
|
||||||
|
li {
|
||||||
|
a {
|
||||||
|
&.active {
|
||||||
|
border-bottom: 2px solid $color-red-bright;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
40
app/assets/stylesheets/donations.scss
Normal file
40
app/assets/stylesheets/donations.scss
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
ul.donations {
|
||||||
|
list-style: none;
|
||||||
|
|
||||||
|
li {
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
display: grid;
|
||||||
|
grid-row-gap: 0.5rem;
|
||||||
|
grid-column-gap: 2rem;
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
grid-template-areas:
|
||||||
|
"date amount-btc"
|
||||||
|
"public-name amounts-fiat";
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
grid-area: "date";
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
margin-bottom: 0;
|
||||||
|
|
||||||
|
&.amount-btc {
|
||||||
|
grid-area: amount-btc;
|
||||||
|
text-align: right;
|
||||||
|
font-family: monospace;
|
||||||
|
font-size: 1.25rem;
|
||||||
|
}
|
||||||
|
&.amounts-fiat {
|
||||||
|
grid-area: amounts-fiat;
|
||||||
|
text-align: right;
|
||||||
|
font-family: monospace;
|
||||||
|
font-size: 0.85rem;
|
||||||
|
color: #888;
|
||||||
|
}
|
||||||
|
&.public-name {
|
||||||
|
grid-area: public-name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
@font-face {
|
|
||||||
font-family: 'Raleway';
|
|
||||||
src: url('/fonts/raleway-light.woff') format('woff2');
|
|
||||||
font-weight: 300;
|
|
||||||
font-style: normal;
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
font-family: "Open Sans", Helvetica, Arial, sans-serif;
|
|
||||||
font-weight: 400;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1, h2, h3 {
|
|
||||||
font-family: Raleway, inherit;
|
|
||||||
font-weight: 300;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
text-transform: uppercase;
|
|
||||||
}
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
form {
|
|
||||||
.field_with_errors {
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.layout-signup {
|
|
||||||
label {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
input[type=text], input[type=email], input[type=password] {
|
|
||||||
font-size: 1.25rem;
|
|
||||||
padding: 0.5rem 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
span.at-sign, span.domain {
|
|
||||||
font-size: 1.25rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.error-msg {
|
|
||||||
color: #bc0101;
|
|
||||||
}
|
|
||||||
|
|
||||||
.actions {
|
|
||||||
margin-top: 2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.accept-terms {
|
|
||||||
margin-top: 2rem;
|
|
||||||
font-size: 0.85rem;
|
|
||||||
line-height: 1.5em;
|
|
||||||
color: #888;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,11 +1,6 @@
|
|||||||
|
@import "variables";
|
||||||
@import "mediaqueries";
|
@import "mediaqueries";
|
||||||
|
|
||||||
$content-width: 800px;
|
|
||||||
$content-max-width: 100%;
|
|
||||||
|
|
||||||
body {
|
|
||||||
}
|
|
||||||
|
|
||||||
#wrapper {
|
#wrapper {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
@@ -14,8 +9,9 @@ body {
|
|||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
padding: 4rem 0;
|
padding: 4rem 0;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
background: #0d4f99;
|
background: linear-gradient(35deg, rgba(255,0,255,0.2) 0, rgba(13,79,153,0.8) 100%),
|
||||||
background: linear-gradient(35deg, #8955a0 0, #0d4f99 100%);
|
url('/img/bg-1.jpg');
|
||||||
|
background-size: cover;
|
||||||
|
|
||||||
@include media-max(small) {
|
@include media-max(small) {
|
||||||
padding: 3rem 0;
|
padding: 3rem 0;
|
||||||
@@ -27,37 +23,27 @@ body {
|
|||||||
|
|
||||||
span.project-name {
|
span.project-name {
|
||||||
display: none;
|
display: none;
|
||||||
// font-size: .5em;
|
|
||||||
// text-transform: none;
|
|
||||||
// vertical-align: super;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
span.beta {
|
span.icon {
|
||||||
font-size: .5em;
|
svg {
|
||||||
font-style: italic;
|
display: inline-block;
|
||||||
text-transform: none;
|
height: 1.8rem;
|
||||||
vertical-align: super;
|
margin-top: -0.1rem;
|
||||||
}
|
vertical-align: top;
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
|
||||||
span.bolt {
|
margin-right: 0.5rem;
|
||||||
color: #ffd000;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
p.current-user {
|
p.current-user {
|
||||||
margin-top: 2rem;
|
|
||||||
color: rgba(255,255,255,0.6);
|
color: rgba(255,255,255,0.6);
|
||||||
|
|
||||||
@include media-max(small) {
|
@include media-max(small) {
|
||||||
font-size: 0.85rem;
|
font-size: 0.85rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
strong {
|
|
||||||
font-weight: 400;
|
|
||||||
color: #fff;
|
|
||||||
// color: #ffd000;
|
|
||||||
// color: #ccff40;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
@@ -77,18 +63,18 @@ body {
|
|||||||
padding: 2rem 0;
|
padding: 2rem 0;
|
||||||
|
|
||||||
&.notice {
|
&.notice {
|
||||||
background: #efffc4;
|
background: $background-color-notice;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.alert {
|
&.alert {
|
||||||
background: #fff4c2;
|
background: $background-color-alert;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
main {
|
main {
|
||||||
width: $content-width;
|
width: $content-width;
|
||||||
max-width: $content-max-width;
|
max-width: $content-max-width;
|
||||||
margin: 4rem auto;
|
margin: 4rem auto 6rem auto;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
|
|
||||||
@include media-max(medium) {
|
@include media-max(medium) {
|
||||||
@@ -128,19 +114,32 @@ main {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
th, td {
|
section {
|
||||||
line-height: 1.5rem;
|
margin-bottom: 3rem;
|
||||||
padding-right: 1rem;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
section {
|
table {
|
||||||
border-bottom: 1px dotted #ccc;
|
width: 100%;
|
||||||
padding-bottom: 4rem;
|
|
||||||
margin-bottom: 4rem;
|
|
||||||
|
|
||||||
@include media-max(small) {
|
th, td {
|
||||||
padding-bottom: 3rem;
|
&.hide-small {
|
||||||
margin-bottom: 3rem;
|
@include media-max(small) {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
th {
|
||||||
|
color: $text-color-discreet;
|
||||||
|
font-weight: normal;
|
||||||
|
text-transform: uppercase;
|
||||||
|
font-size: 0.85rem;
|
||||||
|
padding-bottom: 0.825rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
td {
|
||||||
|
padding-top: 0.5rem;
|
||||||
|
padding-bottom: 0.5rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -156,18 +155,5 @@ main {
|
|||||||
@include media-max(small) {
|
@include media-max(small) {
|
||||||
grid-template-columns: 1fr;
|
grid-template-columns: 1fr;
|
||||||
}
|
}
|
||||||
|
|
||||||
margin-top: 3rem;
|
|
||||||
|
|
||||||
h3 {
|
|
||||||
margin-bottom: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.grid-item {
|
|
||||||
p {
|
|
||||||
color: #888;
|
|
||||||
font-size: 0.85rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
55
app/assets/stylesheets/main_nav.scss
Normal file
55
app/assets/stylesheets/main_nav.scss
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
@import "variables";
|
||||||
|
@import "mediaqueries";
|
||||||
|
|
||||||
|
#main-nav {
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
background-color: #efefef;
|
||||||
|
|
||||||
|
.wrapper {
|
||||||
|
width: $content-width;
|
||||||
|
max-width: $content-max-width;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
@include media-max(large) {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(1fr);
|
||||||
|
grid-template-columns: 1fr 1fr 1fr 1fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
li {
|
||||||
|
@include media-min(large) {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
|
||||||
|
@include media-max(large) {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 1.5rem 2rem;
|
||||||
|
text-decoration: none;
|
||||||
|
color: $text-color-discreet;
|
||||||
|
|
||||||
|
@include media-max(large) {
|
||||||
|
display: block;
|
||||||
|
text-align: center;
|
||||||
|
padding-left: 0;
|
||||||
|
padding-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@include media-max(small) {
|
||||||
|
font-size: 0.85rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
color: $text-color-body;
|
||||||
|
border-bottom: 2px solid #4ea2df;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,4 +3,6 @@ class Admin::BaseController < ApplicationController
|
|||||||
before_action :authenticate_user!
|
before_action :authenticate_user!
|
||||||
before_action :authorize_admin
|
before_action :authorize_admin
|
||||||
|
|
||||||
|
layout "admin"
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
class Admin::DashboardController < Admin::BaseController
|
class Admin::DashboardController < Admin::BaseController
|
||||||
def index
|
def index
|
||||||
|
@current_section = :dashboard
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
79
app/controllers/admin/donations_controller.rb
Normal file
79
app/controllers/admin/donations_controller.rb
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
class Admin::DonationsController < Admin::BaseController
|
||||||
|
before_action :set_donation, only: [:show, :edit, :update, :destroy]
|
||||||
|
before_action :set_current_section, only: [:index, :show, :new, :edit]
|
||||||
|
|
||||||
|
# GET /donations
|
||||||
|
# GET /donations.json
|
||||||
|
def index
|
||||||
|
@donations = Donation.all
|
||||||
|
end
|
||||||
|
|
||||||
|
# GET /donations/1
|
||||||
|
# GET /donations/1.json
|
||||||
|
def show
|
||||||
|
end
|
||||||
|
|
||||||
|
# GET /donations/new
|
||||||
|
def new
|
||||||
|
@donation = Donation.new
|
||||||
|
end
|
||||||
|
|
||||||
|
# GET /donations/1/edit
|
||||||
|
def edit
|
||||||
|
end
|
||||||
|
|
||||||
|
# POST /donations
|
||||||
|
# POST /donations.json
|
||||||
|
def create
|
||||||
|
@donation = Donation.new(donation_params)
|
||||||
|
|
||||||
|
respond_to do |format|
|
||||||
|
if @donation.save
|
||||||
|
format.html { redirect_to admin_donation_url(@donation), notice: 'Donation was successfully created.' }
|
||||||
|
format.json { render :show, status: :created, location: @donation }
|
||||||
|
else
|
||||||
|
format.html { render :new }
|
||||||
|
format.json { render json: @donation.errors, status: :unprocessable_entity }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# PATCH/PUT /donations/1
|
||||||
|
# PATCH/PUT /donations/1.json
|
||||||
|
def update
|
||||||
|
respond_to do |format|
|
||||||
|
if @donation.update(donation_params)
|
||||||
|
format.html { redirect_to admin_donation_url(@donation), notice: 'Donation was successfully updated.' }
|
||||||
|
format.json { render :show, status: :ok, location: @donation }
|
||||||
|
else
|
||||||
|
format.html { render :edit }
|
||||||
|
format.json { render json: @donation.errors, status: :unprocessable_entity }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# DELETE /donations/1
|
||||||
|
# DELETE /donations/1.json
|
||||||
|
def destroy
|
||||||
|
@donation.destroy
|
||||||
|
respond_to do |format|
|
||||||
|
format.html { redirect_to admin_donations_url, notice: 'Donation was successfully destroyed.' }
|
||||||
|
format.json { head :no_content }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
# Use callbacks to share common setup or constraints between actions.
|
||||||
|
def set_donation
|
||||||
|
@donation = Donation.find(params[:id])
|
||||||
|
end
|
||||||
|
|
||||||
|
# Only allow a list of trusted parameters through.
|
||||||
|
def donation_params
|
||||||
|
params.require(:donation).permit(:user_id, :amount_sats, :amount_eur, :amount_usd, :public_name, :paid_at)
|
||||||
|
end
|
||||||
|
|
||||||
|
def set_current_section
|
||||||
|
@current_section = :donations
|
||||||
|
end
|
||||||
|
end
|
||||||
8
app/controllers/admin/invitations_controller.rb
Normal file
8
app/controllers/admin/invitations_controller.rb
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
class Admin::InvitationsController < Admin::BaseController
|
||||||
|
def index
|
||||||
|
@current_section = :invitations
|
||||||
|
@invitations_unused_count = Invitation.unused.count
|
||||||
|
@users_with_referrals_count = Invitation.used.distinct.count(:user_id)
|
||||||
|
@invitations_used = Invitation.used.order('used_at desc')
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -1,4 +1,6 @@
|
|||||||
class Admin::LdapUsersController < Admin::BaseController
|
class Admin::LdapUsersController < Admin::BaseController
|
||||||
|
before_action :set_current_section
|
||||||
|
|
||||||
def index
|
def index
|
||||||
attributes = %w{dn cn uid mail admin}
|
attributes = %w{dn cn uid mail admin}
|
||||||
filter = Net::LDAP::Filter.eq("uid", "*")
|
filter = Net::LDAP::Filter.eq("uid", "*")
|
||||||
@@ -38,4 +40,8 @@ class Admin::LdapUsersController < Admin::BaseController
|
|||||||
def ldap_config
|
def ldap_config
|
||||||
ldap_config ||= YAML.load(ERB.new(File.read("#{Rails.root}/config/ldap.yml")).result)[Rails.env]
|
ldap_config ||= YAML.load(ERB.new(File.read("#{Rails.root}/config/ldap.yml")).result)[Rails.env]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def set_current_section
|
||||||
|
@current_section = :ldap_users
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -2,5 +2,6 @@ class DashboardController < ApplicationController
|
|||||||
before_action :require_user_signed_in
|
before_action :require_user_signed_in
|
||||||
|
|
||||||
def index
|
def index
|
||||||
|
@current_section = :dashboard
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
10
app/controllers/donations_controller.rb
Normal file
10
app/controllers/donations_controller.rb
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
class DonationsController < ApplicationController
|
||||||
|
before_action :require_user_signed_in
|
||||||
|
|
||||||
|
# GET /donations
|
||||||
|
# GET /donations.json
|
||||||
|
def index
|
||||||
|
@donations = current_user.donations.completed
|
||||||
|
@current_section = :contributions
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -8,6 +8,7 @@ class InvitationsController < ApplicationController
|
|||||||
def index
|
def index
|
||||||
@invitations_unused = current_user.invitations.unused
|
@invitations_unused = current_user.invitations.unused
|
||||||
@invitations_used = current_user.invitations.used
|
@invitations_used = current_user.invitations.used
|
||||||
|
@current_section = :invitations
|
||||||
end
|
end
|
||||||
|
|
||||||
# GET /invitations/a-random-invitation-token
|
# GET /invitations/a-random-invitation-token
|
||||||
|
|||||||
7
app/controllers/security_controller.rb
Normal file
7
app/controllers/security_controller.rb
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
class SecurityController < ApplicationController
|
||||||
|
before_action :require_user_signed_in
|
||||||
|
|
||||||
|
def index
|
||||||
|
@current_section = :security
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -94,16 +94,15 @@ class SignupController < ApplicationController
|
|||||||
end
|
end
|
||||||
|
|
||||||
def complete_signup
|
def complete_signup
|
||||||
@user.save!
|
|
||||||
session[:new_user] = nil
|
session[:new_user] = nil
|
||||||
session[:validation_error] = nil
|
session[:validation_error] = nil
|
||||||
|
|
||||||
CreateAccount.call(
|
CreateAccount.call(
|
||||||
username: @user.cn,
|
username: @user.cn,
|
||||||
|
domain: "kosmos.org",
|
||||||
email: @user.email,
|
email: @user.email,
|
||||||
password: @user.password
|
password: @user.password,
|
||||||
|
invitation: @invitation
|
||||||
)
|
)
|
||||||
|
|
||||||
@invitation.update! invited_user_id: @user.id, used_at: DateTime.now
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,2 +1,5 @@
|
|||||||
module ApplicationHelper
|
module ApplicationHelper
|
||||||
|
def sats_to_btc(sats)
|
||||||
|
sats.to_f / 100000000
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
2
app/helpers/donations_helper.rb
Normal file
2
app/helpers/donations_helper.rb
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
module DonationsHelper
|
||||||
|
end
|
||||||
@@ -7,7 +7,7 @@ require("@rails/ujs").start()
|
|||||||
require("turbolinks").start()
|
require("turbolinks").start()
|
||||||
require("channels")
|
require("channels")
|
||||||
|
|
||||||
|
import "stylesheets/application"
|
||||||
// Uncomment to copy all static images under ../images to the output folder and reference
|
// Uncomment to copy all static images under ../images to the output folder and reference
|
||||||
// them with the image_pack_tag helper in views (e.g <%= image_pack_tag 'rails.png' %>)
|
// them with the image_pack_tag helper in views (e.g <%= image_pack_tag 'rails.png' %>)
|
||||||
// or the `imagePath` JavaScript helper below.
|
// or the `imagePath` JavaScript helper below.
|
||||||
|
|||||||
8
app/javascript/stylesheets/application.scss
Normal file
8
app/javascript/stylesheets/application.scss
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
@import "tailwindcss/base";
|
||||||
|
@import "tailwindcss/components";
|
||||||
|
@import "tailwindcss/utilities";
|
||||||
|
|
||||||
|
@import "base";
|
||||||
|
@import "buttons";
|
||||||
|
@import "forms";
|
||||||
|
@import "links";
|
||||||
20
app/javascript/stylesheets/base.scss
Normal file
20
app/javascript/stylesheets/base.scss
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
@layer base {
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Raleway';
|
||||||
|
src: url('/fonts/raleway-light.woff') format('woff2');
|
||||||
|
font-weight: 300;
|
||||||
|
font-style: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1, h2, h3 {
|
||||||
|
@apply font-heading font-light;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
@apply uppercase;
|
||||||
|
}
|
||||||
|
}
|
||||||
31
app/javascript/stylesheets/buttons.scss
Normal file
31
app/javascript/stylesheets/buttons.scss
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
@layer components {
|
||||||
|
.btn {
|
||||||
|
@apply font-semibold rounded-md leading-none cursor-pointer
|
||||||
|
transition-colors duration-75 focus:outline-none focus:ring-4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-md {
|
||||||
|
@apply btn;
|
||||||
|
@apply py-2.5 px-5 shadow-md;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-sm {
|
||||||
|
@apply btn;
|
||||||
|
@apply py-1 px-2 text-sm shadow-sm;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-gray {
|
||||||
|
@apply bg-gray-100 hover:bg-gray-200
|
||||||
|
focus:ring-gray-300 focus:ring-opacity-75;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-blue {
|
||||||
|
@apply bg-blue-500 hover:bg-blue-600 text-white
|
||||||
|
focus:ring-blue-400 focus:ring-opacity-75;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-red {
|
||||||
|
@apply bg-red-600 hover:bg-red-700 text-white
|
||||||
|
focus:ring-red-500 focus:ring-opacity-75;
|
||||||
|
}
|
||||||
|
}
|
||||||
17
app/javascript/stylesheets/forms.scss
Normal file
17
app/javascript/stylesheets/forms.scss
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
@layer components {
|
||||||
|
form {
|
||||||
|
input[type=text], input[type=email], input[type=password],
|
||||||
|
input[type=number], select {
|
||||||
|
@apply mt-1 rounded-md bg-gray-100 focus:bg-white
|
||||||
|
border-transparent focus:border-gray-500 focus:ring-0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.field_with_errors {
|
||||||
|
@apply inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.error-msg {
|
||||||
|
@apply text-red-700;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
14
app/javascript/stylesheets/links.scss
Normal file
14
app/javascript/stylesheets/links.scss
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
@layer components {
|
||||||
|
.ks-text-link {
|
||||||
|
@apply text-blue-600;
|
||||||
|
&:hover { @apply underline; }
|
||||||
|
&:visited { @apply text-indigo-600; }
|
||||||
|
&:active { @apply text-red-600; }
|
||||||
|
}
|
||||||
|
|
||||||
|
.devise-links {
|
||||||
|
a {
|
||||||
|
@apply ks-text-link;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
23
app/javascript/stylesheets/tailwind.config.js
Normal file
23
app/javascript/stylesheets/tailwind.config.js
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
const defaultTheme = require('tailwindcss/defaultTheme')
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
purge: [
|
||||||
|
"./app/**/*.html.erb",
|
||||||
|
"./app/helpers/**/*.rb",
|
||||||
|
"./app/javascript/**/*.js"
|
||||||
|
],
|
||||||
|
darkMode: false, // or 'media' or 'class'
|
||||||
|
theme: {
|
||||||
|
extend: {
|
||||||
|
fontFamily: {
|
||||||
|
heading: ['Raleway']
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
variants: {
|
||||||
|
extend: {},
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
require('@tailwindcss/forms')
|
||||||
|
],
|
||||||
|
}
|
||||||
32
app/jobs/create_ldap_user_job.rb
Normal file
32
app/jobs/create_ldap_user_job.rb
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
class CreateLdapUserJob < ApplicationJob
|
||||||
|
queue_as :default
|
||||||
|
|
||||||
|
def perform(username, domain, email, hashed_pw)
|
||||||
|
dn = "cn=#{username},ou=#{domain},cn=users,dc=kosmos,dc=org"
|
||||||
|
attr = {
|
||||||
|
objectclass: ["top", "account", "person", "extensibleObject"],
|
||||||
|
cn: username,
|
||||||
|
sn: username,
|
||||||
|
uid: username,
|
||||||
|
mail: email,
|
||||||
|
userPassword: hashed_pw
|
||||||
|
}
|
||||||
|
|
||||||
|
ldap_client.add(dn: dn, attributes: attr)
|
||||||
|
end
|
||||||
|
|
||||||
|
def ldap_client
|
||||||
|
ldap_client ||= Net::LDAP.new host: ldap_config['host'],
|
||||||
|
port: ldap_config['port'],
|
||||||
|
encryption: ldap_config['ssl'],
|
||||||
|
auth: {
|
||||||
|
method: :simple,
|
||||||
|
username: ldap_config['admin_user'],
|
||||||
|
password: ldap_config['admin_password']
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
def ldap_config
|
||||||
|
ldap_config ||= YAML.load(ERB.new(File.read("#{Rails.root}/config/ldap.yml")).result)[Rails.env]
|
||||||
|
end
|
||||||
|
end
|
||||||
18
app/jobs/exchange_xmpp_contacts_job.rb
Normal file
18
app/jobs/exchange_xmpp_contacts_job.rb
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
class ExchangeXmppContactsJob < ApplicationJob
|
||||||
|
queue_as :default
|
||||||
|
|
||||||
|
def perform(inviter, username, domain)
|
||||||
|
ejabberd = EjabberdApiClient.new
|
||||||
|
|
||||||
|
ejabberd.add_rosteritem({
|
||||||
|
"localuser": username, "localhost": domain,
|
||||||
|
"user": inviter.cn, "host": inviter.ou,
|
||||||
|
"nick": inviter.cn, "group": "Friends", "subs": "both"
|
||||||
|
})
|
||||||
|
ejabberd.add_rosteritem({
|
||||||
|
"localuser": inviter.cn, "localhost": inviter.ou,
|
||||||
|
"user": username, "host": domain,
|
||||||
|
"nick": username, "group": "Friends", "subs": "both"
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
||||||
13
app/models/donation.rb
Normal file
13
app/models/donation.rb
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
class Donation < ApplicationRecord
|
||||||
|
# Relations
|
||||||
|
belongs_to :user
|
||||||
|
|
||||||
|
# Validations
|
||||||
|
validates_presence_of :amount_sats
|
||||||
|
|
||||||
|
# Hooks
|
||||||
|
# TODO before_create :store_fiat_value
|
||||||
|
|
||||||
|
#Scopes
|
||||||
|
scope :completed, -> { where.not(paid_at: nil) }
|
||||||
|
end
|
||||||
@@ -3,6 +3,7 @@ class User < ApplicationRecord
|
|||||||
|
|
||||||
# Relations
|
# Relations
|
||||||
has_many :invitations, dependent: :destroy
|
has_many :invitations, dependent: :destroy
|
||||||
|
has_many :donations, dependent: :nullify
|
||||||
|
|
||||||
validates_uniqueness_of :cn
|
validates_uniqueness_of :cn
|
||||||
validates_length_of :cn, :minimum => 3
|
validates_length_of :cn, :minimum => 3
|
||||||
|
|||||||
@@ -1,42 +1,47 @@
|
|||||||
class CreateAccount < ApplicationService
|
class CreateAccount < ApplicationService
|
||||||
def initialize(args)
|
def initialize(args)
|
||||||
@username = args[:username]
|
@username = args[:username]
|
||||||
@email = args[:email]
|
@domain = args[:ou] || "kosmos.org"
|
||||||
@password = args[:password]
|
@email = args[:email]
|
||||||
|
@password = args[:password]
|
||||||
|
@invitation = args[:invitation]
|
||||||
end
|
end
|
||||||
|
|
||||||
def call
|
def call
|
||||||
|
user = create_user_in_database
|
||||||
add_ldap_document
|
add_ldap_document
|
||||||
|
|
||||||
|
if @invitation.present?
|
||||||
|
update_invitation(user.id)
|
||||||
|
exchange_xmpp_contacts
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def add_ldap_document
|
def create_user_in_database
|
||||||
dn = "cn=#{@username},ou=kosmos.org,cn=users,dc=kosmos,dc=org"
|
User.create!(
|
||||||
attr = {
|
|
||||||
objectclass: ["top", "account", "person", "extensibleObject"],
|
|
||||||
cn: @username,
|
cn: @username,
|
||||||
sn: @username,
|
ou: @domain,
|
||||||
uid: @username,
|
email: @email,
|
||||||
mail: @email,
|
password: @password,
|
||||||
userPassword: Devise.ldap_auth_password_builder.call(@password)
|
password_confirmation: @password
|
||||||
}
|
)
|
||||||
|
|
||||||
ldap_client.add(dn: dn, attributes: attr)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def ldap_client
|
def update_invitation(user_id)
|
||||||
ldap_client ||= Net::LDAP.new host: ldap_config['host'],
|
@invitation.update! invited_user_id: user_id, used_at: DateTime.now
|
||||||
port: ldap_config['port'],
|
|
||||||
encryption: ldap_config['ssl'],
|
|
||||||
auth: {
|
|
||||||
method: :simple,
|
|
||||||
username: ldap_config['admin_user'],
|
|
||||||
password: ldap_config['admin_password']
|
|
||||||
}
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def ldap_config
|
# TODO move to confirmation
|
||||||
ldap_config ||= YAML.load(ERB.new(File.read("#{Rails.root}/config/ldap.yml")).result)[Rails.env]
|
def add_ldap_document
|
||||||
|
hashed_pw = Devise.ldap_auth_password_builder.call(@password)
|
||||||
|
CreateLdapUserJob.perform_later(@username, @domain, @email, hashed_pw)
|
||||||
|
end
|
||||||
|
|
||||||
|
def exchange_xmpp_contacts
|
||||||
|
#TODO enable in development when we have easy setup of ejabberd etc.
|
||||||
|
return if Rails.env.development?
|
||||||
|
ExchangeXmppContactsJob.perform_later(@invitation.user, @username, @domain)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
20
app/services/ejabberd_api_client.rb
Normal file
20
app/services/ejabberd_api_client.rb
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
class EjabberdApiClient
|
||||||
|
def initialize
|
||||||
|
@base_url = ENV["EJABBERD_API_URL"]
|
||||||
|
end
|
||||||
|
|
||||||
|
def post(endpoint, payload)
|
||||||
|
res = Faraday.post("#{@base_url}/#{endpoint}", payload.to_json,
|
||||||
|
"Content-Type" => "application/json")
|
||||||
|
|
||||||
|
if res.status != 200
|
||||||
|
Rails.logger.error "[ejabberd] API request failed:"
|
||||||
|
Rails.logger.error res.body
|
||||||
|
#TODO add some kind of exception tracking/notifications
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def add_rosteritem(payload)
|
||||||
|
post "add_rosteritem", payload
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -1,7 +1,3 @@
|
|||||||
<h2>Admin Panel</h2>
|
<p class="text-center">
|
||||||
<p>
|
With great power comes great responsibility.
|
||||||
Ohai there, admin human.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<%= link_to 'LDAP users', admin_ldap_users_path %>
|
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
2
app/views/admin/donations/_donation.json.jbuilder
Normal file
2
app/views/admin/donations/_donation.json.jbuilder
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
json.extract! donation, :id, :user_id, :amount_sats, :amount_eur, :amount_usd, :public_name, :created_at, :updated_at
|
||||||
|
json.url donation_url(donation, format: :json)
|
||||||
58
app/views/admin/donations/_form.html.erb
Normal file
58
app/views/admin/donations/_form.html.erb
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
<%= form_with(url: url, model: donation, local: true) do |form| %>
|
||||||
|
<% if donation.errors.any? %>
|
||||||
|
<div id="error_explanation">
|
||||||
|
<h3><%= pluralize(donation.errors.count, "error") %> prohibited this donation from being saved:</h3>
|
||||||
|
<ul>
|
||||||
|
<% donation.errors.full_messages.each do |message| %>
|
||||||
|
<li><%= message %></li>
|
||||||
|
<% end %>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<div class="field">
|
||||||
|
<p>
|
||||||
|
<%= form.label :user_id %>
|
||||||
|
<%= form.collection_select :user_id, User.where(ou: "kosmos.org").order(:cn), :id, :cn %>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="field">
|
||||||
|
<p>
|
||||||
|
<%= form.label :amount_sats, "Amount BTC (sats)" %>
|
||||||
|
<%= form.number_field :amount_sats %>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="field">
|
||||||
|
<p>
|
||||||
|
<%= form.label :amount_eur, "Amount EUR (cents)" %>
|
||||||
|
<%= form.number_field :amount_eur %>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="field">
|
||||||
|
<p>
|
||||||
|
<%= form.label :amount_usd, "Amount USD (cents)"%>
|
||||||
|
<%= form.number_field :amount_usd %>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="field">
|
||||||
|
<p>
|
||||||
|
<%= form.label :public_name %>
|
||||||
|
<%= form.text_field :public_name %>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="field">
|
||||||
|
<p>
|
||||||
|
<%= form.label :paid_at %>
|
||||||
|
<%= form.text_field :paid_at %>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p class="mt-8">
|
||||||
|
<%= form.submit class: 'btn-md btn-blue' %>
|
||||||
|
</p>
|
||||||
|
<% end %>
|
||||||
8
app/views/admin/donations/edit.html.erb
Normal file
8
app/views/admin/donations/edit.html.erb
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<h2>Editing Donation</h2>
|
||||||
|
|
||||||
|
<%= render 'form', donation: @donation, url: admin_donation_path(@donation) %>
|
||||||
|
|
||||||
|
<p class="mt-8">
|
||||||
|
<%= link_to 'Show', admin_donation_path(@donation), class: 'ks-text-link' %> |
|
||||||
|
<%= link_to 'Back', admin_donations_path, class: 'ks-text-link' %>
|
||||||
|
<p>
|
||||||
41
app/views/admin/donations/index.html.erb
Normal file
41
app/views/admin/donations/index.html.erb
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
<h2>Donations</h2>
|
||||||
|
|
||||||
|
<% if @donations.any? %>
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>User</th>
|
||||||
|
<th>Amount BTC</th>
|
||||||
|
<th>in EUR</th>
|
||||||
|
<th>in USD</th>
|
||||||
|
<th>Public name</th>
|
||||||
|
<th>Date</th>
|
||||||
|
<th colspan="3"></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
|
||||||
|
<tbody>
|
||||||
|
<% @donations.each do |donation| %>
|
||||||
|
<tr>
|
||||||
|
<td><%= donation.user.cn %></td>
|
||||||
|
<td><%= sats_to_btc donation.amount_sats %> BTC</td>
|
||||||
|
<td><%= number_to_currency donation.amount_eur / 100, unit: "" %></td>
|
||||||
|
<td><%= number_to_currency donation.amount_usd / 100, unit: "" %></td>
|
||||||
|
<td><%= donation.public_name %></td>
|
||||||
|
<td><%= donation.paid_at ? donation.paid_at.strftime("%Y-%m-%d") : "" %></td>
|
||||||
|
<td><%= link_to 'Show', admin_donation_path(donation), class: 'btn btn-sm btn-gray' %></td>
|
||||||
|
<td><%= link_to 'Edit', edit_admin_donation_path(donation), class: 'btn btn-sm btn-gray' %></td>
|
||||||
|
<td><%= link_to 'Destroy', admin_donation_path(donation), class: 'btn btn-sm btn-red', method: :delete, data: { confirm: 'Are you sure?' } %></td>
|
||||||
|
</tr>
|
||||||
|
<% end %>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<% else %>
|
||||||
|
<p>
|
||||||
|
No donations yet.
|
||||||
|
</p>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<p class="mt-12">
|
||||||
|
<%= link_to 'Record an out-of-system donation', new_admin_donation_path, class: 'btn-md btn-gray' %>
|
||||||
|
</p>
|
||||||
1
app/views/admin/donations/index.json.jbuilder
Normal file
1
app/views/admin/donations/index.json.jbuilder
Normal file
@@ -0,0 +1 @@
|
|||||||
|
json.array! @donations, partial: "donations/donation", as: :donation
|
||||||
7
app/views/admin/donations/new.html.erb
Normal file
7
app/views/admin/donations/new.html.erb
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<h2>New Donation</h2>
|
||||||
|
|
||||||
|
<%= render 'form', donation: @donation, url: admin_donations_path %>
|
||||||
|
|
||||||
|
<p class="mt-8">
|
||||||
|
<%= link_to 'Back', admin_donations_path, class: 'ks-text-link' %>
|
||||||
|
</p>
|
||||||
36
app/views/admin/donations/show.html.erb
Normal file
36
app/views/admin/donations/show.html.erb
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
<p id="notice"><%= notice %></p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<strong>User:</strong>
|
||||||
|
<%= @donation.user_id %>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<strong>Amount sats:</strong>
|
||||||
|
<%= @donation.amount_sats %>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<strong>Amount eur:</strong>
|
||||||
|
<%= @donation.amount_eur %>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<strong>Amount usd:</strong>
|
||||||
|
<%= @donation.amount_usd %>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<strong>Public name:</strong>
|
||||||
|
<%= @donation.public_name %>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<strong>Date:</strong>
|
||||||
|
<%= @donation.paid_at %>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p class="mt-8">
|
||||||
|
<%= link_to 'Edit', edit_admin_donation_path(@donation), class: 'ks-text-link' %> |
|
||||||
|
<%= link_to 'Back', admin_donations_path, class: 'ks-text-link' %>
|
||||||
|
</p>
|
||||||
1
app/views/admin/donations/show.json.jbuilder
Normal file
1
app/views/admin/donations/show.json.jbuilder
Normal file
@@ -0,0 +1 @@
|
|||||||
|
json.partial! "donations/donation", donation: @donation
|
||||||
32
app/views/admin/invitations/index.html.erb
Normal file
32
app/views/admin/invitations/index.html.erb
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
<section>
|
||||||
|
<h2>Invitations</h2>
|
||||||
|
<p>
|
||||||
|
There are currently <strong><%= @invitations_unused_count %>
|
||||||
|
unused invitations</strong> available to existing users.
|
||||||
|
<strong><%= @users_with_referrals_count %> users</strong> have successfully
|
||||||
|
invited new users.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
<% if @invitations_used.any? %>
|
||||||
|
<section>
|
||||||
|
<h3>Accepted (<%= @invitations_used.length %>)</h3>
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Token</th>
|
||||||
|
<th>Accepted</th>
|
||||||
|
<th>Invited user</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<% @invitations_used.each do |invitation| %>
|
||||||
|
<tr>
|
||||||
|
<td class="overflow-ellipsis"><%= invitation.token %></td>
|
||||||
|
<td><%= invitation.used_at.strftime("%Y-%m-%d") %></td>
|
||||||
|
<td><%= User.find(invitation.invited_user_id).address %></td>
|
||||||
|
</tr>
|
||||||
|
<% end %>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</section>
|
||||||
|
<% end %>
|
||||||
@@ -4,45 +4,46 @@
|
|||||||
Your Kosmos account and password currently give you access to these
|
Your Kosmos account and password currently give you access to these
|
||||||
services:
|
services:
|
||||||
</p>
|
</p>
|
||||||
<div class="grid services">
|
<div class="grid services mt-12">
|
||||||
<div class="grid-item chat">
|
<div>
|
||||||
<h3><%= link_to "Chat", "https://wiki.kosmos.org/Services:XMPP" %></h3>
|
<h3 class="mb-3.5">
|
||||||
<p>
|
<%= link_to "Chat", "https://wiki.kosmos.org/Services:Chat", class: "ks-text-link" %>
|
||||||
|
</h3>
|
||||||
|
<p class="text-gray-500">
|
||||||
Chat rooms and instant messaging (XMPP/Jabber)
|
Chat rooms and instant messaging (XMPP/Jabber)
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="grid-item wiki">
|
<div>
|
||||||
<h3><%= link_to "Wiki", "https://wiki.kosmos.org" %></h3>
|
<h3 class="mb-3.5">
|
||||||
<p>
|
<%= link_to "Wiki", "https://wiki.kosmos.org", class: "ks-text-link" %>
|
||||||
|
</h3>
|
||||||
|
<p class="text-gray-500">
|
||||||
Kosmos documentation and knowledge base
|
Kosmos documentation and knowledge base
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="grid-item discourse">
|
<div>
|
||||||
<h3><%= link_to "Discourse", "https://community.kosmos.org" %></h3>
|
<h3 class="mb-3.5">
|
||||||
<p>
|
<%= link_to "Discourse", "https://community.kosmos.org", class: "ks-text-link" %>
|
||||||
|
</h3>
|
||||||
|
<p class="text-gray-500">
|
||||||
Kosmos community forums and user support/help site
|
Kosmos community forums and user support/help site
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="grid-item gitea">
|
<div>
|
||||||
<h3><%= link_to "Gitea", "https://gitea.kosmos.org" %></h3>
|
<h3 class="mb-3.5">
|
||||||
<p>
|
<%= link_to "Gitea", "https://gitea.kosmos.org", class: "ks-text-link" %>
|
||||||
|
</h3>
|
||||||
|
<p class="text-gray-500">
|
||||||
Code hosting and collaboration for software projects
|
Code hosting and collaboration for software projects
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="grid-item gitea">
|
<div>
|
||||||
<h3><%= link_to "Drone CI", "https://drone.kosmos.org" %></h3>
|
<h3 class="mb-3.5">
|
||||||
<p>
|
<%= link_to "Drone CI", "https://drone.kosmos.org", class: "ks-text-link" %>
|
||||||
Continuous integration for software projects, tied to our Gitea
|
</h3>
|
||||||
|
<p class="text-gray-500">
|
||||||
|
Continuous integration for software projects on Gitea
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section>
|
|
||||||
<h3>Password change</h3>
|
|
||||||
<p>
|
|
||||||
<%= form_with(url: settings_reset_password_path, method: :post) do %>
|
|
||||||
<%= submit_tag("Send me a password reset link") %>
|
|
||||||
<% end %>
|
|
||||||
</p>
|
|
||||||
</section>
|
|
||||||
|
|||||||
@@ -2,19 +2,13 @@
|
|||||||
|
|
||||||
<%= form_for(resource, as: resource_name, url: confirmation_path(resource_name), html: { method: :post }) do |f| %>
|
<%= form_for(resource, as: resource_name, url: confirmation_path(resource_name), html: { method: :post }) do |f| %>
|
||||||
<%= render "devise/shared/error_messages", resource: resource %>
|
<%= render "devise/shared/error_messages", resource: resource %>
|
||||||
|
<p>
|
||||||
<div class="field">
|
<%= f.label :email, 'Email address', class: 'block mb-1' %>
|
||||||
<p>
|
<%= f.email_field :email, required: true, autofocus: true, autocomplete: "email", value: (resource.pending_reconfirmation? ? resource.unconfirmed_email : resource.email) %>
|
||||||
<%= f.label :email, 'Email address' %><br />
|
</p>
|
||||||
<%= f.email_field :email, required: true, autofocus: true, autocomplete: "email", value: (resource.pending_reconfirmation? ? resource.unconfirmed_email : resource.email) %>
|
<p class="mt-8">
|
||||||
</p>
|
<%= f.submit "Resend confirmation instructions", class: 'btn-md btn-blue' %>
|
||||||
</div>
|
</p>
|
||||||
|
|
||||||
<div class="actions">
|
|
||||||
<p>
|
|
||||||
<%= f.submit "Resend confirmation instructions" %>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<%= render "devise/shared/links" %>
|
<%= render "devise/shared/links" %>
|
||||||
|
|||||||
@@ -4,22 +4,24 @@
|
|||||||
<%= render "devise/shared/error_messages", resource: resource %>
|
<%= render "devise/shared/error_messages", resource: resource %>
|
||||||
<%= f.hidden_field :reset_password_token %>
|
<%= f.hidden_field :reset_password_token %>
|
||||||
|
|
||||||
<div class="field">
|
<p class="mb-1">
|
||||||
<%= f.label :password, "New password" %><br />
|
<%= f.label :password, "New password" %>
|
||||||
<% if @minimum_password_length %>
|
</p>
|
||||||
<em>(<%= @minimum_password_length %> characters minimum)</em><br />
|
<p>
|
||||||
<% end %>
|
|
||||||
<%= f.password_field :password, autofocus: true, autocomplete: "new-password" %>
|
<%= f.password_field :password, autofocus: true, autocomplete: "new-password" %>
|
||||||
</div>
|
<% if @minimum_password_length %>
|
||||||
|
<br><em class="text-sm text-gray-500">(<%= @minimum_password_length %> characters minimum)</em>
|
||||||
<div class="field">
|
<% end %>
|
||||||
<%= f.label :password_confirmation, "Confirm new password" %><br />
|
</p>
|
||||||
|
<p class="mb-1">
|
||||||
|
<%= f.label :password_confirmation, "Confirm new password" %>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
<%= f.password_field :password_confirmation, autocomplete: "new-password" %>
|
<%= f.password_field :password_confirmation, autocomplete: "new-password" %>
|
||||||
</div>
|
</p>
|
||||||
|
<p class="mt-8">
|
||||||
<div class="actions">
|
<%= f.submit "Change my password", class: 'btn-md btn-blue' %>
|
||||||
<%= f.submit "Change my password" %>
|
</p>
|
||||||
</div>
|
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<%= render "devise/shared/links" %>
|
<%= render "devise/shared/links" %>
|
||||||
|
|||||||
@@ -2,26 +2,17 @@
|
|||||||
|
|
||||||
<%= form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :post }) do |f| %>
|
<%= form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :post }) do |f| %>
|
||||||
<%= render "devise/shared/error_messages", resource: resource %>
|
<%= render "devise/shared/error_messages", resource: resource %>
|
||||||
|
<p>
|
||||||
<div class="field">
|
<%= f.label :cn, 'User', class: 'block' %>
|
||||||
<p>
|
<%= f.text_field :cn, autofocus: true, autocomplete: "username", required: true %> @ kosmos.org
|
||||||
<%= f.label :cn, 'User' %><br />
|
</p>
|
||||||
<%= f.text_field :cn, autofocus: true, autocomplete: "username", required: true %> @ kosmos.org
|
<p>
|
||||||
</p>
|
<%= f.label :email, 'Email address', class: 'block' %>
|
||||||
</div>
|
<%= f.email_field :email, autocomplete: "email", required: true %>
|
||||||
|
</p>
|
||||||
<div class="field">
|
<p class="mt-8">
|
||||||
<p>
|
<%= f.submit "Send me reset password instructions", class: 'btn-md btn-blue' %>
|
||||||
<%= f.label :email, 'Email address' %><br />
|
</p>
|
||||||
<%= f.email_field :email, autocomplete: "email", required: true %>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="actions">
|
|
||||||
<p>
|
|
||||||
<%= f.submit "Send me reset password instructions" %>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<%= render "devise/shared/links" %>
|
<%= render "devise/shared/links" %>
|
||||||
|
|||||||
@@ -31,9 +31,9 @@
|
|||||||
<%= f.password_field :current_password, autocomplete: "current-password" %>
|
<%= f.password_field :current_password, autocomplete: "current-password" %>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="actions">
|
<p class="mt-8">
|
||||||
<%= f.submit "Update" %>
|
<%= f.submit "Update", class: 'btn-md btn-blue' %>
|
||||||
</div>
|
</p>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<h3>Cancel my account</h3>
|
<h3>Cancel my account</h3>
|
||||||
|
|||||||
@@ -2,24 +2,17 @@
|
|||||||
|
|
||||||
<%= form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| %>
|
<%= form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| %>
|
||||||
<%= render "devise/shared/error_messages", resource: resource %>
|
<%= render "devise/shared/error_messages", resource: resource %>
|
||||||
|
<p>
|
||||||
<div class="field">
|
<%= f.label :cn, 'User', class: 'block' %>
|
||||||
<p>
|
<%= f.text_field :cn, autofocus: true, autocomplete: "username" %> @ kosmos.org
|
||||||
<%= f.label :cn, 'User' %><br />
|
</p>
|
||||||
<%= f.text_field :cn, autofocus: true, autocomplete: "username" %> @ kosmos.org
|
<p>
|
||||||
</p>
|
<%= f.label :password, class: 'block' %>
|
||||||
</div>
|
<%= f.password_field :password, autocomplete: "current-password" %>
|
||||||
<div class="field">
|
</p>
|
||||||
<p>
|
<p class="mt-8">
|
||||||
<%= f.label :password %><br />
|
<%= f.submit "Log in", class: 'btn-md btn-blue' %>
|
||||||
<%= f.password_field :password, autocomplete: "current-password" %>
|
</p>
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div class="actions">
|
|
||||||
<p>
|
|
||||||
<%= f.submit "Log in" %>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<%= render "devise/shared/links" %>
|
<%= render "devise/shared/links" %>
|
||||||
|
|||||||
@@ -1,24 +1,24 @@
|
|||||||
<div class="devise-links">
|
<div class="devise-links mt-8 text-sm">
|
||||||
<%- if controller_name != 'sessions' %>
|
<%- if controller_name != 'sessions' %>
|
||||||
<p>
|
<p class="mb-1.5">
|
||||||
<%= link_to "Log in", new_session_path(resource_name) %><br />
|
<%= link_to "Log in", new_session_path(resource_name) %><br />
|
||||||
</p>
|
</p>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<%- if devise_mapping.recoverable? && controller_name != 'passwords' && controller_name != 'registrations' %>
|
<%- if devise_mapping.recoverable? && controller_name != 'passwords' && controller_name != 'registrations' %>
|
||||||
<p>
|
<p class="mb-1.5">
|
||||||
<%= link_to "Forgot your password?", new_password_path(resource_name) %><br />
|
<%= link_to "Forgot your password?", new_password_path(resource_name) %><br />
|
||||||
</p>
|
</p>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<%- if devise_mapping.confirmable? && controller_name != 'confirmations' %>
|
<%- if devise_mapping.confirmable? && controller_name != 'confirmations' %>
|
||||||
<p>
|
<p class="mb-1.5">
|
||||||
<%= link_to "Didn't receive confirmation instructions?", new_confirmation_path(resource_name) %><br />
|
<%= link_to "Didn't receive confirmation instructions?", new_confirmation_path(resource_name) %><br />
|
||||||
</p>
|
</p>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<%- if devise_mapping.lockable? && resource_class.unlock_strategy_enabled?(:email) && controller_name != 'unlocks' %>
|
<%- if devise_mapping.lockable? && resource_class.unlock_strategy_enabled?(:email) && controller_name != 'unlocks' %>
|
||||||
<p>
|
<p class="mb-1.5">
|
||||||
<%= link_to "Didn't receive unlock instructions?", new_unlock_path(resource_name) %><br />
|
<%= link_to "Didn't receive unlock instructions?", new_unlock_path(resource_name) %><br />
|
||||||
</p>
|
</p>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|||||||
@@ -2,15 +2,13 @@
|
|||||||
|
|
||||||
<%= form_for(resource, as: resource_name, url: unlock_path(resource_name), html: { method: :post }) do |f| %>
|
<%= form_for(resource, as: resource_name, url: unlock_path(resource_name), html: { method: :post }) do |f| %>
|
||||||
<%= render "devise/shared/error_messages", resource: resource %>
|
<%= render "devise/shared/error_messages", resource: resource %>
|
||||||
|
<p>
|
||||||
<div class="field">
|
|
||||||
<%= f.label :email %><br />
|
<%= f.label :email %><br />
|
||||||
<%= f.email_field :email, autofocus: true, autocomplete: "email" %>
|
<%= f.email_field :email, autofocus: true, autocomplete: "email" %>
|
||||||
</div>
|
</p>
|
||||||
|
<p class="mt-8">
|
||||||
<div class="actions">
|
<%= f.submit "Resend unlock instructions", class: 'btn-md btn-blue' %>
|
||||||
<%= f.submit "Resend unlock instructions" %>
|
</p>
|
||||||
</div>
|
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<%= render "devise/shared/links" %>
|
<%= render "devise/shared/links" %>
|
||||||
|
|||||||
38
app/views/donations/index.html.erb
Normal file
38
app/views/donations/index.html.erb
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
<section>
|
||||||
|
<h2>Donations</h2>
|
||||||
|
<p>
|
||||||
|
Your financial contributions to the development and
|
||||||
|
upkeep of Kosmos software and services.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<% if @donations.any? %>
|
||||||
|
<ul class="donations">
|
||||||
|
<% @donations.each do |donation| %>
|
||||||
|
<li>
|
||||||
|
<h3>
|
||||||
|
<%= donation.paid_at.strftime("%B %d, %Y") %>
|
||||||
|
</h3>
|
||||||
|
<p class="amount-btc">
|
||||||
|
<%= sats_to_btc donation.amount_sats %> BTC
|
||||||
|
</p>
|
||||||
|
<p class="amounts-fiat">
|
||||||
|
(~ <%= number_to_currency donation.amount_eur / 100, unit: "" %> EUR)
|
||||||
|
</p>
|
||||||
|
<p class="public-name">
|
||||||
|
<% if donation.public_name.present? %>
|
||||||
|
Public name: <%= donation.public_name %>
|
||||||
|
<% else %>
|
||||||
|
Anonymous
|
||||||
|
<% end %>
|
||||||
|
</p>
|
||||||
|
</li>
|
||||||
|
<% end %>
|
||||||
|
</ul>
|
||||||
|
<% else %>
|
||||||
|
<p>
|
||||||
|
No donations to show.
|
||||||
|
</p>
|
||||||
|
<% end %>
|
||||||
|
</section>
|
||||||
1
app/views/donations/index.json.jbuilder
Normal file
1
app/views/donations/index.json.jbuilder
Normal file
@@ -0,0 +1 @@
|
|||||||
|
json.array! @donations, partial: "donations/donation", as: :donation
|
||||||
@@ -24,23 +24,25 @@
|
|||||||
</section>
|
</section>
|
||||||
|
|
||||||
<% if @invitations_used.any? %>
|
<% if @invitations_used.any? %>
|
||||||
<h3>Accepted Invitations</h3>
|
<section>
|
||||||
<table>
|
<h3>Accepted Invitations</h3>
|
||||||
<thead>
|
<table>
|
||||||
<tr>
|
<thead>
|
||||||
<th>URL</th>
|
|
||||||
<th>Used at</th>
|
|
||||||
<th>Invited user</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<% @invitations_used.each do |invitation| %>
|
|
||||||
<tr>
|
<tr>
|
||||||
<td><%= invitation_url(invitation.token) %></td>
|
<th class="hide-small">ID</th>
|
||||||
<td><%= invitation.used_at %></td>
|
<th>Accepted</th>
|
||||||
<td><%= User.find(invitation.invited_user_id).address %></td>
|
<th>Invited user</th>
|
||||||
</tr>
|
</tr>
|
||||||
<% end %>
|
</thead>
|
||||||
</tbody>
|
<tbody>
|
||||||
</table>
|
<% @invitations_used.each do |invitation| %>
|
||||||
|
<tr>
|
||||||
|
<td class="hide-small"><%= invitation.token %></td>
|
||||||
|
<td><%= invitation.used_at.strftime("%Y-%m-%d") %></td>
|
||||||
|
<td><%= User.find(invitation.invited_user_id).address %></td>
|
||||||
|
</tr>
|
||||||
|
<% end %>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</section>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|||||||
41
app/views/layouts/admin.html.erb
Normal file
41
app/views/layouts/admin.html.erb
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Admin Panel | Kosmos Accounts</title>
|
||||||
|
<%= csrf_meta_tags %>
|
||||||
|
<%= csp_meta_tag %>
|
||||||
|
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
|
||||||
|
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
|
||||||
|
<%= stylesheet_pack_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
|
||||||
|
<%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body id="admin-panel">
|
||||||
|
<div id="wrapper">
|
||||||
|
<header>
|
||||||
|
<h1>
|
||||||
|
<span class ="icon"><%= render partial: "shared/icons/comet" %></span>
|
||||||
|
<span class ="project-name">Kosmos</span>
|
||||||
|
<span class ="site-name">Accounts</span>
|
||||||
|
</h1>
|
||||||
|
<%= render partial: 'shared/header_account' %>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<% if user_signed_in? && current_user.confirmed? %>
|
||||||
|
<%= render partial: 'shared/admin_nav' %>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<% flash.each do |type, msg| %>
|
||||||
|
<div class="flash-msg <%= type %>">
|
||||||
|
<p><%= msg %></p>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<main>
|
||||||
|
<%= yield %>
|
||||||
|
</main>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -8,6 +8,7 @@
|
|||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
|
||||||
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
|
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
|
||||||
|
<%= stylesheet_pack_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
|
||||||
<%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
|
<%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
@@ -15,18 +16,17 @@
|
|||||||
<div id="wrapper">
|
<div id="wrapper">
|
||||||
<header>
|
<header>
|
||||||
<h1>
|
<h1>
|
||||||
|
<span class ="icon"><%= render partial: "shared/icons/comet" %></span>
|
||||||
<span class ="project-name">Kosmos</span>
|
<span class ="project-name">Kosmos</span>
|
||||||
<span class ="site-name">Akkounts</span>
|
<span class ="site-name">Account</span>
|
||||||
<span class="beta"><span class="bolt">⚡</span> beta</span>
|
|
||||||
</h1>
|
</h1>
|
||||||
<% if user_signed_in? %>
|
<%= render partial: 'shared/header_account' %>
|
||||||
<p class="current-user">
|
|
||||||
Signed in as <strong><%= current_user.cn %>@kosmos.org</strong>.
|
|
||||||
<%= link_to "Log out", destroy_user_session_path, method: :delete %>
|
|
||||||
</p>
|
|
||||||
<% end %>
|
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
|
<% if user_signed_in? && current_user.confirmed? %>
|
||||||
|
<%= render partial: 'shared/main_nav' %>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
<% flash.each do |type, msg| %>
|
<% flash.each do |type, msg| %>
|
||||||
<div class="flash-msg <%= type %>">
|
<div class="flash-msg <%= type %>">
|
||||||
<p><%= msg %></p>
|
<p><%= msg %></p>
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
|
||||||
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
|
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
|
||||||
|
<%= stylesheet_pack_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
|
||||||
<%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
|
<%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
@@ -15,9 +16,9 @@
|
|||||||
<div id="wrapper">
|
<div id="wrapper">
|
||||||
<header>
|
<header>
|
||||||
<h1>
|
<h1>
|
||||||
|
<span class ="icon"><%= render partial: "shared/icons/comet" %></span>
|
||||||
<span class ="project-name">Kosmos</span>
|
<span class ="project-name">Kosmos</span>
|
||||||
<span class ="site-name">Sign Up</span>
|
<span class ="site-name">Sign Up</span>
|
||||||
<!-- <span class="beta"><span class="bolt">⚡</span> beta</span> -->
|
|
||||||
</h1>
|
</h1>
|
||||||
<% if user_signed_in? %>
|
<% if user_signed_in? %>
|
||||||
<p class="current-user">
|
<p class="current-user">
|
||||||
|
|||||||
12
app/views/security/index.html.erb
Normal file
12
app/views/security/index.html.erb
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<section>
|
||||||
|
<h2>Security</h2>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<h3>Password change</h3>
|
||||||
|
<p>
|
||||||
|
<%= form_with(url: settings_reset_password_path, method: :post) do %>
|
||||||
|
<%= submit_tag("Send me a password reset link", class: 'btn-md btn-gray') %>
|
||||||
|
<% end %>
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
22
app/views/shared/_admin_nav.html.erb
Normal file
22
app/views/shared/_admin_nav.html.erb
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
<nav id="main-nav">
|
||||||
|
<div class="wrapper">
|
||||||
|
<ul class="pages">
|
||||||
|
<li>
|
||||||
|
<%= link_to "Dashboard", admin_root_path,
|
||||||
|
class: @current_section == :dashboard ? "active" : nil %>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<%= link_to "Invitations", admin_invitations_path,
|
||||||
|
class: @current_section == :invitations ? "active" : nil %>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<%= link_to "Donations", admin_donations_path,
|
||||||
|
class: @current_section == :donations ? "active" : nil %>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<%= link_to "LDAP Users", admin_ldap_users_path,
|
||||||
|
class: @current_section == :ldap_users ? "active" : nil %>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
6
app/views/shared/_header_account.html.erb
Normal file
6
app/views/shared/_header_account.html.erb
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<% if user_signed_in? %>
|
||||||
|
<p class="current-user mt-8">
|
||||||
|
Signed in as <strong class="text-white font-normal"><%= current_user.cn %>@kosmos.org</strong>.
|
||||||
|
<%= link_to "Log out", destroy_user_session_path, method: :delete, class: 'underline' %>
|
||||||
|
</p>
|
||||||
|
<% end %>
|
||||||
22
app/views/shared/_main_nav.html.erb
Normal file
22
app/views/shared/_main_nav.html.erb
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
<nav id="main-nav">
|
||||||
|
<div class="wrapper">
|
||||||
|
<ul class="pages">
|
||||||
|
<li>
|
||||||
|
<%= link_to "Services", root_path,
|
||||||
|
class: @current_section == :dashboard ? "active" : nil %>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<%= link_to "Invitations", invitations_path,
|
||||||
|
class: @current_section == :invitations ? "active" : nil %>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<%= link_to "Donations", donations_path,
|
||||||
|
class: @current_section == :contributions ? "active" : nil %>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<%= link_to "Security", security_path,
|
||||||
|
class: @current_section == :security ? "active" : nil %>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
1
app/views/shared/icons/_comet.html.erb
Normal file
1
app/views/shared/icons/_comet.html.erb
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg id="icon-comet" width="65.364" height="55.773" enable-background="new 0 0 100 100" version="1.1" viewBox="0 0 65.364 55.773" xml:space="preserve" xmlns="http://www.w3.org/2000/svg"><g id="layer1" transform="translate(28.868 20.259)" fill="#fff"><path id="path2" d="m22.81-9.2546-0.0137-0.0072c-0.0445-0.0196-0.0895-0.04052-0.13335-0.06078l-23.822-10.937s2.0034 9.219 2.914 11.778c0 0-27.292-8.1582-30.623-8.9354 1.0916 4.2618 20.006 40.848 20.006 40.848 3.8225 7.7608 12.677 12.083 21.912 12.083 12.949 0 23.446-10.497 23.446-23.446 6.6e-4 -9.4655-5.609-17.62-13.685-21.323z" fill="#fff" stroke-width=".65365"/></g></svg>
|
||||||
|
After Width: | Height: | Size: 627 B |
@@ -7,6 +7,6 @@
|
|||||||
This invitation can only be used once, and sign-up is currently only possible
|
This invitation can only be used once, and sign-up is currently only possible
|
||||||
by invitation. Seems like you have good friends!
|
by invitation. Seems like you have good friends!
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p class="mt-12">
|
||||||
<%= link_to "Get started", signup_steps_path(1), class: "next-step" %>
|
<%= link_to "Get started", signup_steps_path(1), class: "btn btn-md btn-blue" %>
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
@@ -2,60 +2,53 @@
|
|||||||
<% when 1 %>
|
<% when 1 %>
|
||||||
<h2>Choose a username</h2>
|
<h2>Choose a username</h2>
|
||||||
<%= form_for @user, :url => signup_validate_url do |f| %>
|
<%= form_for @user, :url => signup_validate_url do |f| %>
|
||||||
<div class="field">
|
<p>
|
||||||
<p>
|
<%= f.label :cn, 'Username', class: 'hidden' %>
|
||||||
<%= f.label :cn, 'Username' %><br />
|
<%= f.text_field :cn, autofocus: true, autocomplete: "username",
|
||||||
<%= f.text_field :cn, autofocus: true, autocomplete: "username" %>
|
class: 'text-xl' %>
|
||||||
<span class="at-sign">@</span>
|
<span class="text-xl ml-1">@</span>
|
||||||
<span class="domain">kosmos.org</span>
|
<span class="text-xl">kosmos.org</span>
|
||||||
</p>
|
</p>
|
||||||
<% if @validation_error.present? %>
|
<% if @validation_error.present? %>
|
||||||
<p class="error-msg">Username <%= @validation_error %></p>
|
<p class="error-msg">Username <%= @validation_error %></p>
|
||||||
<% end %>
|
<% end %>
|
||||||
</div>
|
<p class="mt-12">
|
||||||
<div class="actions">
|
<%= f.submit "Continue", class: 'btn btn-md btn-blue' %>
|
||||||
<p><%= f.submit "Continue" %></p>
|
</p>
|
||||||
</div>
|
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<% when 2 %>
|
<% when 2 %>
|
||||||
<h2>What's your email?</h2>
|
<h2>What's your email?</h2>
|
||||||
<%= form_for @user, :url => signup_validate_url do |f| %>
|
<%= form_for @user, :url => signup_validate_url do |f| %>
|
||||||
<div class="field">
|
<p>
|
||||||
<p>
|
<%= f.label :email, 'Email address', class: 'hidden' %>
|
||||||
<%= f.label :email, 'Email address' %><br />
|
<%= f.email_field :email, autofocus: true, autocomplete: 'email', class: 'text-xl' %>
|
||||||
<%= f.email_field :email, autofocus: true, autocomplete: "email" %>
|
</p>
|
||||||
</p>
|
<% if @validation_error.present? %>
|
||||||
<% if @validation_error.present? %>
|
<p class="error-msg">Email <%= @validation_error %></p>
|
||||||
<p class="error-msg">Email <%= @validation_error %></p>
|
<% end %>
|
||||||
<% end %>
|
<p class="mt-12">
|
||||||
</div>
|
<%= f.submit "Continue", class: 'btn btn-md btn-blue' %>
|
||||||
<div class="actions">
|
</p>
|
||||||
<p><%= f.submit "Continue" %></p>
|
|
||||||
</div>
|
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<% when 3 %>
|
<% when 3 %>
|
||||||
<h2>Choose a password</h2>
|
<h2>Choose a password</h2>
|
||||||
|
|
||||||
<%= form_for @user, :url => signup_validate_url do |f| %>
|
<%= form_for @user, :url => signup_validate_url do |f| %>
|
||||||
<div class="field">
|
<p>
|
||||||
<p>
|
<%= f.label :password, 'Password', class: 'hidden' %>
|
||||||
<%= f.label :password, 'Password' %><br />
|
<%= f.password_field :password, autofocus: true, class: 'text-xl' %>
|
||||||
<%= f.password_field :password, autofocus: true %>
|
</p>
|
||||||
</p>
|
<% if @validation_error.present? %>
|
||||||
<% if @validation_error.present? %>
|
<p class="error-msg">Password <%= @validation_error %></p>
|
||||||
<p class="error-msg">Password <%= @validation_error %></p>
|
<% end %>
|
||||||
<% end %>
|
<p class="mt-8 text-sm text-gray-500">
|
||||||
</div>
|
By clicking the button below, you accept our future Terms of Service
|
||||||
<p class="accept-terms">
|
and Privacy Policy. Don't worry, they will be excellent!
|
||||||
<small>
|
</p>
|
||||||
By clicking the button below, you accept our future Terms of Service
|
<p class="mt-8">
|
||||||
and Privacy Policy. Don't worry, they will be excellent!
|
<%= f.submit "Create account", class: 'btn-md btn-blue' %>
|
||||||
</small>
|
|
||||||
</p>
|
</p>
|
||||||
<div class="actions">
|
|
||||||
<p><%= f.submit "Create account" %></p>
|
|
||||||
</div>
|
|
||||||
<% end %>
|
<% end %>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|||||||
@@ -39,5 +39,8 @@ module Akkounts
|
|||||||
g.fixture_replacement :factory_bot, suffix_factory: 'factory', dir: 'spec/factories'
|
g.fixture_replacement :factory_bot, suffix_factory: 'factory', dir: 'spec/factories'
|
||||||
g.stylesheets false
|
g.stylesheets false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
config.active_job.queue_adapter = :sidekiq
|
||||||
|
config.action_mailer.deliver_later_queue_name = nil # use "default" queue
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
LWyKwPZq9Kd97rn/7+q3MEkh7kITScDMHD3JvVuaV3A4YIHJHU+460k+PaEGlsH1xkbuClGiAb57rk1XLyDnmVGtbSueYOtinkw6kar8ZfKWZob061LwGjpMVRQkS49TjCUZlqCFrXeKxlH03mXWBnqAj9RUIPrm7eibb3c7qmJFglR1380RSVsfZnp8A3QwGm4Wh9OWtpUa6P2lne0jQsOuSe8ur3DUF0LplzS4CbkMxAUDOom+pXB13AlxOH9NQE7F4dsYHugHkh1tG3r3ER3xAUD/9Kn6UZZP7BnwUs3zqhoZdULRpRgA5dK7ueTIAnO/jtJDF4562VS8ECo7AnNoVxNe8/mBMFIOUfqg+db/72N2pIk3r4lK7Uzm/4jJ5/99ItnQjHQPcApiwZXIr3OyDLUvq5+d0UVmAMXdwcAjvctVQXFx5imG149Y0ISHKWVm1ca37aAspxWPU+CIj8/HW0yEpjp3vhwDUbjCaZeAPm8UQC14MxZwSK3N+EUSQXdltiweFynabDB7zGGQsjMM8LwMtyo9bTBzJA78Cl96MDyd20i1zSF9ntLuKulwGm3oZowpbNuvo2anY6r9yBlDJBOEISbtXv2tLX4SqcM=--bRcsE4K/29XzyZat--+G3iQCLBqgSwLaQ+7+4YvA==
|
LXwVUXfG3P3NMBp56xEQHKY4YABoVvECgctVLuj4XRkCUKQURUC3pt60yBbMfw8Qs7yH1oeNiUv5ouoNrxR35PiquFr05oIPoHbHewB/aRShe7y313q1iXfddfYnom9r7wEETkeuFLBULNrLjJjzlgJgB8A9lmcSKMy9lEdGKJ5LghA6pEGq4KRxlixr8vC8ExcDtdENuxSWPU97cc5YHGjTTaiB9XIM61xtGcBUcREaizSyzloeRjPee71GfWKfVx3XNTQDoKfs6cecWhrSLlOVjsWGoiGlwpff3cPo1pSuYIoNo/YRnfHEr1WTw/+R3nc0wgPMBZSmFLK/8Uunzr8T6Q3vqqWB1QnKBquOcASa8jRaPFBs5k8PUeCT6aYdVBV0GSOGlyll2dBtfwrZgt2ssk24BuqK5pru5vIdhWNR7zl3+R0o2ABLTEcBSuxe754NiPasEKRQ8/K4lojOjnOcwdhdqC7jN2RVS5G03ZgHEqk1m+Z9svtu9PaRAD8I9vrpCQfq9Bifm2qZUSBJrgexHtDnSMfg/36hCUeyd2z0naoq3IWJ/xyCf1S5uzyd5MPh7N76L9FudD5nK39Jrj+yuVayAXQ1M9K89kSCiC2/ZbBE--TCbSksW4umkXZY62--jE6cZdM44o8/AWe7alnotA==
|
||||||
@@ -49,4 +49,6 @@ Rails.application.configure do
|
|||||||
protocol: "https",
|
protocol: "https",
|
||||||
from: "accounts@kosmos.org"
|
from: "accounts@kosmos.org"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
config.active_job.queue_adapter = :test
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
|
require 'sidekiq/web'
|
||||||
|
|
||||||
Rails.application.routes.draw do
|
Rails.application.routes.draw do
|
||||||
|
resources :donations
|
||||||
devise_for :users
|
devise_for :users
|
||||||
|
|
||||||
get 'welcome', to: 'welcome#index'
|
get 'welcome', to: 'welcome#index'
|
||||||
@@ -11,11 +14,19 @@ Rails.application.routes.draw do
|
|||||||
get 'settings', to: 'settings#index'
|
get 'settings', to: 'settings#index'
|
||||||
post 'settings_reset_password', to: 'settings#reset_password'
|
post 'settings_reset_password', to: 'settings#reset_password'
|
||||||
|
|
||||||
|
get 'security', to: 'security#index'
|
||||||
|
|
||||||
resources :invitations, only: ['index', 'show', 'create', 'destroy']
|
resources :invitations, only: ['index', 'show', 'create', 'destroy']
|
||||||
|
|
||||||
namespace :admin do
|
namespace :admin do
|
||||||
root to: 'dashboard#index'
|
root to: 'dashboard#index'
|
||||||
|
get 'invitations', to: 'invitations#index'
|
||||||
get 'ldap_users', to: 'ldap_users#index'
|
get 'ldap_users', to: 'ldap_users#index'
|
||||||
|
resources :donations
|
||||||
|
end
|
||||||
|
|
||||||
|
authenticate :user, ->(user) { user.is_admin? } do
|
||||||
|
mount Sidekiq::Web => '/sidekiq'
|
||||||
end
|
end
|
||||||
|
|
||||||
# Letter Opener (open "sent" emails in dev and staging)
|
# Letter Opener (open "sent" emails in dev and staging)
|
||||||
|
|||||||
3
config/sidekiq.yml
Normal file
3
config/sidekiq.yml
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
:concurrency: 2
|
||||||
|
:queues:
|
||||||
|
- default
|
||||||
@@ -8,6 +8,7 @@ class CreateInvitations < ActiveRecord::Migration[6.0]
|
|||||||
|
|
||||||
t.timestamps
|
t.timestamps
|
||||||
end
|
end
|
||||||
|
|
||||||
add_index :invitations, :user_id
|
add_index :invitations, :user_id
|
||||||
add_index :invitations, :invited_user_id
|
add_index :invitations, :invited_user_id
|
||||||
end
|
end
|
||||||
|
|||||||
15
db/migrate/20201217161544_create_donations.rb
Normal file
15
db/migrate/20201217161544_create_donations.rb
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
class CreateDonations < ActiveRecord::Migration[6.0]
|
||||||
|
def change
|
||||||
|
create_table :donations do |t|
|
||||||
|
t.integer :user_id
|
||||||
|
t.integer :amount_sats
|
||||||
|
t.integer :amount_eur
|
||||||
|
t.integer :amount_usd
|
||||||
|
t.string :public_name
|
||||||
|
|
||||||
|
t.timestamps
|
||||||
|
end
|
||||||
|
|
||||||
|
add_index :donations, :user_id
|
||||||
|
end
|
||||||
|
end
|
||||||
5
db/migrate/20201219121808_add_paid_at_to_donations.rb
Normal file
5
db/migrate/20201219121808_add_paid_at_to_donations.rb
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
class AddPaidAtToDonations < ActiveRecord::Migration[6.0]
|
||||||
|
def change
|
||||||
|
add_column :donations, :paid_at, :datetime
|
||||||
|
end
|
||||||
|
end
|
||||||
14
db/schema.rb
14
db/schema.rb
@@ -10,7 +10,19 @@
|
|||||||
#
|
#
|
||||||
# It's strongly recommended that you check this file into your version control system.
|
# It's strongly recommended that you check this file into your version control system.
|
||||||
|
|
||||||
ActiveRecord::Schema.define(version: 2020_11_30_132533) do
|
ActiveRecord::Schema.define(version: 2020_12_19_121808) do
|
||||||
|
|
||||||
|
create_table "donations", force: :cascade do |t|
|
||||||
|
t.integer "user_id"
|
||||||
|
t.integer "amount_sats"
|
||||||
|
t.integer "amount_eur"
|
||||||
|
t.integer "amount_usd"
|
||||||
|
t.string "public_name"
|
||||||
|
t.datetime "created_at", precision: 6, null: false
|
||||||
|
t.datetime "updated_at", precision: 6, null: false
|
||||||
|
t.datetime "paid_at"
|
||||||
|
t.index ["user_id"], name: "index_donations_on_user_id"
|
||||||
|
end
|
||||||
|
|
||||||
create_table "invitations", force: :cascade do |t|
|
create_table "invitations", force: :cascade do |t|
|
||||||
t.string "token"
|
t.string "token"
|
||||||
|
|||||||
@@ -5,6 +5,10 @@
|
|||||||
"@rails/actioncable": "^6.0.0",
|
"@rails/actioncable": "^6.0.0",
|
||||||
"@rails/ujs": "^6.0.0",
|
"@rails/ujs": "^6.0.0",
|
||||||
"@rails/webpacker": "4.3.0",
|
"@rails/webpacker": "4.3.0",
|
||||||
|
"@tailwindcss/forms": "^0.2.1",
|
||||||
|
"autoprefixer": "^9",
|
||||||
|
"postcss": "^7",
|
||||||
|
"tailwindcss": "npm:@tailwindcss/postcss7-compat",
|
||||||
"turbolinks": "^5.2.0"
|
"turbolinks": "^5.2.0"
|
||||||
},
|
},
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
plugins: [
|
plugins: [
|
||||||
|
require("tailwindcss")("./app/javascript/stylesheets/tailwind.config.js"),
|
||||||
require('postcss-import'),
|
require('postcss-import'),
|
||||||
require('postcss-flexbugs-fixes'),
|
require('postcss-flexbugs-fixes'),
|
||||||
require('postcss-preset-env')({
|
require('postcss-preset-env')({
|
||||||
|
|||||||
BIN
public/img/bg-1.jpg
Normal file
BIN
public/img/bg-1.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 291 KiB |
9
spec/factories/donations.rb
Normal file
9
spec/factories/donations.rb
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
FactoryBot.define do
|
||||||
|
factory :donation do
|
||||||
|
user_id { 1 }
|
||||||
|
amount_sats { 100000 }
|
||||||
|
amount_eur { 10 }
|
||||||
|
amount_usd { 13 }
|
||||||
|
public_name { nil }
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -10,6 +10,6 @@ RSpec.describe 'Admin dashboard', type: :feature do
|
|||||||
|
|
||||||
scenario 'View dashboard' do
|
scenario 'View dashboard' do
|
||||||
visit admin_root_path
|
visit admin_root_path
|
||||||
expect(page).to have_content('Admin Panel')
|
expect(page).to have_content('great power')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -53,8 +53,11 @@ RSpec.describe "Signup", type: :feature do
|
|||||||
expect(page).to have_content("Choose a password")
|
expect(page).to have_content("Choose a password")
|
||||||
|
|
||||||
expect(CreateAccount).to receive(:call)
|
expect(CreateAccount).to receive(:call)
|
||||||
.with(username: "tony", email: "tony@example.com", password: "a-valid-password")
|
.with(
|
||||||
.and_return(true)
|
username: "tony", domain: "kosmos.org",
|
||||||
|
email: "tony@example.com", password: "a-valid-password",
|
||||||
|
invitation: Invitation.last
|
||||||
|
).and_return(true)
|
||||||
|
|
||||||
fill_in "user_password", with: "a-valid-password"
|
fill_in "user_password", with: "a-valid-password"
|
||||||
click_button "Create account"
|
click_button "Create account"
|
||||||
@@ -62,7 +65,6 @@ RSpec.describe "Signup", type: :feature do
|
|||||||
expect(page).to have_content("confirm your address")
|
expect(page).to have_content("confirm your address")
|
||||||
end
|
end
|
||||||
expect(page).to have_content("close this window or tab now")
|
expect(page).to have_content("close this window or tab now")
|
||||||
expect(User.last.confirmed_at).to be_nil
|
|
||||||
end
|
end
|
||||||
|
|
||||||
scenario "Validation errors" do
|
scenario "Validation errors" do
|
||||||
@@ -89,15 +91,17 @@ RSpec.describe "Signup", type: :feature do
|
|||||||
expect(page).to have_content("Password is too short")
|
expect(page).to have_content("Password is too short")
|
||||||
|
|
||||||
expect(CreateAccount).to receive(:call)
|
expect(CreateAccount).to receive(:call)
|
||||||
.with(username: "tony", email: "tony@example.com", password: "a-valid-password")
|
.with(
|
||||||
.and_return(true)
|
username: "tony", domain: "kosmos.org",
|
||||||
|
email: "tony@example.com", password: "a-valid-password",
|
||||||
|
invitation: Invitation.last
|
||||||
|
).and_return(true)
|
||||||
|
|
||||||
fill_in "user_password", with: "a-valid-password"
|
fill_in "user_password", with: "a-valid-password"
|
||||||
click_button "Create account"
|
click_button "Create account"
|
||||||
within ".flash-msg.notice" do
|
within ".flash-msg.notice" do
|
||||||
expect(page).to have_content("confirm your address")
|
expect(page).to have_content("confirm your address")
|
||||||
end
|
end
|
||||||
expect(User.last.cn).to eq("tony")
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
9
spec/helpers/application_helper_spec.rb
Normal file
9
spec/helpers/application_helper_spec.rb
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
describe ApplicationHelper do
|
||||||
|
describe "sats_to_btc" do
|
||||||
|
it "converts satoshis to BTC" do
|
||||||
|
expect(helper.sats_to_btc(120000000)).to eq(1.2)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
15
spec/helpers/donations_helper_spec.rb
Normal file
15
spec/helpers/donations_helper_spec.rb
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
# Specs in this file have access to a helper object that includes
|
||||||
|
# the DonationsHelper. For example:
|
||||||
|
#
|
||||||
|
# describe DonationsHelper do
|
||||||
|
# describe "string concat" do
|
||||||
|
# it "concats two strings with spaces" do
|
||||||
|
# expect(helper.concat_strings("this","that")).to eq("this that")
|
||||||
|
# end
|
||||||
|
# end
|
||||||
|
# end
|
||||||
|
RSpec.describe DonationsHelper, type: :helper do
|
||||||
|
pending "add some examples to (or delete) #{__FILE__}"
|
||||||
|
end
|
||||||
34
spec/jobs/create_ldap_user_job_spec.rb
Normal file
34
spec/jobs/create_ldap_user_job_spec.rb
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
RSpec.describe CreateLdapUserJob, type: :job do
|
||||||
|
let(:ldap_client_mock) { instance_double(Net::LDAP) }
|
||||||
|
|
||||||
|
subject(:job) {
|
||||||
|
described_class.any_instance.stub(:ldap_client).and_return(ldap_client_mock)
|
||||||
|
described_class.perform_later(
|
||||||
|
'halfinney', 'kosmos.org', 'halfinney@example.com',
|
||||||
|
'remember-remember-the-5th-of-november'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
it "creates a new document with the correct attributes" do
|
||||||
|
ldap_client_mock.should_receive(:add).with(
|
||||||
|
dn: "cn=halfinney,ou=kosmos.org,cn=users,dc=kosmos,dc=org",
|
||||||
|
attributes: {
|
||||||
|
objectclass: ["top", "account", "person", "extensibleObject"],
|
||||||
|
cn: "halfinney",
|
||||||
|
sn: "halfinney",
|
||||||
|
uid: "halfinney",
|
||||||
|
mail: "halfinney@example.com",
|
||||||
|
userPassword: "remember-remember-the-5th-of-november"
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
perform_enqueued_jobs { job }
|
||||||
|
end
|
||||||
|
|
||||||
|
after do
|
||||||
|
clear_enqueued_jobs
|
||||||
|
clear_performed_jobs
|
||||||
|
end
|
||||||
|
end
|
||||||
29
spec/jobs/exchange_xmpp_contacts_job_spec.rb
Normal file
29
spec/jobs/exchange_xmpp_contacts_job_spec.rb
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
require 'rails_helper'
|
||||||
|
require 'webmock/rspec'
|
||||||
|
|
||||||
|
RSpec.describe ExchangeXmppContactsJob, type: :job do
|
||||||
|
let(:user) { create :user, cn: "willherschel", ou: "kosmos.org" }
|
||||||
|
|
||||||
|
subject(:job) {
|
||||||
|
described_class.perform_later(user, 'isaacnewton', 'kosmos.org')
|
||||||
|
}
|
||||||
|
|
||||||
|
before do
|
||||||
|
stub_request(:post, "http://xmpp.example.com/api/add_rosteritem")
|
||||||
|
.to_return(status: 200, body: "", headers: {})
|
||||||
|
end
|
||||||
|
|
||||||
|
it "posts add_rosteritem commands to the ejabberd API" do
|
||||||
|
perform_enqueued_jobs { job }
|
||||||
|
|
||||||
|
expect(WebMock).to have_requested(:post, "http://xmpp.example.com/api/add_rosteritem")
|
||||||
|
.with { |req| req.body == '{"localuser":"isaacnewton","localhost":"kosmos.org","user":"willherschel","host":"kosmos.org","nick":"willherschel","group":"Friends","subs":"both"}' }
|
||||||
|
expect(WebMock).to have_requested(:post, "http://xmpp.example.com/api/add_rosteritem")
|
||||||
|
.with { |req| req.body == '{"localuser":"willherschel","localhost":"kosmos.org","user":"isaacnewton","host":"kosmos.org","nick":"isaacnewton","group":"Friends","subs":"both"}' }
|
||||||
|
end
|
||||||
|
|
||||||
|
after do
|
||||||
|
clear_enqueued_jobs
|
||||||
|
clear_performed_jobs
|
||||||
|
end
|
||||||
|
end
|
||||||
5
spec/models/donation_spec.rb
Normal file
5
spec/models/donation_spec.rb
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
RSpec.describe Donation, type: :model do
|
||||||
|
pending "add some examples to (or delete) #{__FILE__}"
|
||||||
|
end
|
||||||
@@ -69,5 +69,6 @@ RSpec.configure do |config|
|
|||||||
config.include Devise::Test::ControllerHelpers, :type => :controller
|
config.include Devise::Test::ControllerHelpers, :type => :controller
|
||||||
config.include Warden::Test::Helpers
|
config.include Warden::Test::Helpers
|
||||||
config.include FactoryBot::Syntax::Methods
|
config.include FactoryBot::Syntax::Methods
|
||||||
|
config.include ActiveJob::TestHelper, type: :job
|
||||||
config.extend ControllerMacros, :type => :controller
|
config.extend ControllerMacros, :type => :controller
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,33 +1,95 @@
|
|||||||
require 'rails_helper'
|
require 'rails_helper'
|
||||||
|
|
||||||
RSpec.describe CreateAccount, type: :model do
|
RSpec.describe CreateAccount, type: :model do
|
||||||
let(:ldap_client_mock) { instance_double(Net::LDAP) }
|
describe "#create_user_in_database" do
|
||||||
|
let(:service) { CreateAccount.new(
|
||||||
|
username: 'isaacnewton',
|
||||||
|
email: 'isaacnewton@example.com',
|
||||||
|
password: 'bright-ideas-in-autumn'
|
||||||
|
)}
|
||||||
|
|
||||||
before do
|
it "creates a new user record in the akkounts database" do
|
||||||
allow(service).to receive(:ldap_client).and_return(ldap_client_mock)
|
expect(User.count).to eq(0)
|
||||||
|
service.send(:create_user_in_database)
|
||||||
|
expect(User.count).to eq(1)
|
||||||
|
expect(User.last.cn).to eq("isaacnewton")
|
||||||
|
expect(User.last.email).to eq("isaacnewton@example.com")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#update_invitation" do
|
||||||
|
let(:invitation) { create :invitation }
|
||||||
|
let(:service) { CreateAccount.new(
|
||||||
|
username: 'isaacnewton',
|
||||||
|
email: 'isaacnewton@example.com',
|
||||||
|
password: 'bright-ideas-in-autumn',
|
||||||
|
invitation: invitation
|
||||||
|
)}
|
||||||
|
|
||||||
|
before(:each) do
|
||||||
|
service.send(:update_invitation, 23)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "marks the invitation as used" do
|
||||||
|
expect(invitation.used_at).not_to be_nil
|
||||||
|
end
|
||||||
|
|
||||||
|
it "saves the invited user's ID" do
|
||||||
|
expect(invitation.invited_user_id).to eq(23)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "#add_ldap_document" do
|
describe "#add_ldap_document" do
|
||||||
|
include ActiveJob::TestHelper
|
||||||
|
|
||||||
let(:service) { CreateAccount.new(
|
let(:service) { CreateAccount.new(
|
||||||
username: 'halfinney',
|
username: 'halfinney',
|
||||||
email: 'halfinney@example.com',
|
email: 'halfinney@example.com',
|
||||||
password: 'remember-remember-the-5th-of-november'
|
password: 'remember-remember-the-5th-of-november'
|
||||||
)}
|
)}
|
||||||
|
|
||||||
it "creates a new document with the correct attributes" do
|
it "enqueues a job to create the LDAP user document" do
|
||||||
expect(ldap_client_mock).to receive(:add).with(
|
|
||||||
dn: "cn=halfinney,ou=kosmos.org,cn=users,dc=kosmos,dc=org",
|
|
||||||
attributes: {
|
|
||||||
objectclass: ["top", "account", "person", "extensibleObject"],
|
|
||||||
cn: "halfinney",
|
|
||||||
sn: "halfinney",
|
|
||||||
uid: "halfinney",
|
|
||||||
mail: "halfinney@example.com",
|
|
||||||
userPassword: /^{SSHA512}.{171}=/
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
service.send(:add_ldap_document)
|
service.send(:add_ldap_document)
|
||||||
|
|
||||||
|
expect(enqueued_jobs.size).to eq(1)
|
||||||
|
|
||||||
|
args = enqueued_jobs.first['arguments']
|
||||||
|
expect(args[0]).to eq('halfinney')
|
||||||
|
expect(args[1]).to eq('kosmos.org')
|
||||||
|
expect(args[2]).to eq('halfinney@example.com')
|
||||||
|
expect(args[3]).to match(/^{SSHA512}.{171}=/)
|
||||||
|
end
|
||||||
|
|
||||||
|
after do
|
||||||
|
clear_enqueued_jobs
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#exchange_xmpp_contacts" do
|
||||||
|
include ActiveJob::TestHelper
|
||||||
|
|
||||||
|
let(:inviter) { create :user, cn: "willherschel", ou: "kosmos.org" }
|
||||||
|
let(:invitation) { create :invitation, user: inviter }
|
||||||
|
let(:service) { CreateAccount.new(
|
||||||
|
username: 'isaacnewton',
|
||||||
|
email: 'isaacnewton@example.com',
|
||||||
|
password: 'bright-ideas-in-autumn',
|
||||||
|
invitation: invitation
|
||||||
|
)}
|
||||||
|
|
||||||
|
it "enqueues a job to exchange XMPP contacts between inviter and invitee" do
|
||||||
|
service.send(:exchange_xmpp_contacts)
|
||||||
|
|
||||||
|
expect(enqueued_jobs.size).to eq(1)
|
||||||
|
|
||||||
|
args = enqueued_jobs.first['arguments']
|
||||||
|
expect(args[0]['_aj_globalid']).to match('gid://akkounts/User')
|
||||||
|
expect(args[1]).to eq('isaacnewton')
|
||||||
|
expect(args[2]).to eq('kosmos.org')
|
||||||
|
end
|
||||||
|
|
||||||
|
after do
|
||||||
|
clear_enqueued_jobs
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
294
yarn.lock
294
yarn.lock
@@ -839,6 +839,13 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@csstools/convert-colors/-/convert-colors-1.4.0.tgz#ad495dc41b12e75d588c6db8b9834f08fa131eb7"
|
resolved "https://registry.yarnpkg.com/@csstools/convert-colors/-/convert-colors-1.4.0.tgz#ad495dc41b12e75d588c6db8b9834f08fa131eb7"
|
||||||
integrity sha512-5a6wqoJV/xEdbRNKVo6I4hO3VjyDq//8q2f9I6PBAvMesJHFauXDorcNCsr9RzvsZnaWi5NYCcfyqP1QeFHFbw==
|
integrity sha512-5a6wqoJV/xEdbRNKVo6I4hO3VjyDq//8q2f9I6PBAvMesJHFauXDorcNCsr9RzvsZnaWi5NYCcfyqP1QeFHFbw==
|
||||||
|
|
||||||
|
"@fullhuman/postcss-purgecss@^3.0.0":
|
||||||
|
version "3.1.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@fullhuman/postcss-purgecss/-/postcss-purgecss-3.1.3.tgz#47af7b87c9bfb3de4bc94a38f875b928fffdf339"
|
||||||
|
integrity sha512-kwOXw8fZ0Lt1QmeOOrd+o4Ibvp4UTEBFQbzvWldjlKv5n+G9sXfIPn1hh63IQIL8K8vbvv1oYMJiIUbuy9bGaA==
|
||||||
|
dependencies:
|
||||||
|
purgecss "^3.1.3"
|
||||||
|
|
||||||
"@npmcli/move-file@^1.0.1":
|
"@npmcli/move-file@^1.0.1":
|
||||||
version "1.0.1"
|
version "1.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/@npmcli/move-file/-/move-file-1.0.1.tgz#de103070dac0f48ce49cf6693c23af59c0f70464"
|
resolved "https://registry.yarnpkg.com/@npmcli/move-file/-/move-file-1.0.1.tgz#de103070dac0f48ce49cf6693c23af59c0f70464"
|
||||||
@@ -900,6 +907,13 @@
|
|||||||
webpack-cli "^3.3.10"
|
webpack-cli "^3.3.10"
|
||||||
webpack-sources "^1.4.3"
|
webpack-sources "^1.4.3"
|
||||||
|
|
||||||
|
"@tailwindcss/forms@^0.2.1":
|
||||||
|
version "0.2.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@tailwindcss/forms/-/forms-0.2.1.tgz#3244b185854fae1a7cbe8d2456314d8b2d98cf43"
|
||||||
|
integrity sha512-czfvEdY+J2Ogfd6RUSr/ZSUmDxTujr34M++YLnp2cCPC3oJ4kFvFMaRXA6cEXKw7F1hJuapdjXRjsXIEXGgORg==
|
||||||
|
dependencies:
|
||||||
|
mini-svg-data-uri "^1.2.3"
|
||||||
|
|
||||||
"@types/glob@^7.1.1":
|
"@types/glob@^7.1.1":
|
||||||
version "7.1.3"
|
version "7.1.3"
|
||||||
resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.3.tgz#e6ba80f36b7daad2c685acd9266382e68985c183"
|
resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.3.tgz#e6ba80f36b7daad2c685acd9266382e68985c183"
|
||||||
@@ -1101,11 +1115,30 @@ accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.7:
|
|||||||
mime-types "~2.1.24"
|
mime-types "~2.1.24"
|
||||||
negotiator "0.6.2"
|
negotiator "0.6.2"
|
||||||
|
|
||||||
|
acorn-node@^1.6.1:
|
||||||
|
version "1.8.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/acorn-node/-/acorn-node-1.8.2.tgz#114c95d64539e53dede23de8b9d96df7c7ae2af8"
|
||||||
|
integrity sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A==
|
||||||
|
dependencies:
|
||||||
|
acorn "^7.0.0"
|
||||||
|
acorn-walk "^7.0.0"
|
||||||
|
xtend "^4.0.2"
|
||||||
|
|
||||||
|
acorn-walk@^7.0.0:
|
||||||
|
version "7.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-7.2.0.tgz#0de889a601203909b0fbe07b8938dc21d2e967bc"
|
||||||
|
integrity sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==
|
||||||
|
|
||||||
acorn@^6.4.1:
|
acorn@^6.4.1:
|
||||||
version "6.4.2"
|
version "6.4.2"
|
||||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.2.tgz#35866fd710528e92de10cf06016498e47e39e1e6"
|
resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.2.tgz#35866fd710528e92de10cf06016498e47e39e1e6"
|
||||||
integrity sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==
|
integrity sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==
|
||||||
|
|
||||||
|
acorn@^7.0.0:
|
||||||
|
version "7.4.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa"
|
||||||
|
integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==
|
||||||
|
|
||||||
aggregate-error@^3.0.0:
|
aggregate-error@^3.0.0:
|
||||||
version "3.1.0"
|
version "3.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a"
|
resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a"
|
||||||
@@ -1181,6 +1214,13 @@ ansi-styles@^3.2.0, ansi-styles@^3.2.1:
|
|||||||
dependencies:
|
dependencies:
|
||||||
color-convert "^1.9.0"
|
color-convert "^1.9.0"
|
||||||
|
|
||||||
|
ansi-styles@^4.1.0:
|
||||||
|
version "4.3.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937"
|
||||||
|
integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==
|
||||||
|
dependencies:
|
||||||
|
color-convert "^2.0.1"
|
||||||
|
|
||||||
anymatch@^2.0.0:
|
anymatch@^2.0.0:
|
||||||
version "2.0.0"
|
version "2.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb"
|
resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb"
|
||||||
@@ -1326,12 +1366,17 @@ asynckit@^0.4.0:
|
|||||||
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
|
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
|
||||||
integrity sha1-x57Zf380y48robyXkLzDZkdLS3k=
|
integrity sha1-x57Zf380y48robyXkLzDZkdLS3k=
|
||||||
|
|
||||||
|
at-least-node@^1.0.0:
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2"
|
||||||
|
integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==
|
||||||
|
|
||||||
atob@^2.1.2:
|
atob@^2.1.2:
|
||||||
version "2.1.2"
|
version "2.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9"
|
resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9"
|
||||||
integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==
|
integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==
|
||||||
|
|
||||||
autoprefixer@^9.6.1:
|
autoprefixer@^9, autoprefixer@^9.6.1:
|
||||||
version "9.8.6"
|
version "9.8.6"
|
||||||
resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.8.6.tgz#3b73594ca1bf9266320c5acf1588d74dea74210f"
|
resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.8.6.tgz#3b73594ca1bf9266320c5acf1588d74dea74210f"
|
||||||
integrity sha512-XrvP4VVHdRBCdX1S3WXVD8+RyG9qeb1D5Sn1DeLiG2xfSpzellk5k54xbUERJ3M5DggQxes39UGOTP8CFrEGbg==
|
integrity sha512-XrvP4VVHdRBCdX1S3WXVD8+RyG9qeb1D5Sn1DeLiG2xfSpzellk5k54xbUERJ3M5DggQxes39UGOTP8CFrEGbg==
|
||||||
@@ -1634,7 +1679,7 @@ bytes@3.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048"
|
resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048"
|
||||||
integrity sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=
|
integrity sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=
|
||||||
|
|
||||||
bytes@3.1.0:
|
bytes@3.1.0, bytes@^3.0.0:
|
||||||
version "3.1.0"
|
version "3.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6"
|
resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6"
|
||||||
integrity sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==
|
integrity sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==
|
||||||
@@ -1754,6 +1799,11 @@ callsites@^3.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73"
|
resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73"
|
||||||
integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==
|
integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==
|
||||||
|
|
||||||
|
camelcase-css@^2.0.1:
|
||||||
|
version "2.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/camelcase-css/-/camelcase-css-2.0.1.tgz#ee978f6947914cc30c6b44741b6ed1df7f043fd5"
|
||||||
|
integrity sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==
|
||||||
|
|
||||||
camelcase-keys@^2.0.0:
|
camelcase-keys@^2.0.0:
|
||||||
version "2.1.0"
|
version "2.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-2.1.0.tgz#308beeaffdf28119051efa1d932213c91b8f92e7"
|
resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-2.1.0.tgz#308beeaffdf28119051efa1d932213c91b8f92e7"
|
||||||
@@ -1817,6 +1867,14 @@ chalk@^2.0, chalk@^2.0.0, chalk@^2.4.1, chalk@^2.4.2:
|
|||||||
escape-string-regexp "^1.0.5"
|
escape-string-regexp "^1.0.5"
|
||||||
supports-color "^5.3.0"
|
supports-color "^5.3.0"
|
||||||
|
|
||||||
|
chalk@^4.1.0:
|
||||||
|
version "4.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.0.tgz#4e14870a618d9e2edd97dd8345fd9d9dc315646a"
|
||||||
|
integrity sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==
|
||||||
|
dependencies:
|
||||||
|
ansi-styles "^4.1.0"
|
||||||
|
supports-color "^7.1.0"
|
||||||
|
|
||||||
chokidar@^2.1.8:
|
chokidar@^2.1.8:
|
||||||
version "2.1.8"
|
version "2.1.8"
|
||||||
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.8.tgz#804b3a7b6a99358c3c5c61e71d8728f041cff917"
|
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.8.tgz#804b3a7b6a99358c3c5c61e71d8728f041cff917"
|
||||||
@@ -1938,12 +1996,19 @@ color-convert@^1.9.0, color-convert@^1.9.1:
|
|||||||
dependencies:
|
dependencies:
|
||||||
color-name "1.1.3"
|
color-name "1.1.3"
|
||||||
|
|
||||||
|
color-convert@^2.0.1:
|
||||||
|
version "2.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3"
|
||||||
|
integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==
|
||||||
|
dependencies:
|
||||||
|
color-name "~1.1.4"
|
||||||
|
|
||||||
color-name@1.1.3:
|
color-name@1.1.3:
|
||||||
version "1.1.3"
|
version "1.1.3"
|
||||||
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"
|
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"
|
||||||
integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=
|
integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=
|
||||||
|
|
||||||
color-name@^1.0.0:
|
color-name@^1.0.0, color-name@~1.1.4:
|
||||||
version "1.1.4"
|
version "1.1.4"
|
||||||
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
|
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
|
||||||
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
|
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
|
||||||
@@ -1956,7 +2021,7 @@ color-string@^1.5.4:
|
|||||||
color-name "^1.0.0"
|
color-name "^1.0.0"
|
||||||
simple-swizzle "^0.2.2"
|
simple-swizzle "^0.2.2"
|
||||||
|
|
||||||
color@^3.0.0:
|
color@^3.0.0, color@^3.1.3:
|
||||||
version "3.1.3"
|
version "3.1.3"
|
||||||
resolved "https://registry.yarnpkg.com/color/-/color-3.1.3.tgz#ca67fb4e7b97d611dcde39eceed422067d91596e"
|
resolved "https://registry.yarnpkg.com/color/-/color-3.1.3.tgz#ca67fb4e7b97d611dcde39eceed422067d91596e"
|
||||||
integrity sha512-xgXAcTHa2HeFCGLE9Xs/R82hujGtu9Jd9x4NW3T34+OMs7VoPsjwzRczKHvTAHeJwWFwX5j15+MgAppE8ztObQ==
|
integrity sha512-xgXAcTHa2HeFCGLE9Xs/R82hujGtu9Jd9x4NW3T34+OMs7VoPsjwzRczKHvTAHeJwWFwX5j15+MgAppE8ztObQ==
|
||||||
@@ -1981,6 +2046,11 @@ commander@^2.20.0:
|
|||||||
resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
|
resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
|
||||||
integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==
|
integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==
|
||||||
|
|
||||||
|
commander@^6.0.0:
|
||||||
|
version "6.2.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.1.tgz#0792eb682dfbc325999bb2b84fddddba110ac73c"
|
||||||
|
integrity sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==
|
||||||
|
|
||||||
commondir@^1.0.1:
|
commondir@^1.0.1:
|
||||||
version "1.0.1"
|
version "1.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b"
|
resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b"
|
||||||
@@ -2294,6 +2364,11 @@ css-tree@^1.0.0:
|
|||||||
mdn-data "2.0.12"
|
mdn-data "2.0.12"
|
||||||
source-map "^0.6.1"
|
source-map "^0.6.1"
|
||||||
|
|
||||||
|
css-unit-converter@^1.1.1:
|
||||||
|
version "1.1.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/css-unit-converter/-/css-unit-converter-1.1.2.tgz#4c77f5a1954e6dbff60695ecb214e3270436ab21"
|
||||||
|
integrity sha512-IiJwMC8rdZE0+xiEZHeru6YoONC4rfPMqGm2W85jMIbkFvv5nFTwJVFHam2eFrN6txmoUYFAFXiv8ICVeTO0MA==
|
||||||
|
|
||||||
css-what@^3.2.1:
|
css-what@^3.2.1:
|
||||||
version "3.4.2"
|
version "3.4.2"
|
||||||
resolved "https://registry.yarnpkg.com/css-what/-/css-what-3.4.2.tgz#ea7026fcb01777edbde52124e21f327e7ae950e4"
|
resolved "https://registry.yarnpkg.com/css-what/-/css-what-3.4.2.tgz#ea7026fcb01777edbde52124e21f327e7ae950e4"
|
||||||
@@ -2488,6 +2563,11 @@ define-property@^2.0.2:
|
|||||||
is-descriptor "^1.0.2"
|
is-descriptor "^1.0.2"
|
||||||
isobject "^3.0.1"
|
isobject "^3.0.1"
|
||||||
|
|
||||||
|
defined@^1.0.0:
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693"
|
||||||
|
integrity sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=
|
||||||
|
|
||||||
del@^4.1.1:
|
del@^4.1.1:
|
||||||
version "4.1.1"
|
version "4.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/del/-/del-4.1.1.tgz#9e8f117222ea44a31ff3a156c049b99052a9f0b4"
|
resolved "https://registry.yarnpkg.com/del/-/del-4.1.1.tgz#9e8f117222ea44a31ff3a156c049b99052a9f0b4"
|
||||||
@@ -2539,6 +2619,20 @@ detect-node@^2.0.4:
|
|||||||
resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.0.4.tgz#014ee8f8f669c5c58023da64b8179c083a28c46c"
|
resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.0.4.tgz#014ee8f8f669c5c58023da64b8179c083a28c46c"
|
||||||
integrity sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw==
|
integrity sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw==
|
||||||
|
|
||||||
|
detective@^5.2.0:
|
||||||
|
version "5.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/detective/-/detective-5.2.0.tgz#feb2a77e85b904ecdea459ad897cc90a99bd2a7b"
|
||||||
|
integrity sha512-6SsIx+nUUbuK0EthKjv0zrdnajCCXVYGmbYYiYjFVpzcjwEs/JMDZ8tPRG29J/HhN56t3GJp2cGSWDRjjot8Pg==
|
||||||
|
dependencies:
|
||||||
|
acorn-node "^1.6.1"
|
||||||
|
defined "^1.0.0"
|
||||||
|
minimist "^1.1.1"
|
||||||
|
|
||||||
|
didyoumean@^1.2.1:
|
||||||
|
version "1.2.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/didyoumean/-/didyoumean-1.2.1.tgz#e92edfdada6537d484d73c0172fd1eba0c4976ff"
|
||||||
|
integrity sha1-6S7f2tplN9SE1zwBcv0eugxJdv8=
|
||||||
|
|
||||||
diffie-hellman@^5.0.0:
|
diffie-hellman@^5.0.0:
|
||||||
version "5.0.3"
|
version "5.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875"
|
resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875"
|
||||||
@@ -3124,6 +3218,16 @@ from2@^2.1.0:
|
|||||||
inherits "^2.0.1"
|
inherits "^2.0.1"
|
||||||
readable-stream "^2.0.0"
|
readable-stream "^2.0.0"
|
||||||
|
|
||||||
|
fs-extra@^9.0.1:
|
||||||
|
version "9.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d"
|
||||||
|
integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==
|
||||||
|
dependencies:
|
||||||
|
at-least-node "^1.0.0"
|
||||||
|
graceful-fs "^4.2.0"
|
||||||
|
jsonfile "^6.0.1"
|
||||||
|
universalify "^2.0.0"
|
||||||
|
|
||||||
fs-minipass@^2.0.0:
|
fs-minipass@^2.0.0:
|
||||||
version "2.1.0"
|
version "2.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb"
|
resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb"
|
||||||
@@ -3331,6 +3435,11 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.2.2
|
|||||||
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb"
|
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb"
|
||||||
integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==
|
integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==
|
||||||
|
|
||||||
|
graceful-fs@^4.1.6, graceful-fs@^4.2.0:
|
||||||
|
version "4.2.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.5.tgz#bc18864a6c9fc7b303f2e2abdb9155ad178fbe29"
|
||||||
|
integrity sha512-kBBSQbz2K0Nyn+31j/w36fUfxkBW9/gfwRWdUY1ULReH3iokVJgddZAFcD1D0xlgTmFxJCbUkUclAlc6/IDJkw==
|
||||||
|
|
||||||
handle-thing@^2.0.0:
|
handle-thing@^2.0.0:
|
||||||
version "2.0.1"
|
version "2.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.1.tgz#857f79ce359580c340d43081cc648970d0bb234e"
|
resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.1.tgz#857f79ce359580c340d43081cc648970d0bb234e"
|
||||||
@@ -3487,6 +3596,11 @@ html-entities@^1.3.1:
|
|||||||
resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-1.3.1.tgz#fb9a1a4b5b14c5daba82d3e34c6ae4fe701a0e44"
|
resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-1.3.1.tgz#fb9a1a4b5b14c5daba82d3e34c6ae4fe701a0e44"
|
||||||
integrity sha512-rhE/4Z3hIhzHAUKbW8jVcCyuT5oJCXXqhN/6mXXVCpzTmvJnoH2HL/bt3EZ6p55jbFJBeAe1ZNpL5BugLujxNA==
|
integrity sha512-rhE/4Z3hIhzHAUKbW8jVcCyuT5oJCXXqhN/6mXXVCpzTmvJnoH2HL/bt3EZ6p55jbFJBeAe1ZNpL5BugLujxNA==
|
||||||
|
|
||||||
|
html-tags@^3.1.0:
|
||||||
|
version "3.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/html-tags/-/html-tags-3.1.0.tgz#7b5e6f7e665e9fb41f30007ed9e0d41e97fb2140"
|
||||||
|
integrity sha512-1qYz89hW3lFDEazhjW0yVAV87lw8lVkrJocr72XmBkMKsoSVJCQx3W8BXsC7hO2qAt8BoVjYjtAcZ9perqGnNg==
|
||||||
|
|
||||||
http-deceiver@^1.2.7:
|
http-deceiver@^1.2.7:
|
||||||
version "1.2.7"
|
version "1.2.7"
|
||||||
resolved "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87"
|
resolved "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87"
|
||||||
@@ -3794,6 +3908,13 @@ is-core-module@^2.0.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
has "^1.0.3"
|
has "^1.0.3"
|
||||||
|
|
||||||
|
is-core-module@^2.1.0:
|
||||||
|
version "2.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.2.0.tgz#97037ef3d52224d85163f5597b2b63d9afed981a"
|
||||||
|
integrity sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ==
|
||||||
|
dependencies:
|
||||||
|
has "^1.0.3"
|
||||||
|
|
||||||
is-data-descriptor@^0.1.4:
|
is-data-descriptor@^0.1.4:
|
||||||
version "0.1.4"
|
version "0.1.4"
|
||||||
resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56"
|
resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56"
|
||||||
@@ -4100,6 +4221,15 @@ json5@^2.1.2:
|
|||||||
dependencies:
|
dependencies:
|
||||||
minimist "^1.2.5"
|
minimist "^1.2.5"
|
||||||
|
|
||||||
|
jsonfile@^6.0.1:
|
||||||
|
version "6.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae"
|
||||||
|
integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==
|
||||||
|
dependencies:
|
||||||
|
universalify "^2.0.0"
|
||||||
|
optionalDependencies:
|
||||||
|
graceful-fs "^4.1.6"
|
||||||
|
|
||||||
jsprim@^1.2.2:
|
jsprim@^1.2.2:
|
||||||
version "1.4.1"
|
version "1.4.1"
|
||||||
resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2"
|
resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2"
|
||||||
@@ -4236,12 +4366,17 @@ lodash.templatesettings@^4.0.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
lodash._reinterpolate "^3.0.0"
|
lodash._reinterpolate "^3.0.0"
|
||||||
|
|
||||||
|
lodash.toarray@^4.4.0:
|
||||||
|
version "4.4.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/lodash.toarray/-/lodash.toarray-4.4.0.tgz#24c4bfcd6b2fba38bfd0594db1179d8e9b656561"
|
||||||
|
integrity sha1-JMS/zWsvuji/0FlNsRedjptlZWE=
|
||||||
|
|
||||||
lodash.uniq@^4.5.0:
|
lodash.uniq@^4.5.0:
|
||||||
version "4.5.0"
|
version "4.5.0"
|
||||||
resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"
|
resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"
|
||||||
integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=
|
integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=
|
||||||
|
|
||||||
lodash@^4.0.0, lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.5, lodash@~4.17.10:
|
lodash@^4.0.0, lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.5, lodash@~4.17.10:
|
||||||
version "4.17.20"
|
version "4.17.20"
|
||||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52"
|
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52"
|
||||||
integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==
|
integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==
|
||||||
@@ -4448,6 +4583,11 @@ mini-css-extract-plugin@^0.8.0:
|
|||||||
schema-utils "^1.0.0"
|
schema-utils "^1.0.0"
|
||||||
webpack-sources "^1.1.0"
|
webpack-sources "^1.1.0"
|
||||||
|
|
||||||
|
mini-svg-data-uri@^1.2.3:
|
||||||
|
version "1.2.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/mini-svg-data-uri/-/mini-svg-data-uri-1.2.3.tgz#e16baa92ad55ddaa1c2c135759129f41910bc39f"
|
||||||
|
integrity sha512-zd6KCAyXgmq6FV1mR10oKXYtvmA9vRoB6xPSTUJTbFApCtkefDnYueVR1gkof3KcdLZo1Y8mjF2DFmQMIxsHNQ==
|
||||||
|
|
||||||
minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1:
|
minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1:
|
||||||
version "1.0.1"
|
version "1.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7"
|
resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7"
|
||||||
@@ -4465,7 +4605,7 @@ minimatch@^3.0.4, minimatch@~3.0.2:
|
|||||||
dependencies:
|
dependencies:
|
||||||
brace-expansion "^1.1.7"
|
brace-expansion "^1.1.7"
|
||||||
|
|
||||||
minimist@^1.1.3, minimist@^1.2.0, minimist@^1.2.5:
|
minimist@^1.1.1, minimist@^1.1.3, minimist@^1.2.0, minimist@^1.2.5:
|
||||||
version "1.2.5"
|
version "1.2.5"
|
||||||
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
|
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
|
||||||
integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
|
integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
|
||||||
@@ -4542,6 +4682,11 @@ mkdirp@^1.0.3, mkdirp@^1.0.4:
|
|||||||
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e"
|
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e"
|
||||||
integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==
|
integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==
|
||||||
|
|
||||||
|
modern-normalize@^1.0.0:
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/modern-normalize/-/modern-normalize-1.0.0.tgz#539d84a1e141338b01b346f3e27396d0ed17601e"
|
||||||
|
integrity sha512-1lM+BMLGuDfsdwf3rsgBSrxJwAZHFIrQ8YR61xIqdHo0uNKI9M52wNpHSrliZATJp51On6JD0AfRxd4YGSU0lw==
|
||||||
|
|
||||||
move-concurrently@^1.0.1:
|
move-concurrently@^1.0.1:
|
||||||
version "1.0.1"
|
version "1.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92"
|
resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92"
|
||||||
@@ -4587,6 +4732,11 @@ nan@^2.12.1, nan@^2.13.2:
|
|||||||
resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.2.tgz#f5376400695168f4cc694ac9393d0c9585eeea19"
|
resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.2.tgz#f5376400695168f4cc694ac9393d0c9585eeea19"
|
||||||
integrity sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==
|
integrity sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==
|
||||||
|
|
||||||
|
nanoid@^3.1.20:
|
||||||
|
version "3.1.20"
|
||||||
|
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.20.tgz#badc263c6b1dcf14b71efaa85f6ab4c1d6cfc788"
|
||||||
|
integrity sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw==
|
||||||
|
|
||||||
nanomatch@^1.2.9:
|
nanomatch@^1.2.9:
|
||||||
version "1.2.13"
|
version "1.2.13"
|
||||||
resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119"
|
resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119"
|
||||||
@@ -4619,6 +4769,13 @@ nice-try@^1.0.4:
|
|||||||
resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366"
|
resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366"
|
||||||
integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==
|
integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==
|
||||||
|
|
||||||
|
node-emoji@^1.8.1:
|
||||||
|
version "1.10.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/node-emoji/-/node-emoji-1.10.0.tgz#8886abd25d9c7bb61802a658523d1f8d2a89b2da"
|
||||||
|
integrity sha512-Yt3384If5H6BYGVHiHwTL+99OzJKHhgp82S8/dktEK73T26BazdgZ4JZh92xSVtGNJvz9UbXdNAc5hcrXV42vw==
|
||||||
|
dependencies:
|
||||||
|
lodash.toarray "^4.4.0"
|
||||||
|
|
||||||
node-forge@^0.10.0:
|
node-forge@^0.10.0:
|
||||||
version "0.10.0"
|
version "0.10.0"
|
||||||
resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.10.0.tgz#32dea2afb3e9926f02ee5ce8794902691a676bf3"
|
resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.10.0.tgz#32dea2afb3e9926f02ee5ce8794902691a676bf3"
|
||||||
@@ -4801,6 +4958,11 @@ object-copy@^0.1.0:
|
|||||||
define-property "^0.2.5"
|
define-property "^0.2.5"
|
||||||
kind-of "^3.0.3"
|
kind-of "^3.0.3"
|
||||||
|
|
||||||
|
object-hash@^2.0.3:
|
||||||
|
version "2.1.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-2.1.1.tgz#9447d0279b4fcf80cff3259bf66a1dc73afabe09"
|
||||||
|
integrity sha512-VOJmgmS+7wvXf8CjbQmimtCnEx3IAoLxI3fp2fbWehxrWBcAQFbk+vcwb6vzR0VZv/eNCJ/27j151ZTwqW/JeQ==
|
||||||
|
|
||||||
object-inspect@^1.8.0:
|
object-inspect@^1.8.0:
|
||||||
version "1.8.0"
|
version "1.8.0"
|
||||||
resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.8.0.tgz#df807e5ecf53a609cc6bfe93eac3cc7be5b3a9d0"
|
resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.8.0.tgz#df807e5ecf53a609cc6bfe93eac3cc7be5b3a9d0"
|
||||||
@@ -5389,6 +5551,16 @@ postcss-font-variant@^4.0.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
postcss "^7.0.2"
|
postcss "^7.0.2"
|
||||||
|
|
||||||
|
postcss-functions@^3:
|
||||||
|
version "3.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/postcss-functions/-/postcss-functions-3.0.0.tgz#0e94d01444700a481de20de4d55fb2640564250e"
|
||||||
|
integrity sha1-DpTQFERwCkgd4g3k1V+yZAVkJQ4=
|
||||||
|
dependencies:
|
||||||
|
glob "^7.1.2"
|
||||||
|
object-assign "^4.1.1"
|
||||||
|
postcss "^6.0.9"
|
||||||
|
postcss-value-parser "^3.3.0"
|
||||||
|
|
||||||
postcss-gap-properties@^2.0.0:
|
postcss-gap-properties@^2.0.0:
|
||||||
version "2.0.0"
|
version "2.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/postcss-gap-properties/-/postcss-gap-properties-2.0.0.tgz#431c192ab3ed96a3c3d09f2ff615960f902c1715"
|
resolved "https://registry.yarnpkg.com/postcss-gap-properties/-/postcss-gap-properties-2.0.0.tgz#431c192ab3ed96a3c3d09f2ff615960f902c1715"
|
||||||
@@ -5422,6 +5594,14 @@ postcss-initial@^3.0.0:
|
|||||||
lodash.template "^4.5.0"
|
lodash.template "^4.5.0"
|
||||||
postcss "^7.0.2"
|
postcss "^7.0.2"
|
||||||
|
|
||||||
|
postcss-js@^2:
|
||||||
|
version "2.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/postcss-js/-/postcss-js-2.0.3.tgz#a96f0f23ff3d08cec7dc5b11bf11c5f8077cdab9"
|
||||||
|
integrity sha512-zS59pAk3deu6dVHyrGqmC3oDXBdNdajk4k1RyxeVXCrcEDBUBHoIhE4QTsmhxgzXxsaqFDAkUZfmMa5f/N/79w==
|
||||||
|
dependencies:
|
||||||
|
camelcase-css "^2.0.1"
|
||||||
|
postcss "^7.0.18"
|
||||||
|
|
||||||
postcss-lab-function@^2.0.1:
|
postcss-lab-function@^2.0.1:
|
||||||
version "2.0.1"
|
version "2.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/postcss-lab-function/-/postcss-lab-function-2.0.1.tgz#bb51a6856cd12289ab4ae20db1e3821ef13d7d2e"
|
resolved "https://registry.yarnpkg.com/postcss-lab-function/-/postcss-lab-function-2.0.1.tgz#bb51a6856cd12289ab4ae20db1e3821ef13d7d2e"
|
||||||
@@ -5558,6 +5738,14 @@ postcss-modules-values@^3.0.0:
|
|||||||
icss-utils "^4.0.0"
|
icss-utils "^4.0.0"
|
||||||
postcss "^7.0.6"
|
postcss "^7.0.6"
|
||||||
|
|
||||||
|
postcss-nested@^4:
|
||||||
|
version "4.2.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/postcss-nested/-/postcss-nested-4.2.3.tgz#c6f255b0a720549776d220d00c4b70cd244136f6"
|
||||||
|
integrity sha512-rOv0W1HquRCamWy2kFl3QazJMMe1ku6rCFoAAH+9AcxdbpDeBr6k968MLWuLjvjMcGEip01ak09hKOEgpK9hvw==
|
||||||
|
dependencies:
|
||||||
|
postcss "^7.0.32"
|
||||||
|
postcss-selector-parser "^6.0.2"
|
||||||
|
|
||||||
postcss-nesting@^7.0.0:
|
postcss-nesting@^7.0.0:
|
||||||
version "7.0.1"
|
version "7.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/postcss-nesting/-/postcss-nesting-7.0.1.tgz#b50ad7b7f0173e5b5e3880c3501344703e04c052"
|
resolved "https://registry.yarnpkg.com/postcss-nesting/-/postcss-nesting-7.0.1.tgz#b50ad7b7f0173e5b5e3880c3501344703e04c052"
|
||||||
@@ -5796,7 +5984,7 @@ postcss-selector-parser@^5.0.0-rc.3, postcss-selector-parser@^5.0.0-rc.4:
|
|||||||
indexes-of "^1.0.1"
|
indexes-of "^1.0.1"
|
||||||
uniq "^1.0.1"
|
uniq "^1.0.1"
|
||||||
|
|
||||||
postcss-selector-parser@^6.0.0, postcss-selector-parser@^6.0.2:
|
postcss-selector-parser@^6.0.0, postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4:
|
||||||
version "6.0.4"
|
version "6.0.4"
|
||||||
resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.4.tgz#56075a1380a04604c38b063ea7767a129af5c2b3"
|
resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.4.tgz#56075a1380a04604c38b063ea7767a129af5c2b3"
|
||||||
integrity sha512-gjMeXBempyInaBqpp8gODmwZ52WaYsVOsfr4L4lDQ7n3ncD6mEyySiDtgzCT+NYC0mmeOLvtsF8iaEf0YT6dBw==
|
integrity sha512-gjMeXBempyInaBqpp8gODmwZ52WaYsVOsfr4L4lDQ7n3ncD6mEyySiDtgzCT+NYC0mmeOLvtsF8iaEf0YT6dBw==
|
||||||
@@ -5825,7 +6013,7 @@ postcss-unique-selectors@^4.0.1:
|
|||||||
postcss "^7.0.0"
|
postcss "^7.0.0"
|
||||||
uniqs "^2.0.0"
|
uniqs "^2.0.0"
|
||||||
|
|
||||||
postcss-value-parser@^3.0.0, postcss-value-parser@^3.2.3:
|
postcss-value-parser@^3.0.0, postcss-value-parser@^3.2.3, postcss-value-parser@^3.3.0:
|
||||||
version "3.3.1"
|
version "3.3.1"
|
||||||
resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz#9ff822547e2893213cf1c30efa51ac5fd1ba8281"
|
resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz#9ff822547e2893213cf1c30efa51ac5fd1ba8281"
|
||||||
integrity sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==
|
integrity sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==
|
||||||
@@ -5844,7 +6032,16 @@ postcss-values-parser@^2.0.0, postcss-values-parser@^2.0.1:
|
|||||||
indexes-of "^1.0.1"
|
indexes-of "^1.0.1"
|
||||||
uniq "^1.0.1"
|
uniq "^1.0.1"
|
||||||
|
|
||||||
postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.14, postcss@^7.0.17, postcss@^7.0.2, postcss@^7.0.26, postcss@^7.0.27, postcss@^7.0.32, postcss@^7.0.5, postcss@^7.0.6:
|
postcss@^6.0.9:
|
||||||
|
version "6.0.23"
|
||||||
|
resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.23.tgz#61c82cc328ac60e677645f979054eb98bc0e3324"
|
||||||
|
integrity sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==
|
||||||
|
dependencies:
|
||||||
|
chalk "^2.4.1"
|
||||||
|
source-map "^0.6.1"
|
||||||
|
supports-color "^5.4.0"
|
||||||
|
|
||||||
|
postcss@^7, postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.14, postcss@^7.0.17, postcss@^7.0.18, postcss@^7.0.2, postcss@^7.0.26, postcss@^7.0.27, postcss@^7.0.32, postcss@^7.0.5, postcss@^7.0.6:
|
||||||
version "7.0.35"
|
version "7.0.35"
|
||||||
resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.35.tgz#d2be00b998f7f211d8a276974079f2e92b970e24"
|
resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.35.tgz#d2be00b998f7f211d8a276974079f2e92b970e24"
|
||||||
integrity sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==
|
integrity sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==
|
||||||
@@ -5853,11 +6050,25 @@ postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.14, postcss@^7.0.17, postcss@^7.0.2
|
|||||||
source-map "^0.6.1"
|
source-map "^0.6.1"
|
||||||
supports-color "^6.1.0"
|
supports-color "^6.1.0"
|
||||||
|
|
||||||
|
postcss@^8.2.1:
|
||||||
|
version "8.2.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.2.5.tgz#3c75149ada4e93db9521913654c0144517f77c9a"
|
||||||
|
integrity sha512-wMcb7BpDcm3gxQOQx46NDNT36Kk0Ao6PJLLI2ed5vehbbbxCEuslSQzbQ2sfSKy+gkYxhWcGWSeaK+gwm4KIZg==
|
||||||
|
dependencies:
|
||||||
|
colorette "^1.2.1"
|
||||||
|
nanoid "^3.1.20"
|
||||||
|
source-map "^0.6.1"
|
||||||
|
|
||||||
prepend-http@^1.0.0:
|
prepend-http@^1.0.0:
|
||||||
version "1.0.4"
|
version "1.0.4"
|
||||||
resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc"
|
resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc"
|
||||||
integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=
|
integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=
|
||||||
|
|
||||||
|
pretty-hrtime@^1.0.3:
|
||||||
|
version "1.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz#b7e3ea42435a4c9b2759d99e0f201eb195802ee1"
|
||||||
|
integrity sha1-t+PqQkNaTJsnWdmeDyAesZWALuE=
|
||||||
|
|
||||||
process-nextick-args@~2.0.0:
|
process-nextick-args@~2.0.0:
|
||||||
version "2.0.1"
|
version "2.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2"
|
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2"
|
||||||
@@ -5948,6 +6159,16 @@ punycode@^2.1.0, punycode@^2.1.1:
|
|||||||
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
|
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
|
||||||
integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==
|
integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==
|
||||||
|
|
||||||
|
purgecss@^3.1.3:
|
||||||
|
version "3.1.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/purgecss/-/purgecss-3.1.3.tgz#26987ec09d12eeadc318e22f6e5a9eb0be094f41"
|
||||||
|
integrity sha512-hRSLN9mguJ2lzlIQtW4qmPS2kh6oMnA9RxdIYK8sz18QYqd6ePp4GNDl18oWHA1f2v2NEQIh51CO8s/E3YGckQ==
|
||||||
|
dependencies:
|
||||||
|
commander "^6.0.0"
|
||||||
|
glob "^7.0.0"
|
||||||
|
postcss "^8.2.1"
|
||||||
|
postcss-selector-parser "^6.0.2"
|
||||||
|
|
||||||
q@^1.1.2:
|
q@^1.1.2:
|
||||||
version "1.5.1"
|
version "1.5.1"
|
||||||
resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7"
|
resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7"
|
||||||
@@ -6086,6 +6307,14 @@ redent@^1.0.0:
|
|||||||
indent-string "^2.1.0"
|
indent-string "^2.1.0"
|
||||||
strip-indent "^1.0.1"
|
strip-indent "^1.0.1"
|
||||||
|
|
||||||
|
reduce-css-calc@^2.1.6:
|
||||||
|
version "2.1.8"
|
||||||
|
resolved "https://registry.yarnpkg.com/reduce-css-calc/-/reduce-css-calc-2.1.8.tgz#7ef8761a28d614980dc0c982f772c93f7a99de03"
|
||||||
|
integrity sha512-8liAVezDmUcH+tdzoEGrhfbGcP7nOV4NkGE3a74+qqvE7nt9i4sKLGBuZNOnpI4WiGksiNPklZxva80061QiPg==
|
||||||
|
dependencies:
|
||||||
|
css-unit-converter "^1.1.1"
|
||||||
|
postcss-value-parser "^3.3.0"
|
||||||
|
|
||||||
regenerate-unicode-properties@^8.2.0:
|
regenerate-unicode-properties@^8.2.0:
|
||||||
version "8.2.0"
|
version "8.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz#e5de7111d655e7ba60c057dbe9ff37c87e65cdec"
|
resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz#e5de7111d655e7ba60c057dbe9ff37c87e65cdec"
|
||||||
@@ -6251,6 +6480,14 @@ resolve@^1.1.7, resolve@^1.10.0, resolve@^1.12.0, resolve@^1.3.2, resolve@^1.8.1
|
|||||||
is-core-module "^2.0.0"
|
is-core-module "^2.0.0"
|
||||||
path-parse "^1.0.6"
|
path-parse "^1.0.6"
|
||||||
|
|
||||||
|
resolve@^1.19.0:
|
||||||
|
version "1.19.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.19.0.tgz#1af5bf630409734a067cae29318aac7fa29a267c"
|
||||||
|
integrity sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==
|
||||||
|
dependencies:
|
||||||
|
is-core-module "^2.1.0"
|
||||||
|
path-parse "^1.0.6"
|
||||||
|
|
||||||
ret@~0.1.10:
|
ret@~0.1.10:
|
||||||
version "0.1.15"
|
version "0.1.15"
|
||||||
resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc"
|
resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc"
|
||||||
@@ -6906,7 +7143,7 @@ supports-color@^2.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"
|
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"
|
||||||
integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=
|
integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=
|
||||||
|
|
||||||
supports-color@^5.3.0:
|
supports-color@^5.3.0, supports-color@^5.4.0:
|
||||||
version "5.5.0"
|
version "5.5.0"
|
||||||
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f"
|
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f"
|
||||||
integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==
|
integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==
|
||||||
@@ -6920,7 +7157,7 @@ supports-color@^6.1.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
has-flag "^3.0.0"
|
has-flag "^3.0.0"
|
||||||
|
|
||||||
supports-color@^7.0.0:
|
supports-color@^7.0.0, supports-color@^7.1.0:
|
||||||
version "7.2.0"
|
version "7.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da"
|
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da"
|
||||||
integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==
|
integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==
|
||||||
@@ -6946,6 +7183,34 @@ svgo@^1.0.0:
|
|||||||
unquote "~1.1.1"
|
unquote "~1.1.1"
|
||||||
util.promisify "~1.0.0"
|
util.promisify "~1.0.0"
|
||||||
|
|
||||||
|
"tailwindcss@npm:@tailwindcss/postcss7-compat":
|
||||||
|
version "2.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@tailwindcss/postcss7-compat/-/postcss7-compat-2.0.2.tgz#49cb21703dfb4447620fceab5cef3285cff8c69d"
|
||||||
|
integrity sha512-KM8kjG5dd8qoXBX2a6r3r1TOqhFh8NtFBheG9qpVPwSjrD8wRdoM7s+Xz56HEA1XmeN64gEKqjmY6vm55DiS3Q==
|
||||||
|
dependencies:
|
||||||
|
"@fullhuman/postcss-purgecss" "^3.0.0"
|
||||||
|
autoprefixer "^9"
|
||||||
|
bytes "^3.0.0"
|
||||||
|
chalk "^4.1.0"
|
||||||
|
color "^3.1.3"
|
||||||
|
detective "^5.2.0"
|
||||||
|
didyoumean "^1.2.1"
|
||||||
|
fs-extra "^9.0.1"
|
||||||
|
html-tags "^3.1.0"
|
||||||
|
lodash "^4.17.20"
|
||||||
|
modern-normalize "^1.0.0"
|
||||||
|
node-emoji "^1.8.1"
|
||||||
|
object-hash "^2.0.3"
|
||||||
|
postcss "^7"
|
||||||
|
postcss-functions "^3"
|
||||||
|
postcss-js "^2"
|
||||||
|
postcss-nested "^4"
|
||||||
|
postcss-selector-parser "^6.0.4"
|
||||||
|
postcss-value-parser "^4.1.0"
|
||||||
|
pretty-hrtime "^1.0.3"
|
||||||
|
reduce-css-calc "^2.1.6"
|
||||||
|
resolve "^1.19.0"
|
||||||
|
|
||||||
tapable@^1.0.0, tapable@^1.1.3:
|
tapable@^1.0.0, tapable@^1.1.3:
|
||||||
version "1.1.3"
|
version "1.1.3"
|
||||||
resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2"
|
resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2"
|
||||||
@@ -7205,6 +7470,11 @@ unique-slug@^2.0.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
imurmurhash "^0.1.4"
|
imurmurhash "^0.1.4"
|
||||||
|
|
||||||
|
universalify@^2.0.0:
|
||||||
|
version "2.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717"
|
||||||
|
integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==
|
||||||
|
|
||||||
unpipe@1.0.0, unpipe@~1.0.0:
|
unpipe@1.0.0, unpipe@~1.0.0:
|
||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec"
|
resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec"
|
||||||
@@ -7555,7 +7825,7 @@ ws@^6.2.1:
|
|||||||
dependencies:
|
dependencies:
|
||||||
async-limiter "~1.0.0"
|
async-limiter "~1.0.0"
|
||||||
|
|
||||||
xtend@^4.0.0, xtend@~4.0.1:
|
xtend@^4.0.0, xtend@^4.0.2, xtend@~4.0.1:
|
||||||
version "4.0.2"
|
version "4.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54"
|
resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54"
|
||||||
integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==
|
integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==
|
||||||
|
|||||||
Reference in New Issue
Block a user