Compare commits

..

291 Commits

Author SHA1 Message Date
Karol Wypchło 3da3cf949f
Merge pull request #2255 from SkynetLabs/renovate/skynetlabs-webportal-health-check-1.x
chore(deps): update skynetlabs/webportal-health-check docker tag to v1
2022-10-06 01:47:34 +02:00
renovate[bot] 15d5d7c0d7
chore(deps): update skynetlabs/webportal-health-check docker tag to v1 2022-10-05 23:46:59 +00:00
Karol Wypchło 9559ec160c
Merge pull request #2254 from SkynetLabs/renovate/skynetlabs-webportal-health-check-0.x
chore(deps): update skynetlabs/webportal-health-check docker tag to v0.5.4
2022-10-05 21:07:44 +02:00
renovate[bot] f21f718c13
chore(deps): update skynetlabs/webportal-health-check docker tag to v0.5.4 2022-10-05 19:04:22 +00:00
Karol Wypchło f1ac4c5653
Merge pull request #2252 from SkynetLabs/renovate/certbot-dns-route53-1.x
chore(deps): update certbot/dns-route53 docker tag to v1.31.0
2022-10-05 09:56:53 +02:00
Karol Wypchło 17ea999288
Merge pull request #2253 from SkynetLabs/renovate/jaegertracing
chore(deps): update jaegertracing to v1.38.1
2022-10-05 09:56:13 +02:00
renovate[bot] f91cb72db7
chore(deps): update jaegertracing to v1.38.1 2022-10-05 01:35:25 +00:00
renovate[bot] f83f3cefe8
chore(deps): update certbot/dns-route53 docker tag to v1.31.0 2022-10-04 17:18:21 +00:00
Karol Wypchło e63fcbecb7
Merge pull request #2251 from SkynetLabs/renovate/mongo-4.x
chore(deps): update mongo docker tag to v4.4.17
2022-09-30 10:37:37 +02:00
Karol Wypchło 5ff2f5891e
Merge pull request #2250 from SkynetLabs/delete-skylink-dumps-older-than-week
delete skylink dumps older than week
2022-09-30 10:29:44 +02:00
renovate[bot] b7afcd1feb
chore(deps): update mongo docker tag to v4.4.17 2022-09-29 23:10:43 +00:00
Karol Wypchlo ba106d69f2
delete skylink dumps older than week 2022-09-29 19:48:59 +02:00
Karol Wypchło 8ce5c9d7e6
Merge pull request #2246 from SkynetLabs/amend-skyd-logrotate-and-add-pinner
Amend skyd logrotate and add pinner
2022-09-27 13:18:14 +02:00
Karol Wypchlo b2313c602a
new pinner logrotate config 2022-09-26 11:30:24 +02:00
Karol Wypchlo 2ea337a3b0
change skyd logrotate to copytruncate 2022-09-26 11:30:13 +02:00
Karol Wypchło 919d22b314
Merge pull request #2245 from SkynetLabs/renovate/skynetlabs-pinner-0.x
chore(deps): update skynetlabs/pinner docker tag to v0.7.8
2022-09-23 14:30:13 +02:00
renovate[bot] 983602e5aa
chore(deps): update skynetlabs/pinner docker tag to v0.7.8 2022-09-23 12:26:22 +00:00
Karol Wypchło bb8485b1cc
Merge pull request #2244 from SkynetLabs/renovate/skynetlabs-pinner-0.x
chore(deps): update skynetlabs/pinner docker tag to v0.7.7
2022-09-22 15:25:33 +02:00
renovate[bot] 91e8fad3b1
chore(deps): update skynetlabs/pinner docker tag to v0.7.7 2022-09-22 13:23:36 +00:00
Karol Wypchło 74b72f4f47
add skynet-webportal-skyd logrotate config 2022-09-22 12:33:47 +02:00
Karol Wypchło a940f2728f
add skynet-webportal-nginx logrotate config 2022-09-22 12:33:16 +02:00
Karol Wypchło 634c623e48
Merge pull request #2243 from SkynetLabs/revert-2237-logrotated
Revert "logrotate.d configuration"
2022-09-22 12:18:27 +02:00
Karol Wypchło d926c22aa4
Revert "logrotate.d configuration" 2022-09-22 12:13:09 +02:00
Karol Wypchło 9958b66faf
Merge pull request #2236 from SkynetLabs/remove-deploy-configuration
remove deploy configuration
2022-09-21 14:03:15 +02:00
Karol Wypchło 8381555ce7
Merge pull request #2237 from SkynetLabs/logrotated
logrotate.d configuration
2022-09-21 14:02:16 +02:00
Karol Wypchło 94860262a5
Merge pull request #2240 from SkynetLabs/renovate/skynetlabs-webportal-handshake-api-0.x
chore(deps): update skynetlabs/webportal-handshake-api docker tag to v0.1.3
2022-09-21 14:00:56 +02:00
Karol Wypchło c4243968e1
Merge pull request #2238 from SkynetLabs/revert-1428-sevey/mute-more-pings
Revert "Mute check failures unless server is down"
2022-09-21 14:00:47 +02:00
Karol Wypchło c49cb57315
Merge pull request #2239 from SkynetLabs/renovate/skynetlabs-webportal-dnslink-api-0.x
chore(deps): update skynetlabs/webportal-dnslink-api docker tag to v0.2.1
2022-09-21 14:00:39 +02:00
Karol Wypchło 1334537729
Merge pull request #2241 from SkynetLabs/renovate/skynetlabs-webportal-health-check-0.x
chore(deps): update skynetlabs/webportal-health-check docker tag to v0.5.1
2022-09-21 14:00:24 +02:00
Karol Wypchło 823efb2238
Merge pull request #2242 from SkynetLabs/renovate/skynetlabs-webportal-website-0.x
chore(deps): update skynetlabs/webportal-website docker tag to v0.2.3
2022-09-21 13:59:43 +02:00
renovate[bot] b3c300d7bf
chore(deps): update skynetlabs/webportal-website docker tag to v0.2.3 2022-09-21 11:51:34 +00:00
renovate[bot] 89a263bfc6
chore(deps): update skynetlabs/webportal-health-check docker tag to v0.5.1 2022-09-21 11:51:30 +00:00
renovate[bot] d5cc81f934
chore(deps): update skynetlabs/webportal-handshake-api docker tag to v0.1.3 2022-09-21 11:51:25 +00:00
renovate[bot] 1f0d66a33a
chore(deps): update skynetlabs/webportal-dnslink-api docker tag to v0.2.1 2022-09-21 11:51:20 +00:00
Karol Wypchło 686e20b8a3
use best gzip compression 2022-09-21 13:22:04 +02:00
Karol Wypchło 70b80bb072
use best gzip compression 2022-09-21 13:21:50 +02:00
Karol Wypchło 167a56383f
use best gzip compression 2022-09-21 13:21:27 +02:00
Karol Wypchło c054ffb0ea
Revert "Mute check failures unless server is down" 2022-09-20 15:18:34 +02:00
Karol Wypchlo 17e4d782ca
no need to logrotate 3 levels deep 2022-09-20 14:46:03 +02:00
Karol Wypchlo 4b52d3c671
logrotate.d 2022-09-20 13:51:40 +02:00
Karol Wypchlo c85d788939
remove deploy configuration 2022-09-19 15:16:57 +02:00
Karol Wypchło e4cd4bf991
Merge pull request #2235 from SkynetLabs/renovate/jaegertracing
chore(deps): update jaegertracing to v1.38.0
2022-09-19 12:49:24 +02:00
renovate[bot] 263b733480
chore(deps): update jaegertracing to v1.38.0 2022-09-16 15:26:08 +00:00
Ivaylo Novakov 7ddec93e59
Merge pull request #2232 from SkynetLabs/remove-outdated-readme-info
remove outdated readme info
2022-09-14 14:12:11 +02:00
Christopher Schinnerl ac7942640f
Merge pull request #2231 from SkynetLabs/cleanup-setup-scripts
remove outdated scripts
2022-09-14 14:08:13 +02:00
Christopher Schinnerl 46f8ef0836
Merge branch 'master' into remove-outdated-readme-info 2022-09-14 14:05:46 +02:00
Karol Wypchlo 63323685cc
bring back up and down scripts 2022-09-14 11:29:46 +02:00
Ivaylo Novakov e281e9ca78
Merge branch 'master' into cleanup-setup-scripts 2022-09-14 11:07:12 +02:00
Karol Wypchlo d753be9383
remove more unused scripts 2022-09-13 17:12:45 +02:00
Karol Wypchło bcb0c0cf24
Merge pull request #2233 from SkynetLabs/renovate/skynetlabs-pinner-0.x
chore(deps): update skynetlabs/pinner docker tag to v0.7.6
2022-09-13 16:18:44 +02:00
Karol Wypchło 47046ab31e
Merge pull request #2234 from SkynetLabs/renovate/skynetlabs-skyd-1.x
chore(deps): update skynetlabs/skyd docker tag to v1.6.9
2022-09-13 16:18:28 +02:00
renovate[bot] be8359791e
chore(deps): update skynetlabs/skyd docker tag to v1.6.9 2022-09-13 14:06:35 +00:00
renovate[bot] 4689844014
chore(deps): update skynetlabs/pinner docker tag to v0.7.6 2022-09-13 14:06:30 +00:00
Karol Wypchło 1d1096fd3b
remove outdated readme info 2022-09-13 13:45:49 +02:00
Karol Wypchlo 08c21cafe4
remove outdated setup scripts 2022-09-13 13:39:00 +02:00
Ivaylo Novakov 378ce234dc
Merge pull request #2230 from SkynetLabs/renovate/skynetlabs-webportal-accounts-dashboard-2.x
chore(deps): update skynetlabs/webportal-accounts-dashboard docker tag to v2.1.1
2022-09-13 13:02:14 +02:00
renovate[bot] 3f66dd30dd
chore(deps): update skynetlabs/webportal-accounts-dashboard docker tag to v2.1.1 2022-09-13 10:44:12 +00:00
Karol Wypchło 1c3bcbc063
Update authorized_keys 2022-09-13 12:08:01 +02:00
Ivaylo Novakov 4ccbd351f5
Merge pull request #2229 from SkynetLabs/renovate/skynetlabs-webportal-nginx-1.x
chore(deps): update skynetlabs/webportal-nginx docker tag to v1
2022-09-13 11:13:28 +02:00
Ivaylo Novakov 00a1481091
Merge branch 'master' into renovate/skynetlabs-webportal-nginx-1.x 2022-09-13 11:12:58 +02:00
Ivaylo Novakov e566dad718
Merge pull request #2228 from SkynetLabs/renovate/skynetlabs-webportal-dnslink-api-0.x
chore(deps): update skynetlabs/webportal-dnslink-api docker tag to v0.2.0
2022-09-13 11:12:45 +02:00
renovate[bot] 2ec8b1bdec
chore(deps): update skynetlabs/webportal-nginx docker tag to v1 2022-09-12 10:23:43 +00:00
renovate[bot] 72e7de53db
chore(deps): update skynetlabs/webportal-dnslink-api docker tag to v0.2.0 2022-09-12 10:23:38 +00:00
Ivaylo Novakov cb81ff738b
Merge pull request #2178 from SkynetLabs/pj/abuse-scanner-updates
Update abuse-scanner compose file
2022-09-08 11:11:53 +02:00
Ivaylo Novakov 9477ae03a5
Merge pull request #2227 from SkynetLabs/renovate/certbot-dns-route53-1.x
chore(deps): update certbot/dns-route53 docker tag to v1.30.0
2022-09-08 11:10:54 +02:00
renovate[bot] 88bd55fe64
chore(deps): update certbot/dns-route53 docker tag to v1.30.0 2022-09-07 20:33:02 +00:00
PJ 2de3d03cd0
Bump image tag 2022-09-01 14:58:21 +02:00
PJ 47175686db
Update docker-compose file 2022-09-01 12:54:03 +02:00
Christopher Schinnerl b510f2e5c3
Merge pull request #2225 from SkynetLabs/renovate/skynetlabs-skyd-1.x
chore(deps): update skynetlabs/skyd docker tag to v1.6.8
2022-08-30 17:42:54 +02:00
renovate[bot] be3db7aa0f
chore(deps): update skynetlabs/skyd docker tag to v1.6.8 2022-08-30 15:41:47 +00:00
Christopher Schinnerl fd1dfb2185
Merge pull request #2224 from SkynetLabs/renovate/skynetlabs-pinner-0.x
chore(deps): update skynetlabs/pinner docker tag to v0.7.5
2022-08-30 14:34:19 +02:00
renovate[bot] 7e0f429ec4
chore(deps): update skynetlabs/pinner docker tag to v0.7.5 2022-08-30 12:05:23 +00:00
Christopher Schinnerl 61cd003013
Merge pull request #2223 from SkynetLabs/renovate/skynetlabs-pinner-0.x
chore(deps): update skynetlabs/pinner docker tag to v0.7.4
2022-08-25 17:31:58 +02:00
renovate[bot] 9d728b1855
chore(deps): update skynetlabs/pinner docker tag to v0.7.4 2022-08-25 15:18:37 +00:00
Karol Wypchło 681d0d95bc
Merge pull request #2222 from SkynetLabs/renovate/skynetlabs-webportal-website-0.x
chore(deps): update skynetlabs/webportal-website docker tag to v0.2.2
2022-08-25 16:50:36 +02:00
renovate[bot] 739b96cd5a
chore(deps): update skynetlabs/webportal-website docker tag to v0.2.2 2022-08-25 14:47:45 +00:00
Ivaylo Novakov e629e7bc7f
Merge pull request #2214 from SkynetLabs/ivo/jaeger_clean
Use Jaeger's own cleanup container
2022-08-25 13:37:22 +02:00
Karol Wypchło 7d33fbd93f
Merge pull request #2220 from SkynetLabs/renovate/skynetlabs-pinner-0.x
chore(deps): update skynetlabs/pinner docker tag to v0.7.3
2022-08-25 13:35:45 +02:00
renovate[bot] 500fb3bfd7
chore(deps): update skynetlabs/pinner docker tag to v0.7.3 2022-08-25 11:35:12 +00:00
Karol Wypchło fd53ef99c1
Merge pull request #2219 from SkynetLabs/renovate/skynetlabs-skyd-1.x
chore(deps): update skynetlabs/skyd docker tag to v1.6.7
2022-08-25 10:43:00 +02:00
renovate[bot] 9964e276fc
chore(deps): update skynetlabs/skyd docker tag to v1.6.7 2022-08-25 08:42:26 +00:00
Karol Wypchło e378e3adf9
Merge pull request #2215 from SkynetLabs/renovate/docker.elastic.co-elasticsearch-elasticsearch-7.x
chore(deps): update docker.elastic.co/elasticsearch/elasticsearch docker tag to v7.17.6
2022-08-24 18:13:03 +02:00
Karol Wypchło 1caaebbefe
Merge pull request #2216 from SkynetLabs/renovate/skynetlabs-pinner-0.x
chore(deps): update skynetlabs/pinner docker tag to v0.7.2
2022-08-24 18:12:37 +02:00
Karol Wypchło a6403b94c1
Merge pull request #2217 from SkynetLabs/renovate/skynetlabs-webportal-nginx-0.x
chore(deps): update skynetlabs/webportal-nginx docker tag to v0.5.2
2022-08-24 18:12:19 +02:00
renovate[bot] 0e841cacda
chore(deps): update skynetlabs/webportal-nginx docker tag to v0.5.2 2022-08-24 15:48:09 +00:00
renovate[bot] 185fc811fb
chore(deps): update skynetlabs/pinner docker tag to v0.7.2 2022-08-24 15:48:04 +00:00
renovate[bot] eacdd78cc1
chore(deps): update docker.elastic.co/elasticsearch/elasticsearch docker tag to v7.17.6 2022-08-24 15:47:51 +00:00
Matthew Sevey 9ca5c48629
Merge pull request #2211 from SkynetLabs/renovate/skynetlabs-webportal-handshake-api-0.x
chore(deps): update skynetlabs/webportal-handshake-api docker tag to v0.1.2
2022-08-23 10:06:54 -04:00
Matthew Sevey 0aeb98ff76
Merge branch 'master' into renovate/skynetlabs-webportal-handshake-api-0.x 2022-08-23 10:04:41 -04:00
Matthew Sevey dfb5e32db5
Merge pull request #2212 from SkynetLabs/renovate/skynetlabs-webportal-health-check-0.x
chore(deps): update skynetlabs/webportal-health-check docker tag to v0.5.0
2022-08-23 10:04:23 -04:00
Ivaylo Novakov 4a7ea93076
Cron is not a TTY. 2022-08-22 12:26:54 +02:00
Ivaylo Novakov 89f7b96d5e
Replace our in-house Jaeger cleanup script with their own container that does that. 2022-08-22 12:09:43 +02:00
Ivaylo Novakov 475bcc310a
Merge pull request #2213 from SkynetLabs/renovate/mongo-4.x
chore(deps): update mongo docker tag to v4.4.16
2022-08-22 11:57:08 +02:00
renovate[bot] d24edc4285
chore(deps): update mongo docker tag to v4.4.16 2022-08-20 01:41:23 +00:00
renovate[bot] d1e0ee0fe6
chore(deps): update skynetlabs/webportal-health-check docker tag to v0.5.0 2022-08-19 17:21:24 +00:00
renovate[bot] ffd9af803a
chore(deps): update skynetlabs/webportal-handshake-api docker tag to v0.1.2 2022-08-19 17:21:19 +00:00
Christopher Schinnerl 655851cb69
Merge pull request #2208 from SkynetLabs/renovate/skynetlabs-skyd-1.x
chore(deps): update skynetlabs/skyd docker tag to v1.6.6
2022-08-18 17:45:23 +02:00
renovate[bot] 61e9d3170d
chore(deps): update skynetlabs/skyd docker tag to v1.6.6 2022-08-18 15:43:16 +00:00
Ivaylo Novakov 47cd62f793
Merge pull request #2203 from SkynetLabs/renovate/skynetlabs-pinner-0.x
chore(deps): update skynetlabs/pinner docker tag to v0.7.1
2022-08-18 17:25:52 +02:00
renovate[bot] 36d65fadc8
chore(deps): update skynetlabs/pinner docker tag to v0.7.1 2022-08-18 15:25:26 +00:00
Ivaylo Novakov 96d876b1d2
Merge pull request #2207 from SkynetLabs/renovate/skynetlabs-webportal-health-check-0.x
chore(deps): update skynetlabs/webportal-health-check docker tag to v0.4.0
2022-08-18 17:24:52 +02:00
renovate[bot] 8414d9b793
chore(deps): update skynetlabs/webportal-health-check docker tag to v0.4.0 2022-08-18 15:12:37 +00:00
Ivaylo Novakov c70bc4b953
Merge pull request #2206 from SkynetLabs/do-not-report-when-env-file-does-not-exist
do not report from dc when env file does not exist
2022-08-18 12:00:17 +02:00
Karol Wypchlo 169ca25d67
do not report from dc when env file does not exist 2022-08-16 10:36:54 +02:00
Karol Wypchło 36f37e9be8
Merge pull request #2205 from SkynetLabs/ivo/fix_dc
Fix the path at which `dc` looks for `.env`.
2022-08-16 10:24:25 +02:00
Ivaylo Novakov ab4468ebf5
Fix the path at which `dc` looks for `.env`. 2022-08-16 10:12:11 +02:00
Matthew Sevey e35a0c8354
Merge pull request #2204 from SkynetLabs/ivo/new_pinner
New pinner version.
2022-08-15 14:21:44 -04:00
Ivaylo Novakov 350d2e30fa
New pinner version. 2022-08-15 20:04:51 +02:00
Matthew Sevey 7deaf1c0b9
Merge pull request #2202 from SkynetLabs/allow-relative-call-to-dc-script
allow relative call to dc script
2022-08-15 09:47:59 -04:00
Ivaylo Novakov fd41aa0518
Merge pull request #2192 from SkynetLabs/remove-outdated-blocklist-scripts
remove outdated blocklist scripts
2022-08-15 10:30:47 +02:00
Karol Wypchło 5e1fd0dcf1
Merge branch 'master' into allow-relative-call-to-dc-script 2022-08-12 22:06:47 +02:00
Karol Wypchlo 063f0b0b7b
simplify script and add more information 2022-08-12 21:06:04 +02:00
Matthew Sevey fea1366075
Merge pull request #2201 from SkynetLabs/upgrade-docker-compose-version
upgrade docker compose to 3.8
2022-08-12 10:10:01 -04:00
Karol Wypchlo 747bc1659a
allow relative call to dc script 2022-08-11 23:29:27 +02:00
Karol Wypchlo ad423e9050
upgrade to 3.8 2022-08-11 23:13:03 +02:00
Karol Wypchło 259b25c8c1
Merge pull request #2193 from SkynetLabs/renovate/skynetlabs-skyd-1.x
chore(deps): update dependency skynetlabs/skyd to v1.6.5
2022-08-09 16:08:25 +02:00
renovate[bot] ed8a2e1f17
chore(deps): update dependency skynetlabs/skyd to v1.6.5 2022-08-09 14:06:38 +00:00
Karol Wypchlo e53a8ba46a
remove airtable blocklist scripts 2022-08-09 15:06:20 +02:00
Karol Wypchlo 9e1a8600a5
Revert "remove outdated blocklist scripts"
This reverts commit 0a26516bdf.
2022-08-09 15:05:11 +02:00
Karol Wypchlo 0a26516bdf
remove outdated blocklist scripts 2022-08-09 14:23:06 +02:00
Karol Wypchło 08dae2e238
Merge pull request #2191 from SkynetLabs/renovate/skynetlabs-webportal-nginx-0.x
chore(deps): update dependency skynetlabs/webportal-nginx to v0.5.1
2022-08-09 13:46:12 +02:00
renovate[bot] 1b1ecb2c11
chore(deps): update dependency skynetlabs/webportal-nginx to v0.5.1 2022-08-09 11:38:19 +00:00
Christopher Schinnerl 088bef8937
Merge pull request #2190 from SkynetLabs/add-args-to-skyd-example
add args to skyd service example
2022-08-09 10:24:19 +02:00
Karol Wypchlo 43d1da72fb
add args to skyd service example 2022-08-09 10:23:04 +02:00
Karol Wypchło 67313136df
Merge pull request #2189 from SkynetLabs/renovate/skynetlabs-pinner-0.x
chore(deps): update dependency skynetlabs/pinner to v0.6.0
2022-08-05 16:25:15 +02:00
Karol Wypchło 60d767cf69
Merge pull request #2188 from SkynetLabs/renovate/skynetlabs-webportal-dnslink-api-0.x
chore(deps): update dependency skynetlabs/webportal-dnslink-api to v0.1.2
2022-08-05 16:25:06 +02:00
renovate[bot] 7a34fc914d
chore(deps): update dependency skynetlabs/pinner to v0.6.0 2022-08-05 14:24:20 +00:00
renovate[bot] d85f24428b
chore(deps): update dependency skynetlabs/webportal-dnslink-api to v0.1.2 2022-08-05 14:24:13 +00:00
Matthew Sevey d6a6f4f878
Merge pull request #2185 from SkynetLabs/karol/sky-1397-switch-to-using-docker-skyd-image-in
use skynetlabs/skyd image
2022-08-05 10:16:49 -04:00
Karol Wypchło c8ff1fb7f4
bump to v1.6.4 2022-08-05 16:14:20 +02:00
Karol Wypchło a63689ed53
Merge pull request #2186 from SkynetLabs/renovate/jaegertracing
chore(deps): update jaegertracing to v1.37.0
2022-08-05 16:01:56 +02:00
renovate[bot] 63465b930e
chore(deps): update jaegertracing to v1.37.0 2022-08-03 21:02:43 +00:00
Karol Wypchlo a7c18b85c1
use skynetlabs/skyd:1.6.3 2022-08-01 16:52:32 +02:00
Ivaylo Novakov fb2ba712f4
Merge pull request #2183 from SkynetLabs/renovate/skynetlabs-webportal-accounts-dashboard-2.x
chore(deps): update dependency skynetlabs/webportal-accounts-dashboard to v2.1.0
2022-08-01 16:37:23 +02:00
Ivaylo Novakov 7e2d69cc9f
Merge pull request #2182 from SkynetLabs/renovate/skynetlabs-skynet-accounts-1.x
chore(deps): update dependency skynetlabs/skynet-accounts to v1.3.0
2022-08-01 16:36:58 +02:00
Ivaylo Novakov 591ef6ab69
Merge pull request #2181 from SkynetLabs/renovate/skynetlabs-pinner-0.x
chore(deps): update dependency skynetlabs/pinner to v0.5.0
2022-08-01 16:36:36 +02:00
Ivaylo Novakov 649914dc18
Merge pull request #2180 from SkynetLabs/renovate/skynetlabs-webportal-nginx-0.x
chore(deps): update dependency skynetlabs/webportal-nginx to v0.5.0
2022-08-01 16:36:02 +02:00
Karol Wypchlo aa0a91472b
use skynetlabs/skyd:1.6.2 2022-08-01 13:48:58 +02:00
renovate[bot] 45feb45d31
chore(deps): update dependency skynetlabs/webportal-accounts-dashboard to v2.1.0 2022-08-01 10:55:23 +00:00
renovate[bot] 1f13674785
chore(deps): update dependency skynetlabs/skynet-accounts to v1.3.0 2022-08-01 10:55:18 +00:00
renovate[bot] ad743b3a3d
chore(deps): update dependency skynetlabs/pinner to v0.5.0 2022-08-01 10:55:13 +00:00
renovate[bot] a78f1d2745
chore(deps): update dependency skynetlabs/webportal-nginx to v0.5.0 2022-07-29 12:10:54 +00:00
Karol Wypchło a41ea10f64
upgrade to handshakeorg/hsd:4.0.2 (#2179)
* use handshakeorg/hsd:4.0.2

* add --no-auth
2022-07-29 12:05:01 +02:00
PJ 82e869bf34
Update abuse-scanner compose file 2022-07-27 16:06:37 +02:00
Ivaylo Novakov c7d445e44a
Merge pull request #2177 from SkynetLabs/ivo/log_hsd
Show HSD logs by default.
2022-07-25 19:48:04 +02:00
Ivaylo Novakov 61f153efe6
Remove the var altogether. 2022-07-25 20:03:41 +03:00
Ivaylo Novakov 03df7c7b33
Show HSD logs by default. 2022-07-25 19:28:56 +03:00
Ivaylo Novakov deaf20306a
Merge pull request #2164 from SkynetLabs/improve-certbot-docs
add readme note about certbot plugin
2022-07-25 12:39:46 +02:00
Karol Wypchło 4ca5bb397e
Merge pull request #2176 from SkynetLabs/remove-codeql
remove codeql
2022-07-20 11:57:18 +02:00
Karol Wypchło f6fbf4242d
remove codeql 2022-07-19 10:51:28 +02:00
Michał Leszczyk 453f1210ab
Merge pull request #2175 from SkynetLabs/renovate/skynetlabs-webportal-nginx-0.x
chore(deps): update dependency skynetlabs/webportal-nginx to v0.4.0
2022-07-11 11:42:46 +02:00
renovate[bot] b636894aa2
chore(deps): update dependency skynetlabs/webportal-nginx to v0.4.0 2022-07-11 09:41:30 +00:00
Michał Leszczyk fb75018ce0
Merge pull request #2172 from SkynetLabs/renovate/skynetlabs-webportal-health-check-0.x
chore(deps): update dependency skynetlabs/webportal-health-check to v0.3.0
2022-07-11 11:09:03 +02:00
Michał Leszczyk 8ca17995e2
Merge pull request #2173 from SkynetLabs/renovate/skynetlabs-pinner-0.x
chore(deps): update dependency skynetlabs/pinner to v0.4.1
2022-07-11 11:07:29 +02:00
Michał Leszczyk dd74ad8b3b
Merge pull request #2174 from SkynetLabs/renovate/skynetlabs-webportal-accounts-dashboard-2.x
chore(deps): update dependency skynetlabs/webportal-accounts-dashboard to v2
2022-07-11 11:07:09 +02:00
Michał Leszczyk d13a4ae154
Don't pass GATSBY_ env vars to dashboard anymore (#2163)
* Don't pass GATSBY_ env vars to dashboard anymore

* Bump dashboard image to 2.0.0
2022-07-11 11:03:19 +02:00
renovate[bot] 79c8cd997a
chore(deps): update dependency skynetlabs/webportal-accounts-dashboard to v2 2022-07-10 13:44:11 +00:00
renovate[bot] 2c3978babf
chore(deps): update dependency skynetlabs/pinner to v0.4.1 2022-07-08 15:29:01 +00:00
Karol Wypchło 2f2c90f83e
Merge branch 'master' into improve-certbot-docs 2022-07-08 10:50:58 +02:00
Karol Wypchlo f3ec6f5f33
cloudflare example 2022-07-08 10:49:19 +02:00
Karol Wypchło b2814a68d9
Merge pull request #2171 from SkynetLabs/karol/sky-1240-use-remote-sia-dockerfile-until-ansible
use remote sia dockerfile until ansible is ready to use image
2022-07-08 10:34:25 +02:00
Ivaylo Novakov 4f7729052c
Merge pull request #2166 from SkynetLabs/ivo/pinner_log_file
Define a log file for pinner.
2022-07-08 10:15:50 +02:00
renovate[bot] 60717027dd
chore(deps): update dependency skynetlabs/webportal-health-check to v0.3.0 2022-07-07 11:12:58 +00:00
Karol Wypchlo 266e9a9307
remove unused PORTAL_MODULES env variable 2022-07-06 18:51:01 +02:00
Karol Wypchlo dd5e362b2d
adjust command for new skyd container 2022-07-06 18:48:10 +02:00
Karol Wypchlo 5031229e18
remove dockerfile linter from this repository 2022-07-06 18:44:35 +02:00
Karol Wypchlo 241de3f2ae
use remote sia dockerfile 2022-07-06 18:40:24 +02:00
Matthew Sevey 7b3d8d1430
Merge pull request #2152 from SkynetLabs/add-davids-pub-key
Update authorized_keys
2022-07-06 10:46:53 -04:00
David Vorick a395f84cdb
Merge branch 'master' into add-davids-pub-key 2022-07-06 10:46:33 -04:00
Karol Wypchło 59af9b8ae6
Update setup-scripts/support/authorized_keys 2022-07-06 15:28:40 +02:00
Karol Wypchło 743b5940d6
Merge pull request #2170 from SkynetLabs/renovate/certbot-dns-route53-1.x
chore(deps): update dependency certbot/dns-route53 to v1.29.0
2022-07-06 10:48:30 +02:00
Karol Wypchło a6868085a6
Merge pull request #2165 from SkynetLabs/renovate/jaegertracing
chore(deps): update jaegertracing to v1.36.0
2022-07-06 10:48:19 +02:00
Ivaylo Novakov 44a0f74bd2
Merge pull request #2167 from SkynetLabs/renovate/skynetlabs-skynet-accounts-1.x
chore(deps): update dependency skynetlabs/skynet-accounts to v1.2.3
2022-07-06 10:04:50 +02:00
Ivaylo Novakov 1f2e274e55
Merge pull request #2168 from SkynetLabs/renovate/skynetlabs-pinner-0.x
chore(deps): update dependency skynetlabs/pinner to v0.4.0
2022-07-06 10:04:26 +02:00
Ivaylo Novakov 2d28208722
Merge pull request #2169 from SkynetLabs/renovate/mongo-4.x
chore(deps): update dependency mongo to v4.4.15
2022-07-06 09:44:27 +02:00
renovate[bot] 2941d33ee5
chore(deps): update dependency certbot/dns-route53 to v1.29.0 2022-07-06 02:53:05 +00:00
renovate[bot] 62e300ca0c
chore(deps): update dependency mongo to v4.4.15 2022-07-06 00:11:49 +00:00
renovate[bot] 04f3579f60
chore(deps): update dependency skynetlabs/pinner to v0.4.0 2022-07-05 15:35:57 +00:00
renovate[bot] 9e8def4c5d
chore(deps): update dependency skynetlabs/skynet-accounts to v1.2.3 2022-07-05 15:35:52 +00:00
Ivaylo Novakov 6bfc12287d
Clean up redundant code. 2022-07-05 17:11:41 +03:00
Ivaylo Novakov 919061a6ec
Define a log file for pinner. 2022-07-05 16:23:46 +03:00
renovate[bot] 975ede05f5
chore(deps): update jaegertracing to v1.36.0 2022-07-05 13:00:10 +00:00
Karol Wypchlo db579f6ebd
add readme note about certbot plugin 2022-07-01 16:40:34 +02:00
Michał Leszczyk beb6e2c3af
Merge pull request #2162 from SkynetLabs/renovate/docker.elastic.co-elasticsearch-elasticsearch-7.x
chore(deps): update dependency docker.elastic.co/elasticsearch/elasticsearch to v7.17.5
2022-06-29 13:46:31 +02:00
Ivaylo Novakov 5a47c89e59
Merge pull request #2150 from SkynetLabs/renovate/jaegertracing
chore(deps): update jaegertracing to v1.35.2
2022-06-29 11:18:25 +02:00
renovate[bot] b3d344ec81
chore(deps): update dependency docker.elastic.co/elasticsearch/elasticsearch to v7.17.5 2022-06-28 16:51:56 +00:00
Matthew Sevey 6343cff81b
Merge pull request #2161 from SkynetLabs/karol/sky-1133-set-codeowners-for-skynet-webportal
Create CODEOWNERS
2022-06-28 12:50:00 -04:00
Ivaylo Novakov c341e3e4f8
Merge pull request #2159 from SkynetLabs/renovate/skynetlabs-blocker-0.x
chore(deps): update dependency skynetlabs/blocker to v0.1.2
2022-06-28 11:37:40 +02:00
Ivaylo Novakov e3be698f34
Merge pull request #2160 from SkynetLabs/renovate/skynetlabs-abuse-scanner-0.x
chore(deps): update dependency skynetlabs/abuse-scanner to v0.2.0
2022-06-28 11:37:23 +02:00
Karol Wypchło dd192c11b2
Create CODEOWNERS 2022-06-28 10:36:30 +02:00
renovate[bot] 8bc3da2bfb
chore(deps): update dependency skynetlabs/abuse-scanner to v0.2.0 2022-06-27 18:16:48 +00:00
renovate[bot] b57dd97b24
chore(deps): update dependency skynetlabs/blocker to v0.1.2 2022-06-27 18:16:43 +00:00
Ivaylo Novakov d00a472b94
Merge pull request #2157 from SkynetLabs/renovate/skynetlabs-webportal-health-check-0.x
chore(deps): update dependency skynetlabs/webportal-health-check to v0.2.0
2022-06-27 16:15:01 +02:00
Ivaylo Novakov e4178ec85a
Merge pull request #2156 from SkynetLabs/renovate/skynetlabs-webportal-website-0.x
chore(deps): update dependency skynetlabs/webportal-website to v0.2.1
2022-06-27 16:14:45 +02:00
Ivaylo Novakov e9c7613c08
Merge pull request #2155 from SkynetLabs/renovate/skynetlabs-webportal-nginx-0.x
chore(deps): update dependency skynetlabs/webportal-nginx to v0.3.3
2022-06-27 16:14:23 +02:00
Ivaylo Novakov 6327e5a961
Merge pull request #2154 from SkynetLabs/renovate/skynetlabs-skynet-accounts-1.x
chore(deps): update dependency skynetlabs/skynet-accounts to v1.2.2
2022-06-27 16:14:07 +02:00
renovate[bot] fa156a208d
chore(deps): update dependency skynetlabs/webportal-health-check to v0.2.0 2022-06-27 14:11:14 +00:00
renovate[bot] 46d1099561
chore(deps): update dependency skynetlabs/webportal-website to v0.2.1 2022-06-27 14:11:08 +00:00
renovate[bot] cdf5c3f732
chore(deps): update dependency skynetlabs/webportal-nginx to v0.3.3 2022-06-27 14:11:03 +00:00
renovate[bot] f17e78f7c4
chore(deps): update dependency skynetlabs/skynet-accounts to v1.2.2 2022-06-27 11:01:11 +00:00
Matthew Sevey e273491360
Update authorized_keys 2022-06-25 23:48:35 -04:00
Christopher Schinnerl 22a1ac6348
Merge pull request #2151 from SkynetLabs/renovate/skynetlabs-webportal-website-0.x
chore(deps): update dependency skynetlabs/webportal-website to v0.2.0
2022-06-21 17:37:10 +02:00
renovate[bot] d88c3b65fa
chore(deps): update dependency skynetlabs/webportal-website to v0.2.0 2022-06-21 15:32:28 +00:00
renovate[bot] a603879277
chore(deps): update jaegertracing to v1.35.2 2022-06-21 15:31:38 +00:00
Ivaylo Novakov e01752d5aa
Merge pull request #2148 from SkynetLabs/group-renovate-jaegertracing
group renovate jaegertracing
2022-06-21 17:12:29 +02:00
Ivaylo Novakov fb46a740cc
Merge pull request #2139 from SkynetLabs/renovate/mongo-4.x
chore(deps): update dependency mongo to v4.4.14
2022-06-21 17:11:21 +02:00
Ivaylo Novakov f0531b0831
Merge pull request #2140 from SkynetLabs/renovate/certbot-dns-route53-1.x
chore(deps): update dependency certbot/dns-route53 to v1.28.0
2022-06-21 17:09:08 +02:00
Ivaylo Novakov 4a7cbd7c00
Merge pull request #2141 from SkynetLabs/renovate/docker.elastic.co-elasticsearch-elasticsearch-7.x
chore(deps): update dependency docker.elastic.co/elasticsearch/elasticsearch to v7.17.4
2022-06-21 17:08:40 +02:00
Christopher Schinnerl 1a8791e814
Merge pull request #2149 from SkynetLabs/renovate/skynetlabs-webportal-nginx-0.x
chore(deps): update dependency skynetlabs/webportal-nginx to v0.3.1
2022-06-21 17:06:19 +02:00
renovate[bot] c1f6ae9e04
chore(deps): update dependency skynetlabs/webportal-nginx to v0.3.1 2022-06-21 15:01:58 +00:00
Karol Wypchlo cbc3d6560e
group renovate jaegertracing 2022-06-21 13:40:45 +02:00
renovate[bot] de310cf873
chore(deps): update dependency docker.elastic.co/elasticsearch/elasticsearch to v7.17.4 2022-06-21 11:35:37 +00:00
renovate[bot] 7719089dbd
chore(deps): update dependency certbot/dns-route53 to v1.28.0 2022-06-21 11:35:33 +00:00
renovate[bot] 990ad41c0f
chore(deps): update dependency mongo to v4.4.14 2022-06-21 11:35:28 +00:00
Christopher Schinnerl 61f85a9109
Merge pull request #2138 from SkynetLabs/renovate/configure
Configure Renovate
2022-06-21 13:33:31 +02:00
Karol Wypchlo 4e18dfaca0
configure only docker-compose files 2022-06-21 13:26:51 +02:00
renovate[bot] 66b12f1d77
chore(deps): add renovate.json 2022-06-21 11:00:02 +00:00
Michał Leszczyk 65d9b7ddb3
Merge pull request #2135 from SkynetLabs/update-webportal-nginx-to-version-0.3.0
update webportal-nginx to version 0.3.0
2022-06-21 12:38:14 +02:00
Karol Wypchło 09c0fcfc35
update webportal-nginx to version 0.3.0 2022-06-21 11:22:26 +02:00
Karol Wypchło 4474b3e5cb
Merge pull request #2134 from SkynetLabs/bump-dashboard-to-1.1.2
Bump webportal-accounts-dashboard to 1.1.2
2022-06-20 15:53:43 +02:00
Michał Leszczyk 582526b735
Bump webportal-accounts-dashboard to 1.1.2 2022-06-20 15:39:01 +02:00
Matthew Sevey 7d62814e11
Merge pull request #2133 from SkynetLabs/bump-dashboard-n-accounts
Bump dashboard image to 1.1.1
2022-06-09 11:20:59 -04:00
Michał Leszczyk 79c41d5979
Bump dashboard image to 1.1.1 2022-06-09 17:17:13 +02:00
Ivaylo Novakov a02887c13a
Merge pull request #2132 from SkynetLabs/ivo/bump
Bump pinner to 0.3.1 and accounts to 1.2.0.
2022-06-08 16:23:38 +02:00
Ivaylo Novakov a24a54aed9
Bump pinner to 0.3.1 and accounts to 1.2.0. 2022-06-08 15:50:43 +02:00
Matthew Sevey 7f2f35db7b
Merge pull request #2129 from SkynetLabs/sky-762
ops: configure new dashboard
2022-06-02 09:38:13 -04:00
Michał Leszczyk 8a2cbcc5e8
ops: bump webportal-nginx to 0.2.0 2022-06-02 15:37:11 +02:00
Matthew Sevey aa9dbc3b17
Merge branch 'master' into sky-762 2022-06-02 09:29:15 -04:00
Ivaylo Novakov ff0035c89b
Merge pull request #2130 from SkynetLabs/ivo/bump_versions
Bump pinner and accounts versions.
2022-06-02 15:28:12 +02:00
Ivaylo Novakov 145fb0807c
Bump pinner version to 0.3.0.
Bump accounts version to 1.1.1.
2022-06-02 15:20:18 +02:00
Michał Leszczyk b2731e820b
ops: bump webportal-accounts-dashboard to 1.1.0 2022-06-02 15:11:30 +02:00
Michał Leszczyk 936c1a5cdd
ops: configure new dashboard 2022-06-01 14:25:21 +02:00
Matthew Sevey 3eded4bb0c
Merge pull request #2109 from SkynetLabs/matt/sky-585-update-webportal-repo
remove dashboard related code
2022-05-27 09:43:05 -04:00
Matthew Sevey 0450b35016
Merge branch 'master' into matt/sky-585-update-webportal-repo 2022-05-27 09:39:16 -04:00
Karol Wypchło 9ec9c5630f
Merge pull request #2110 from SkynetLabs/matt/sky-567-pr-to-update-docker-compose-on-webportal
Remove Health-Check package
2022-05-27 15:37:53 +02:00
Matthew Sevey d459a7eab5
Fix merge conflicts 2022-05-27 09:35:19 -04:00
Matthew Sevey e30efa45fa
Fix dependabot file 2022-05-27 09:32:56 -04:00
Matthew Sevey 417c7afe58
Merge branch 'matt/sky-567-pr-to-update-docker-compose-on-webportal' of github.com:SkynetLabs/skynet-webportal into matt/sky-567-pr-to-update-docker-compose-on-webportal 2022-05-27 09:32:05 -04:00
Matthew Sevey 56c5b444e3
Merge branch 'matt/sky-567-pr-to-update-docker-compose-on-webportal' of github.com:SkynetLabs/skynet-webportal into matt/sky-567-pr-to-update-docker-compose-on-webportal 2022-05-27 09:31:38 -04:00
Karol Wypchło fbd03b87ed
Merge branch 'master' into matt/sky-567-pr-to-update-docker-compose-on-webportal 2022-05-27 15:31:29 +02:00
Matthew Sevey f3f4220053
Merge branch 'matt/sky-567-pr-to-update-docker-compose-on-webportal' of github.com:SkynetLabs/skynet-webportal into matt/sky-567-pr-to-update-docker-compose-on-webportal 2022-05-27 09:30:47 -04:00
Karol Wypchło 2615916ee6
Merge branch 'master' into matt/sky-567-pr-to-update-docker-compose-on-webportal 2022-05-27 15:30:29 +02:00
Karol Wypchło 819aa17499
Merge branch 'master' into matt/sky-567-pr-to-update-docker-compose-on-webportal 2022-05-27 15:29:31 +02:00
Matthew Sevey 1dbd2bab76
Merge branch 'master' into matt/sky-567-pr-to-update-docker-compose-on-webportal 2022-05-27 09:29:29 -04:00
Matthew Sevey b5c2d4cda8
Merge branch 'master' into matt/sky-585-update-webportal-repo 2022-05-27 09:28:27 -04:00
Matthew Sevey df0e949bee
Merge branch 'matt/sky-567-pr-to-update-docker-compose-on-webportal' of github.com:SkynetLabs/skynet-webportal into matt/sky-567-pr-to-update-docker-compose-on-webportal 2022-05-27 09:26:04 -04:00
Matthew Sevey 9126a45352
Merge pull request #2108 from SkynetLabs/matt/sky-571-update-webportal-docker-compose
Remove dsn-link related code and files
2022-05-27 09:25:48 -04:00
Karol Wypchło 831565f4a2
Merge branch 'master' into matt/sky-571-update-webportal-docker-compose 2022-05-27 15:25:43 +02:00
Karol Wypchło 227df6cc28
Update docker-compose.yml
Co-authored-by: Michał Leszczyk <michasko37@gmail.com>
2022-05-27 15:24:05 +02:00
Karol Wypchło 82659c481a
Merge pull request #2112 from SkynetLabs/matt/sky-593-nginx-update-webportal-docker-compose
Remove NGINX code
2022-05-27 15:20:47 +02:00
Matthew Sevey 91b55e67ff
Merge pull request #2111 from SkynetLabs/matt/sky-577-handshake-update-webportal
Remove handshake API code
2022-05-27 09:19:35 -04:00
Karol Wypchło 09e66279f7
Merge pull request #2113 from SkynetLabs/matt/sky-702-remove-website-subpackage-from-webportal
Remove website subpackage from webportal
2022-05-27 15:18:04 +02:00
Matthew Sevey b9798dab14
Merge pull request #2107 from SkynetLabs/matt/sky-665-update-webportal-repo
Remove dashboard V2
2022-05-27 09:12:52 -04:00
Karol Wypchlo 591dfa37a6
clean up dependabot configuration 2022-05-27 12:52:18 +02:00
Karol Wypchło 9446f9bb75
Merge branch 'master' into matt/sky-665-update-webportal-repo 2022-05-27 12:49:59 +02:00
Karol Wypchło 93ffd77d54
Merge branch 'master' into matt/sky-585-update-webportal-repo 2022-05-27 12:49:28 +02:00
Karol Wypchlo ca40bc1bc0
clean up dependabot health-check configuration 2022-05-27 12:37:33 +02:00
Matthew Sevey 2ef8c7c288
Update health check image 2022-05-27 12:35:25 +02:00
Matthew Sevey ba72d340ab
Remove Health-Check package 2022-05-27 12:35:23 +02:00
Karol Wypchlo cccab4d497
clean up website dependabot and gitignore 2022-05-27 12:29:58 +02:00
Karol Wypchło 286445365d
Merge branch 'master' into matt/sky-702-remove-website-subpackage-from-webportal 2022-05-27 12:28:21 +02:00
Karol Wypchlo 4a72b7e5e5
clean up dnslink-api dependabot config 2022-05-27 11:34:01 +02:00
Karol Wypchło 51926242de
Merge branch 'master' into matt/sky-571-update-webportal-docker-compose 2022-05-27 11:32:46 +02:00
Karol Wypchlo 9cb81842a8
clean up handshake-api dependabot 2022-05-27 11:29:04 +02:00
Karol Wypchło 06c1847857
Merge branch 'master' into matt/sky-577-handshake-update-webportal 2022-05-27 11:07:18 +02:00
Karol Wypchlo eafd2da5bd
remove local nginx references 2022-05-27 10:46:15 +02:00
Karol Wypchło 5bd7f9a946
Merge branch 'master' into matt/sky-593-nginx-update-webportal-docker-compose 2022-05-27 10:42:34 +02:00
Matthew Sevey dab29fead5
Merge pull request #2106 from SkynetLabs/fix-single-server-portals-health-check
skip server_domain check on single server portals
2022-05-27 03:04:04 -04:00
Matthew Sevey b1f0019220
Update docker image 2022-05-26 14:32:33 -04:00
Matthew Sevey 40381e0afb
Update image 2022-05-26 14:24:00 -04:00
Matthew Sevey f3cb494d1a
Update docker image 2022-05-26 14:16:19 -04:00
Matthew Sevey 1533b1527e
Update image 2022-05-26 13:43:00 -04:00
Matthew Sevey f25c2ab7bf
Set to stock website image 2022-05-26 13:22:40 -04:00
Matthew Sevey cc66e397a3
update docke compose for new website docker image 2022-05-26 13:17:48 -04:00
Matthew Sevey 2c00bdd86f
remove website files 2022-05-26 13:16:26 -04:00
Matthew Sevey c3c369c312
Update health check image 2022-05-26 13:12:58 -04:00
Matthew Sevey 526445f499
update docker compose 2022-05-25 15:25:23 -04:00
Matthew Sevey 26d255bee7
Forgot to save fiel 2022-05-25 15:24:17 -04:00
Matthew Sevey 37a56e5568
Remove NGINX code 2022-05-25 15:18:12 -04:00
Matthew Sevey db39492bdb
Remove handshake API code 2022-05-25 15:14:26 -04:00
Matthew Sevey 68f36209f8
Fix branch name 2022-05-25 15:06:11 -04:00
Matthew Sevey f8331577f6
fix branch name 2022-05-25 15:04:13 -04:00
Matthew Sevey b1884bb365
Remove Health-Check package 2022-05-25 11:47:53 -04:00
Matthew Sevey c4a8020f0b
update docker compose 2022-05-25 10:55:46 -04:00
Matthew Sevey 0041c5cd90
remove dashboard related code 2022-05-25 10:53:55 -04:00
Matthew Sevey 623319da42
Remove DNSlint related code and files 2022-05-25 10:50:13 -04:00
Matthew Sevey a69b77d328
remove storybook action 2022-05-25 09:35:48 -04:00
Matthew Sevey 9e20478f4c
Remove outdated github actions 2022-05-25 09:31:37 -04:00
Matthew Sevey 6085224a5d
remove dashboard v2 files and update docker compose 2022-05-25 09:30:54 -04:00
Karol Wypchlo 4af101cb4c
skip server_domain check on single server portals 2022-05-25 15:15:33 +02:00
Matthew Sevey 98d6884391
Merge pull request #2105 from SkynetLabs/michalleszczyk/sky-652-fix-subscription-plans-view
Dashboard V2: Fix extraneous tiers on /payments screen
2022-05-25 08:50:57 -04:00
569 changed files with 145 additions and 58144 deletions

1
.github/CODEOWNERS vendored Normal file
View File

@ -0,0 +1 @@
* @kwypchlo @meeh0w

View File

@ -1,50 +1,6 @@
version: 2
updates:
- package-ecosystem: npm
directory: "/packages/dashboard"
schedule:
interval: monthly
- package-ecosystem: npm
directory: "/packages/dnslink-api"
schedule:
interval: monthly
- package-ecosystem: npm
directory: "/packages/handshake-api"
schedule:
interval: monthly
- package-ecosystem: npm
directory: "/packages/health-check"
schedule:
interval: monthly
- package-ecosystem: npm
directory: "/packages/website"
schedule:
interval: monthly
- package-ecosystem: docker
directory: "/docker/nginx"
schedule:
interval: monthly
- package-ecosystem: docker
directory: "/docker/sia"
schedule:
interval: monthly
- package-ecosystem: docker
directory: "/packages/dashboard"
schedule:
interval: monthly
- package-ecosystem: docker
directory: "/packages/dnslink-api"
schedule:
interval: monthly
- package-ecosystem: docker
directory: "/packages/handshake-api"
schedule:
interval: monthly
- package-ecosystem: docker
directory: "/packages/health-check"
schedule:
interval: monthly
- package-ecosystem: docker
directory: "/packages/website"
schedule:
interval: monthly

View File

@ -1,71 +0,0 @@
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL"
on:
push:
branches: [ main ]
pull_request:
# The branches below must be a subset of the branches above
branches: [ main ]
schedule:
- cron: '32 21 * * 0'
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write
strategy:
fail-fast: false
matrix:
language: [ 'javascript', 'python' ]
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ]
# Learn more:
# https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed
steps:
- name: Checkout repository
uses: actions/checkout@v2
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v1
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# queries: ./path/to/local/query, your-org/your-repo/queries@main
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v1
# Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
# and modify them (or add more) to build your code if your project
# uses a compiled language
#- run: |
# make bootstrap
# make release
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v1

View File

@ -1,31 +0,0 @@
name: Build Storybook - packages/dashboard-v2
on:
push:
branches:
- master
paths:
- "packages/dashboard-v2/**"
pull_request:
paths:
- "packages/dashboard-v2/**"
defaults:
run:
working-directory: packages/dashboard-v2
jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: 16.x
- run: yarn install
- run: yarn build-storybook
- name: "Deploy to Skynet"
uses: skynetlabs/deploy-to-skynet-action@v2
with:
upload-dir: packages/dashboard-v2/storybook-build
github-token: ${{ secrets.GITHUB_TOKEN }}

View File

@ -1,54 +0,0 @@
name: Deploy website to Skynet
on:
push:
branches:
- master
paths:
- "packages/website/**"
pull_request:
paths:
- "packages/website/**"
defaults:
run:
working-directory: packages/website
env:
PORTAL_DOMAIN: siasky.net
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 16.x
cache: yarn
cache-dependency-path: packages/website/yarn.lock
- run: yarn
- run: yarn build
- name: "Integration tests"
uses: cypress-io/github-action@v3
env:
CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
working-directory: packages/website
install: false
record: true
start: yarn develop
wait-on: http://localhost:8000
wait-on-timeout: 120
config: baseUrl=http://localhost:8000
- name: "Deploy to Skynet"
uses: skynetlabs/deploy-to-skynet-action@v2
with:
upload-dir: packages/website/public
github-token: ${{ secrets.GITHUB_TOKEN }}
registry-seed: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' && secrets.WEBSITE_REGISTRY_SEED || '' }}

View File

@ -1,29 +0,0 @@
name: Dockerfile Lint
on:
push:
branches:
- master
pull_request:
jobs:
hadolint:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
dockerfile:
- docker/nginx/Dockerfile
- docker/nginx/testing/Dockerfile
- docker/sia/Dockerfile
- packages/dashboard/Dockerfile
- packages/dashboard-v2/Dockerfile
- packages/dnslink-api/Dockerfile
- packages/handshake-api/Dockerfile
- packages/health-check/Dockerfile
- packages/website/Dockerfile
steps:
- uses: actions/checkout@v3
- uses: hadolint/hadolint-action@v2.0.0
with:
dockerfile: ${{ matrix.dockerfile }}

View File

@ -1,24 +0,0 @@
name: Lint - packages/dashboard-v2
on:
pull_request:
paths:
- packages/dashboard-v2/**
defaults:
run:
working-directory: packages/dashboard-v2
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: 16.x
- run: yarn
- run: yarn prettier --check
- run: yarn lint

View File

@ -1,24 +0,0 @@
name: Lint - packages/dashboard
on:
pull_request:
paths:
- packages/dashboard/**
defaults:
run:
working-directory: packages/dashboard
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: 16.x
- run: yarn
- run: yarn prettier --check .
- run: yarn next lint

View File

@ -1,23 +0,0 @@
name: Lint - packages/dnslink-api
on:
pull_request:
paths:
- packages/dnslink-api/**
defaults:
run:
working-directory: packages/dnslink-api
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: 16.x
- run: yarn
- run: yarn prettier --check .

View File

@ -1,23 +0,0 @@
name: Lint - packages/handshake-api
on:
pull_request:
paths:
- packages/handshake-api/**
defaults:
run:
working-directory: packages/handshake-api
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: 16.x
- run: yarn
- run: yarn prettier --check .

View File

@ -1,23 +0,0 @@
name: Lint - packages/health-check
on:
pull_request:
paths:
- packages/health-check/**
defaults:
run:
working-directory: packages/health-check
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: 16.x
- run: yarn
- run: yarn prettier --check .

View File

@ -1,23 +0,0 @@
name: Lint - packages/website
on:
pull_request:
paths:
- packages/website/**
defaults:
run:
working-directory: packages/website
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: 16.x
- run: yarn
- run: yarn prettier --check .

View File

@ -1,46 +0,0 @@
# Install and run unit tests with busted
# Docs: http://olivinelabs.com/busted/
name: Nginx Lua Unit Tests
on:
push:
branches:
- master
paths:
- docker/nginx/libs/**
pull_request:
paths:
- docker/nginx/libs/**
jobs:
test:
runs-on: ubuntu-latest
container: openresty/openresty:1.19.9.1-focal
steps:
- uses: actions/checkout@v3
- name: Install Dependencies
run: |
luarocks install lua-resty-http
luarocks install hasher
luarocks install busted
luarocks install luacov
luarocks install luacheck
- name: Lint Code With Luacheck
run: luacheck docker/nginx/libs --std ngx_lua+busted
- name: Run Tests With Busted
# ran from root repo directory; produces luacov.stats.out file
run: docker/nginx/testing/rbusted --lpath='docker/nginx/libs/?.lua;docker/nginx/libs/?/?.lua' --verbose --coverage --pattern=spec docker/nginx/libs
- name: Generate Code Coverage Report With Luacov
# requires config file in cwd; produces luacov.report.out file
run: cp docker/nginx/testing/.luacov . && luacov && rm .luacov
- uses: codecov/codecov-action@v3
with:
root_dir: ${GITHUB_WORKSPACE}
files: ./luacov.report.out
flags: nginx-lua

View File

@ -1,23 +0,0 @@
name: Test - packages/health-check
on:
pull_request:
paths:
- packages/health-check/**
defaults:
run:
working-directory: packages/health-check
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: 16.x
- run: yarn
- run: yarn jest

4
.gitignore vendored
View File

@ -67,10 +67,6 @@ yarn-error.log
# Yarn Integrity file
.yarn-integrity
# Cypress
packages/website/cypress/screenshots
packages/website/cypress/videos
# Docker data
docker/data

View File

@ -8,23 +8,6 @@ supports is located at https://portal-docs.skynetlabs.com/.
Some scripts and setup documentation contained in this repository
(`skynet-webportal`) may be outdated and generally should not be used.
## Web application
Change current directory with `cd packages/website`.
Use `yarn start` to start the development server.
Use `yarn build` to compile the application to `/public` directory.
You can use the below build parameters to customize your web application.
- development example `GATSBY_API_URL=https://siasky.dev yarn start`
- production example `GATSBY_API_URL=https://siasky.net yarn build`
List of available parameters:
- `GATSBY_API_URL`: override api url (defaults to location origin)
## License
Skynet uses a custom [License](./LICENSE.md). The Skynet License is a source code license that allows you to use, modify
@ -33,19 +16,3 @@ and distribute the software, but you must preserve the payment mechanism in the
For the purposes of complying with our code license, you can use the following Siacoin address:
`fb6c9320bc7e01fbb9cd8d8c3caaa371386928793c736837832e634aaaa484650a3177d6714a`
## Running a Portal
For those interested in running a Webportal, head over to our developer docs [here](https://portal-docs.skynetlabs.com/) to learn more.
## Contributing
### Testing Your Code
Before pushing your code, you should verify that it will pass our online test suite.
**Cypress Tests**
Verify the Cypress test suite by doing the following:
1. In one terminal screen run `GATSBY_API_URL=https://siasky.net website serve`
1. In a second terminal screen run `yarn cypress run`

31
dc
View File

@ -5,56 +5,59 @@
# would use docker-compose with the only difference being that you don't need to specify compose files. For more
# information you can run `./dc` or `./dc help`.
if [ -f .env ]; then
OLD_IFS=$IFS
IFS=$'\n'
for x in $(grep -v '^#.*' .env); do export $x; done
IFS=$OLD_IFS
# get current working directory of this script and prefix all files with it to
# be able to call this script from anywhere and not only root directory of
# skynet-webportal project
cwd="$(dirname -- "$0";)";
# get portal modules configuration from .env file (if defined more than once, the last one is used)
if [[ -f "${cwd}/.env" ]]; then
PORTAL_MODULES=$(grep -e "^PORTAL_MODULES=" ${cwd}/.env | tail -1 | sed "s/PORTAL_MODULES=//")
fi
# include base docker compose file
COMPOSE_FILES="-f docker-compose.yml"
COMPOSE_FILES="-f ${cwd}/docker-compose.yml"
for i in $(seq 1 ${#PORTAL_MODULES}); do
# accounts module - alias "a"
if [[ ${PORTAL_MODULES:i-1:1} == "a" ]]; then
COMPOSE_FILES+=" -f docker-compose.mongodb.yml -f docker-compose.accounts.yml"
COMPOSE_FILES+=" -f ${cwd}/docker-compose.mongodb.yml -f ${cwd}/docker-compose.accounts.yml"
fi
# blocker module - alias "b"
if [[ ${PORTAL_MODULES:i-1:1} == "b" ]]; then
COMPOSE_FILES+=" -f docker-compose.mongodb.yml -f docker-compose.blocker.yml"
COMPOSE_FILES+=" -f ${cwd}/docker-compose.mongodb.yml -f ${cwd}/docker-compose.blocker.yml"
fi
# jaeger module - alias "j"
if [[ ${PORTAL_MODULES:i-1:1} == "j" ]]; then
COMPOSE_FILES+=" -f docker-compose.jaeger.yml"
COMPOSE_FILES+=" -f ${cwd}/docker-compose.jaeger.yml"
fi
# malware-scanner module - alias "s"
if [[ ${PORTAL_MODULES:i-1:1} == "s" ]]; then
COMPOSE_FILES+=" -f docker-compose.blocker.yml -f docker-compose.mongodb.yml -f docker-compose.malware-scanner.yml"
COMPOSE_FILES+=" -f ${cwd}/docker-compose.blocker.yml -f ${cwd}/docker-compose.mongodb.yml -f ${cwd}/docker-compose.malware-scanner.yml"
fi
# mongodb module - alias "m"
if [[ ${PORTAL_MODULES:i-1:1} == "m" ]]; then
COMPOSE_FILES+=" -f docker-compose.mongodb.yml"
COMPOSE_FILES+=" -f ${cwd}/docker-compose.mongodb.yml"
fi
# abuse-scanner module - alias "u"
if [[ ${PORTAL_MODULES:i-1:1} == "u" ]]; then
COMPOSE_FILES+=" -f docker-compose.mongodb.yml -f docker-compose.blocker.yml -f docker-compose.abuse-scanner.yml"
COMPOSE_FILES+=" -f ${cwd}/docker-compose.mongodb.yml -f ${cwd}/docker-compose.blocker.yml -f ${cwd}/docker-compose.abuse-scanner.yml"
fi
# pinner module - alias "p"
if [[ ${PORTAL_MODULES:i-1:1} == "p" ]]; then
COMPOSE_FILES+=" -f docker-compose.mongodb.yml -f docker-compose.pinner.yml"
COMPOSE_FILES+=" -f ${cwd}/docker-compose.mongodb.yml -f ${cwd}/docker-compose.pinner.yml"
fi
done
# override file if exists
if [[ -f docker-compose.override.yml ]]; then
COMPOSE_FILES+=" -f docker-compose.override.yml"
COMPOSE_FILES+=" -f ${cwd}/docker-compose.override.yml"
fi
docker-compose $COMPOSE_FILES $@

View File

@ -1,4 +1,4 @@
version: "3.7"
version: "3.8"
x-logging: &default-logging
driver: json-file
@ -10,7 +10,7 @@ services:
abuse-scanner:
# uncomment "build" and comment out "image" to build from sources
# build: https://github.com/SkynetLabs/abuse-scanner.git#main
image: skynetlabs/abuse-scanner:0.1.1
image: skynetlabs/abuse-scanner:0.4.0
container_name: abuse-scanner
restart: unless-stopped
logging: *default-logging
@ -36,3 +36,6 @@ services:
depends_on:
- mongo
- blocker
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /tmp:/tmp

View File

@ -1,4 +1,4 @@
version: "3.7"
version: "3.8"
x-logging: &default-logging
driver: json-file
@ -21,8 +21,8 @@ services:
accounts:
# uncomment "build" and comment out "image" to build from sources
build: https://github.com/SkynetLabs/skynet-accounts.git#dashboard-v2-tests
# image: skynetlabs/skynet-accounts:1.1.0
# build: https://github.com/SkynetLabs/skynet-accounts.git#main
image: skynetlabs/skynet-accounts:1.3.0
container_name: accounts
restart: unless-stopped
logging: *default-logging
@ -54,50 +54,23 @@ services:
depends_on:
- mongo
# dashboard:
# # uncomment "build" and comment out "image" to build from sources
# build:
# context: https://github.com/SkynetLabs/skynet-webportal.git#master
# dockerfile: ./packages/dashboard/Dockerfile
# # image: skynetlabs/dashboard
# container_name: dashboard
# restart: unless-stopped
# logging: *default-logging
# env_file:
# - .env
# environment:
# - NEXT_PUBLIC_PORTAL_DOMAIN=${PORTAL_DOMAIN}
# - NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=${STRIPE_PUBLISHABLE_KEY}
# volumes:
# - ./docker/data/dashboard/.next:/usr/app/.next
# networks:
# shared:
# ipv4_address: 10.10.10.85
# expose:
# - 3000
# depends_on:
# - mongo
# Do not build dashboard-v2 until we're ready to make a switch
# ============================================================
dashboard-v2:
build:
context: ./packages/dashboard-v2
dockerfile: Dockerfile
container_name: dashboard-v2
dashboard:
# uncomment "build" and comment out "image" to build from sources
# build:
# context: https://github.com/SkynetLabs/webportal-accounts-dashboard.git#main
# dockerfile: Dockerfile
image: skynetlabs/webportal-accounts-dashboard:2.1.1
container_name: dashboard
restart: unless-stopped
logging: *default-logging
env_file:
- .env
environment:
- GATSBY_PORTAL_DOMAIN=${PORTAL_DOMAIN}
- GATSBY_STRIPE_PUBLISHABLE_KEY=${STRIPE_PUBLISHABLE_KEY}
volumes:
- ./docker/data/dashboard-v2/.cache:/usr/app/.cache
- ./docker/data/dashboard-v2/public:/usr/app/public
- ./docker/data/dashboard/.cache:/usr/app/.cache
- ./docker/data/dashboard/public:/usr/app/public
networks:
shared:
ipv4_address: 10.10.10.86
ipv4_address: 10.10.10.85
expose:
- 9000
depends_on:

View File

@ -1,4 +1,4 @@
version: "3.7"
version: "3.8"
x-logging: &default-logging
driver: json-file
@ -15,7 +15,7 @@ services:
blocker:
# uncomment "build" and comment out "image" to build from sources
# build: https://github.com/SkynetLabs/blocker.git#main
image: skynetlabs/blocker:0.1.1
image: skynetlabs/blocker:0.1.2
container_name: blocker
restart: unless-stopped
logging: *default-logging

View File

@ -1,4 +1,4 @@
version: "3.7"
version: "3.8"
x-logging: &default-logging
driver: json-file
@ -21,7 +21,7 @@ services:
- JAEGER_REPORTER_LOG_SPANS=false
jaeger-agent:
image: jaegertracing/jaeger-agent:1.32.0
image: jaegertracing/jaeger-agent:1.38.1
command:
[
"--reporter.grpc.host-port=jaeger-collector:14250",
@ -43,7 +43,7 @@ services:
- jaeger-collector
jaeger-collector:
image: jaegertracing/jaeger-collector:1.32.0
image: jaegertracing/jaeger-collector:1.38.1
entrypoint: /wait_to_start.sh
container_name: jaeger-collector
restart: on-failure
@ -68,7 +68,7 @@ services:
- elasticsearch
jaeger-query:
image: jaegertracing/jaeger-query:1.32.0
image: jaegertracing/jaeger-query:1.38.1
entrypoint: /wait_to_start.sh
container_name: jaeger-query
restart: on-failure
@ -93,7 +93,7 @@ services:
- elasticsearch
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:7.13.2
image: docker.elastic.co/elasticsearch/elasticsearch:7.17.6
container_name: elasticsearch
restart: on-failure
logging: *default-logging

View File

@ -1,4 +1,4 @@
version: "3.7"
version: "3.8"
x-logging: &default-logging
driver: json-file
@ -17,10 +17,6 @@ services:
- ./docker/clamav/clamd.conf:/etc/clamav/clamd.conf:ro
expose:
- 3310 # NEVER expose this outside of the local network!
deploy:
resources:
limits:
cpus: "${CLAMAV_CPU:-0.50}"
networks:
shared:
ipv4_address: 10.10.10.100

View File

@ -1,4 +1,4 @@
version: "3.7"
version: "3.8"
x-logging: &default-logging
driver: json-file
@ -14,7 +14,7 @@ services:
- MONGODB_PASSWORD=${SKYNET_DB_PASS}
mongo:
image: mongo:4.4.1
image: mongo:4.4.17
command: --keyFile=/data/mgkey --replSet=${SKYNET_DB_REPLICASET:-skynet} --setParameter ShardingTaskExecutorPoolMinSize=10
container_name: mongo
restart: unless-stopped

View File

@ -1,4 +1,4 @@
version: "3.7"
version: "3.8"
x-logging: &default-logging
driver: json-file
@ -10,12 +10,14 @@ services:
pinner:
# uncomment "build" and comment out "image" to build from sources
# build: https://github.com/SkynetLabs/pinner.git#main
image: skynetlabs/pinner:0.1.0
image: skynetlabs/pinner:0.7.8
container_name: pinner
restart: unless-stopped
logging: *default-logging
env_file:
- .env
volumes:
- ./docker/data/pinner/logs:/logs
environment:
- PINNER_LOG_LEVEL=${PINNER_LOG_LEVEL:-info}
expose:

View File

@ -1,4 +1,4 @@
version: "3.7"
version: "3.8"
x-logging: &default-logging
driver: json-file
@ -15,17 +15,19 @@ networks:
services:
sia:
build:
context: ./docker/sia
dockerfile: Dockerfile
args:
branch: portal-latest
# uncomment "build" and comment out "image" to build from sources
# build:
# context: https://github.com/SkynetLabs/docker-skyd.git#main
# dockerfile: scratch/Dockerfile
# args:
# branch: master
image: skynetlabs/skyd:1.6.9
command: --disable-api-security --api-addr :9980 --modules gctwra
container_name: sia
restart: unless-stopped
stop_grace_period: 5m
logging: *default-logging
environment:
- SIA_MODULES=gctwra
- SKYD_DISK_CACHE_ENABLED=${SKYD_DISK_CACHE_ENABLED:-true}
- SKYD_DISK_CACHE_SIZE=${SKYD_DISK_CACHE_SIZE:-53690000000} # 50GB
- SKYD_DISK_CACHE_MIN_HITS=${SKYD_DISK_CACHE_MIN_HITS:-3}
@ -41,7 +43,24 @@ services:
- 9980
certbot:
image: certbot/dns-route53:v1.25.0
# replace this image with the image supporting your dns provider from
# https://hub.docker.com/r/certbot/certbot and adjust CERTBOT_ARGS env variable
# note: you will need to authenticate your dns request so consult the plugin docs
# configuration https://eff-certbot.readthedocs.io/en/stable/using.html#dns-plugins
#
# =================================================================================
# example docker-compose.yml changes required for Cloudflare dns provider:
#
# image: certbot/dns-cloudflare
# environment:
# - CERTBOT_ARGS=--dns-cloudflare --dns-cloudflare-credentials /etc/letsencrypt/cloudflare.ini
#
# create ./docker/data/certbot/cloudflare.ini file with the following content:
# dns_cloudflare_api_token = <api key generated at https://dash.cloudflare.com/profile/api-tokens>
#
# make sure that the file has 0400 permissions with:
# chmod 0400 ./docker/data/certbot/cloudflare.ini
image: certbot/dns-route53:v1.31.0
entrypoint: sh /entrypoint.sh
container_name: certbot
restart: unless-stopped
@ -57,9 +76,9 @@ services:
nginx:
# uncomment "build" and comment out "image" to build from sources
# build:
# context: https://github.com/SkynetLabs/skynet-webportal.git#master
# dockerfile: ./docker/nginx/Dockerfile
image: skynetlabs/nginx
# context: https://github.com/SkynetLabs/webportal-nginx.git#main
# dockerfile: Dockerfile
image: skynetlabs/webportal-nginx:1.0.0
container_name: nginx
restart: unless-stopped
logging: *default-logging
@ -72,10 +91,6 @@ services:
- ./docker/data/nginx/skynet:/data/nginx/skynet:ro
- ./docker/data/sia/apipassword:/data/sia/apipassword:ro
- ./docker/data/certbot:/etc/letsencrypt
- ./docker/nginx/libs:/etc/nginx/libs
- ./docker/nginx/conf.d:/etc/nginx/conf.d
- ./docker/nginx/conf.d.templates:/etc/nginx/templates
- ./docker/nginx/nginx.conf:/usr/local/openresty/nginx/conf/nginx.conf
networks:
shared:
ipv4_address: 10.10.10.30
@ -91,9 +106,9 @@ services:
website:
# uncomment "build" and comment out "image" to build from sources
# build:
# context: https://github.com/SkynetLabs/skynet-webportal.git#master
# dockerfile: ./packages/website/Dockerfile
image: skynetlabs/website
# context: https://github.com/SkynetLabs/webportal-website.git#main
# dockerfile: Dockerfile
image: skynetlabs/webportal-website:0.2.3
container_name: website
restart: unless-stopped
logging: *default-logging
@ -109,18 +124,11 @@ services:
- 9000
handshake:
image: skynetlabs/hsd:3.0.1
command: --chain-migrate=2 --wallet-migrate=1
image: handshakeorg/hsd:4.0.2
command: --chain-migrate=3 --no-wallet --no-auth --compact-tree-on-init --network=main --http-host=0.0.0.0
container_name: handshake
restart: unless-stopped
logging: *default-logging
environment:
- HSD_LOG_CONSOLE=false
- HSD_HTTP_HOST=0.0.0.0
- HSD_NETWORK=main
- HSD_PORT=12037
env_file:
- .env
volumes:
- ./docker/data/handshake/.hsd:/root/.hsd
networks:
@ -132,9 +140,9 @@ services:
handshake-api:
# uncomment "build" and comment out "image" to build from sources
# build:
# context: https://github.com/SkynetLabs/skynet-webportal.git#master
# dockerfile: ./packages/handshake-api/Dockerfile
image: skynetlabs/handshake-api
# context: https://github.com/SkynetLabs/webportal-handshake-api.git#main
# dockerfile: Dockerfile
image: skynetlabs/webportal-handshake-api:0.1.3
container_name: handshake-api
restart: unless-stopped
logging: *default-logging
@ -156,9 +164,9 @@ services:
dnslink-api:
# uncomment "build" and comment out "image" to build from sources
# build:
# context: https://github.com/SkynetLabs/skynet-webportal.git#master
# dockerfile: ./packages/dnslink-api/Dockerfile
image: skynetlabs/dnslink-api
# context: https://github.com/SkynetLabs/webportal-dnslink-api.git#main
# dockerfile: Dockerfile
image: skynetlabs/webportal-dnslink-api:0.2.1
container_name: dnslink-api
restart: unless-stopped
logging: *default-logging
@ -171,9 +179,9 @@ services:
health-check:
# uncomment "build" and comment out "image" to build from sources
# build:
# context: https://github.com/SkynetLabs/skynet-webportal.git#master
# dockerfile: ./packages/health-check/Dockerfile
image: skynetlabs/health-check
# context: https://github.com/SkynetLabs/webportal-health-check.git#main
# dockerfile: Dockerfile
image: skynetlabs/webportal-health-check:1.0.0
container_name: health-check
restart: unless-stopped
logging: *default-logging

View File

@ -1,21 +0,0 @@
FROM openresty/openresty:1.19.9.1-focal
WORKDIR /
RUN apt-get update && apt-get --no-install-recommends -y install bc=1.07.1-2build1 && \
apt-get clean && rm -rf /var/lib/apt/lists/* && \
luarocks install lua-resty-http && \
luarocks install hasher
# reload nginx every 6 hours (for reloading certificates)
ENV NGINX_ENTRYPOINT_RELOAD_EVERY_X_HOURS 6
# copy entrypoint and entrypoint scripts
COPY docker/nginx/docker-entrypoint.sh /
COPY docker/nginx/docker-entrypoint.d /docker-entrypoint.d
ENTRYPOINT ["/docker-entrypoint.sh"]
STOPSIGNAL SIGQUIT
CMD ["nginx", "-g", "daemon off;"]

View File

@ -1,44 +0,0 @@
server {
server_name account.${PORTAL_DOMAIN}; # example: account.siasky.net
include /etc/nginx/conf.d/server/server.http;
}
server {
server_name account.${PORTAL_DOMAIN}; # example: account.siasky.net
set_by_lua_block $skynet_portal_domain { return "${PORTAL_DOMAIN}" }
set_by_lua_block $skynet_server_domain {
-- fall back to portal domain if server domain is not defined
if "${SERVER_DOMAIN}" == "" then
return "${PORTAL_DOMAIN}"
end
return "${SERVER_DOMAIN}"
}
include /etc/nginx/conf.d/server/server.account;
}
server {
server_name account.${SERVER_DOMAIN}; # example: account.eu-ger-1.siasky.net
include /etc/nginx/conf.d/server/server.http;
set_by_lua_block $server_alias { return string.match("${SERVER_DOMAIN}", "^([^.]+)") }
}
server {
server_name account.${SERVER_DOMAIN}; # example: account.eu-ger-1.siasky.net
set_by_lua_block $skynet_portal_domain {
-- when accessing portal directly through server domain, portal domain should be set to server domain
-- motivation: skynet-js uses Skynet-Portal-Api header (that is set to $skynet_portal_domain) to detect current
-- portal address and it should be server domain when accessing specific server by its domain address
return "${SERVER_DOMAIN}"
}
set_by_lua_block $skynet_server_domain { return "${SERVER_DOMAIN}" }
include /etc/nginx/conf.d/server/server.account;
set_by_lua_block $server_alias { return string.match("${SERVER_DOMAIN}", "^([^.]+)") }
}

View File

@ -1,44 +0,0 @@
server {
server_name ${PORTAL_DOMAIN}; # example: siasky.net
include /etc/nginx/conf.d/server/server.http;
}
server {
server_name ${PORTAL_DOMAIN}; # example: siasky.net
set_by_lua_block $skynet_portal_domain { return "${PORTAL_DOMAIN}" }
set_by_lua_block $skynet_server_domain {
-- fall back to portal domain if server domain is not defined
if "${SERVER_DOMAIN}" == "" then
return "${PORTAL_DOMAIN}"
end
return "${SERVER_DOMAIN}"
}
include /etc/nginx/conf.d/server/server.api;
}
server {
server_name ${SERVER_DOMAIN}; # example: eu-ger-1.siasky.net
include /etc/nginx/conf.d/server/server.http;
set_by_lua_block $server_alias { return string.match("${SERVER_DOMAIN}", "^([^.]+)") }
}
server {
server_name ${SERVER_DOMAIN}; # example: eu-ger-1.siasky.net
set_by_lua_block $skynet_portal_domain {
-- when accessing portal directly through server domain, portal domain should be set to server domain
-- motivation: skynet-js uses Skynet-Portal-Api header (that is set to $skynet_portal_domain) to detect current
-- portal address and it should be server domain when accessing specific server by its domain address
return "${SERVER_DOMAIN}"
}
set_by_lua_block $skynet_server_domain { return "${SERVER_DOMAIN}" }
include /etc/nginx/conf.d/server/server.api;
set_by_lua_block $server_alias { return string.match("${SERVER_DOMAIN}", "^([^.]+)") }
}

View File

@ -1,25 +0,0 @@
lua_shared_dict dnslink 10m;
server {
listen 80 default_server;
include /etc/nginx/conf.d/server/server.dnslink;
}
server {
listen 443 default_server;
ssl_certificate /etc/ssl/local-certificate.crt;
ssl_certificate_key /etc/ssl/local-certificate.key;
set_by_lua_block $skynet_portal_domain { return "${PORTAL_DOMAIN}" }
set_by_lua_block $skynet_server_domain {
-- fall back to portal domain if server domain is not defined
if "${SERVER_DOMAIN}" == "" then
return "${PORTAL_DOMAIN}"
end
return "${SERVER_DOMAIN}"
}
include /etc/nginx/conf.d/server/server.dnslink;
}

View File

@ -1,46 +0,0 @@
server {
server_name *.hns.${PORTAL_DOMAIN}; # example: *.hns.siasky.net
include /etc/nginx/conf.d/server/server.http;
}
server {
server_name *.hns.${PORTAL_DOMAIN}; # example: *.hns.siasky.net
set_by_lua_block $skynet_portal_domain { return "${PORTAL_DOMAIN}" }
set_by_lua_block $skynet_server_domain {
-- fall back to portal domain if server domain is not defined
if "${SERVER_DOMAIN}" == "" then
return "${PORTAL_DOMAIN}"
end
return "${SERVER_DOMAIN}"
}
proxy_set_header Host ${PORTAL_DOMAIN};
include /etc/nginx/conf.d/server/server.hns;
}
server {
server_name *.hns.${SERVER_DOMAIN}; # example: *.hns.eu-ger-1.siasky.net
include /etc/nginx/conf.d/server/server.http;
set_by_lua_block $server_alias { return string.match("${SERVER_DOMAIN}", "^([^.]+)") }
}
server {
server_name *.hns.${SERVER_DOMAIN}; # example: *.hns.eu-ger-1.siasky.net
set_by_lua_block $skynet_portal_domain {
-- when accessing portal directly through server domain, portal domain should be set to server domain
-- motivation: skynet-js uses Skynet-Portal-Api header (that is set to $skynet_portal_domain) to detect current
-- portal address and it should be server domain when accessing specific server by its domain address
return "${SERVER_DOMAIN}"
}
set_by_lua_block $skynet_server_domain { return "${SERVER_DOMAIN}" }
proxy_set_header Host ${SERVER_DOMAIN};
include /etc/nginx/conf.d/server/server.hns;
set_by_lua_block $server_alias { return string.match("${SERVER_DOMAIN}", "^([^.]+)") }
}

View File

@ -1,44 +0,0 @@
server {
server_name *.${PORTAL_DOMAIN}; # example: *.siasky.net
include /etc/nginx/conf.d/server/server.http;
}
server {
server_name *.${PORTAL_DOMAIN}; # example: *.siasky.net
set_by_lua_block $skynet_portal_domain { return "${PORTAL_DOMAIN}" }
set_by_lua_block $skynet_server_domain {
-- fall back to portal domain if server domain is not defined
if "${SERVER_DOMAIN}" == "" then
return "${PORTAL_DOMAIN}"
end
return "${SERVER_DOMAIN}"
}
include /etc/nginx/conf.d/server/server.skylink;
}
server {
server_name *.${SERVER_DOMAIN}; # example: *.eu-ger-1.siasky.net
include /etc/nginx/conf.d/server/server.http;
set_by_lua_block $server_alias { return string.match("${SERVER_DOMAIN}", "^([^.]+)") }
}
server {
server_name *.${SERVER_DOMAIN}; # example: *.eu-ger-1.siasky.net
set_by_lua_block $skynet_portal_domain {
-- when accessing portal directly through server domain, portal domain should be set to server domain
-- motivation: skynet-js uses Skynet-Portal-Api header (that is set to $skynet_portal_domain) to detect current
-- portal address and it should be server domain when accessing specific server by its domain address
return "${SERVER_DOMAIN}"
}
set_by_lua_block $skynet_server_domain { return "${SERVER_DOMAIN}" }
include /etc/nginx/conf.d/server/server.skylink;
set_by_lua_block $server_alias { return string.match("${SERVER_DOMAIN}", "^([^.]+)") }
}

View File

@ -1,8 +0,0 @@
-----BEGIN DH PARAMETERS-----
MIIBCAKCAQEA//////////+t+FRYortKmq/cViAnPTzx2LnFg84tNpWp4TZBFGQz
+8yTnc4kmz75fS/jY2MMddj2gbICrsRhetPfHtXV/WVhJDP1H18GbtCFY2VVPe0a
87VXE15/V8k1mE8McODmi3fipona8+/och3xWKE2rec1MKzKT0g6eXq8CrGCsyT7
YdEIqUuyyOP7uWrat2DX9GgdT0Kj3jlN9K5W7edjcrsZCwenyO4KbXCeAvzhzffi
7MA0BM0oNC9hkXL+nOmFg/+OTxIy7vKBg8P+OxtMb61zO7X8vC7CIAXFjvGDfRaD
ssbzSibBsu/6iGtCOGEoXJf//////////wIBAg==
-----END DH PARAMETERS-----

View File

@ -1,18 +0,0 @@
# enables gzip compression
gzip on;
# set the gzip compression level (1-9)
gzip_comp_level 6;
# tells proxies to cache both gzipped and regular versions of a resource
gzip_vary on;
# informs NGINX to not compress anything smaller than the defined size
gzip_min_length 256;
# compress data even for clients that are connecting via proxies if a response header includes
# the "expired", "no-cache", "no-store", "private", and "Authorization" parameters
gzip_proxied expired no-cache no-store private auth;
# enables the types of files that can be compressed
gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/vnd.ms-fontobject application/x-font-ttf font/opentype image/svg+xml image/x-icon;

View File

@ -1,9 +0,0 @@
if ($request_method = 'OPTIONS') {
include /etc/nginx/conf.d/include/cors-headers;
more_set_headers 'Access-Control-Max-Age: 1728000';
more_set_headers 'Content-Type: text/plain; charset=utf-8';
more_set_headers 'Content-Length: 0';
return 204;
}
include /etc/nginx/conf.d/include/cors-headers;

View File

@ -1,5 +0,0 @@
more_set_headers 'Access-Control-Allow-Origin: $http_origin';
more_set_headers 'Access-Control-Allow-Credentials: true';
more_set_headers 'Access-Control-Allow-Methods: GET, POST, HEAD, OPTIONS, PUT, PATCH, DELETE';
more_set_headers 'Access-Control-Allow-Headers: DNT,User-Agent,X-Requested-With,If-Modified-Since,If-None-Match,Cache-Control,Content-Type,Range,X-HTTP-Method-Override,upload-offset,upload-metadata,upload-length,tus-version,tus-resumable,tus-extension,tus-max-size,upload-concat,location,Skynet-API-Key';
more_set_headers 'Access-Control-Expose-Headers: Content-Length,Content-Range,ETag,Accept-Ranges,Skynet-File-Metadata,Skynet-Skylink,Skynet-Proof,Skynet-Portal-Api,Skynet-Server-Api,upload-offset,upload-metadata,upload-length,tus-version,tus-resumable,tus-extension,tus-max-size,upload-concat,location';

View File

@ -1,11 +0,0 @@
# Extract 2 sets of 2 characters from $request_id and assign to $dir1, $dir2
# respectfully. The rest of the $request_id is going to be assigned to $dir3.
# We use those variables to automatically generate a unique path for the uploaded file.
# This ensures that not all uploaded files end up in the same directory, which is something
# that causes performance issues in the renter.
# Example path result: /af/24/9bc5ec894920ccc45634dc9a8065
if ($request_id ~* "(\w{2})(\w{2})(\w+)") {
set $dir1 $1;
set $dir2 $2;
set $dir3 $3;
}

View File

@ -1,15 +0,0 @@
# optional variables initialisation - those variables are used in log_format
# but are not set on every route so we need to initialise them with empty value
# because otherwise logger with throw error
# set only on hns routes
set $hns_domain "";
# set only if server has been access through SERVER_DOMAIN
set $server_alias "";
# expose skylink variable so we can use it in access log
set $skylink "";
# cached account limits (json string) - applies only if accounts are enabled
set $account_limits "";

View File

@ -1,3 +0,0 @@
allow 127.0.0.1/32; # localhost
allow 10.10.10.0/24; # docker network
deny all;

View File

@ -1,94 +0,0 @@
include /etc/nginx/conf.d/include/proxy-pass-internal;
include /etc/nginx/conf.d/include/portal-access-check;
# variable definititions - we need to define a variable to be able to access it in lua by ngx.var.something
set $skylink ''; # placeholder for the raw 46 bit skylink
# resolve handshake domain by requesting to /hnsres endpoint and assign correct values to $skylink and $rest
rewrite_by_lua_block {
local json = require('cjson')
local httpc = require("resty.http").new()
-- make a get request to /hnsres endpoint with the domain name from request_uri
-- 10.10.10.50 points to handshake-api service (alias not available when using resty-http)
local hnsres_res, hnsres_err = httpc:request_uri("http://10.10.10.50:3100/hnsres/" .. ngx.var.hns_domain)
-- print error and exit with 500 or exit with response if status is not 200
if hnsres_err or (hnsres_res and hnsres_res.status ~= ngx.HTTP_OK) then
ngx.status = (hnsres_err and ngx.HTTP_INTERNAL_SERVER_ERROR) or hnsres_res.status
ngx.header["content-type"] = "text/plain"
ngx.say(hnsres_err or hnsres_res.body)
return ngx.exit(ngx.status)
end
-- since /hnsres endpoint response is a json, we need to decode it before we access it
-- example response: '{"skylink":"sia://XABvi7JtJbQSMAcDwnUnmp2FKDPjg8_tTTFP4BwMSxVdEg"}'
local hnsres_json = json.decode(hnsres_res.body)
-- define local variable containing rest of the skylink if provided
local skylink_rest
if hnsres_json.skylink then
-- try to match the skylink with sia:// prefix
skylink, skylink_rest = string.match(hnsres_json.skylink, "sia://([^/?]+)(.*)")
-- in case the skylink did not match, assume that there is no sia:// prefix and try to match again
if skylink == nil then
skylink, skylink_rest = string.match(hnsres_json.skylink, "/?([^/?]+)(.*)")
end
elseif hnsres_json.registry then
local publickey = hnsres_json.registry.publickey
local datakey = hnsres_json.registry.datakey
-- make a get request to /skynet/registry endpoint with the credentials from text record
-- 10.10.10.10 points to sia service (alias not available when using resty-http)
local registry_res, registry_err = httpc:request_uri("http://10.10.10.10:9980/skynet/registry?publickey=" .. publickey .. "&datakey=" .. datakey, {
headers = { ["User-Agent"] = "Sia-Agent" }
})
-- print error and exit with 500 or exit with response if status is not 200
if registry_err or (registry_res and registry_res.status ~= ngx.HTTP_OK) then
ngx.status = (registry_err and ngx.HTTP_INTERNAL_SERVER_ERROR) or registry_res.status
ngx.header["content-type"] = "text/plain"
ngx.say(registry_err or registry_res.body)
return ngx.exit(ngx.status)
end
-- since /skynet/registry endpoint response is a json, we need to decode it before we access it
local registry_json = json.decode(registry_res.body)
-- response will contain a hex encoded skylink, we need to decode it
local data = (registry_json.data:gsub('..', function (cc)
return string.char(tonumber(cc, 16))
end))
skylink = data
end
-- fail with a generic 404 if skylink has not been extracted from a valid /hnsres response for some reason
if not skylink then
return ngx.exit(ngx.HTTP_NOT_FOUND)
end
ngx.var.skylink = skylink
if ngx.var.path == "/" and skylink_rest ~= nil and skylink_rest ~= "" and skylink_rest ~= "/" then
ngx.var.path = skylink_rest
end
}
# we proxy to another nginx location rather than directly to siad because we do not want to deal with caching here
proxy_pass https://127.0.0.1/$skylink$path$is_args$args;
# in case siad returns location header, we need to replace the skylink with the domain name
header_filter_by_lua_block {
ngx.header["Skynet-Portal-Api"] = ngx.var.scheme .. "://" .. ngx.var.skynet_portal_domain
ngx.header["Skynet-Server-Api"] = ngx.var.scheme .. "://" .. ngx.var.skynet_server_domain
if ngx.header.location then
-- match location redirect part after the skylink
local path = string.match(ngx.header.location, "[^/?]+(.*)");
-- because siad will set the location header to ie. XABvi7JtJbQSMAcDwnUnmp2FKDPjg8_tTTFP4BwMSxVdEg/index.html
-- we need to replace the skylink with the domain_name so we are not redirected to skylink
ngx.header.location = ngx.var.hns_domain .. path
end
}

View File

@ -1,53 +0,0 @@
include /etc/nginx/conf.d/include/cors;
limit_conn downloads_by_ip 100; # ddos protection: max 100 downloads at a time
# ensure that skylink that we pass around is base64 encoded (transform base32 encoded ones)
# this is important because we want only one format in cache keys and logs
set_by_lua_block $skylink { return require("skynet.skylink").parse(ngx.var.skylink) }
# default download rate to unlimited
set $limit_rate 0;
access_by_lua_block {
if require("skynet.account").accounts_enabled() then
-- check if portal is in authenticated only mode
if require("skynet.account").is_access_unauthorized() then
return require("skynet.account").exit_access_unauthorized()
end
-- check if portal is in subscription only mode
if require("skynet.account").is_access_forbidden() then
return require("skynet.account").exit_access_forbidden()
end
-- get account limits of currently authenticated user
local limits = require("skynet.account").get_account_limits()
-- apply download speed limit
ngx.var.limit_rate = limits.download
end
}
limit_rate_after 512k;
limit_rate $limit_rate;
proxy_read_timeout 600;
proxy_set_header User-Agent: Sia-Agent;
proxy_pass http://sia:9980/skynet/skylink/$skylink$path$is_args$args;
log_by_lua_block {
local skynet_account = require("skynet.account")
local skynet_modules = require("skynet.modules")
local skynet_scanner = require("skynet.scanner")
local skynet_tracker = require("skynet.tracker")
if skynet_modules.is_enabled("a") then
skynet_tracker.track_download(ngx.header["Skynet-Skylink"], ngx.status, skynet_account.get_auth_headers(), ngx.var.body_bytes_sent)
end
if skynet_modules.is_enabled("s") then
skynet_scanner.scan_skylink(ngx.header["Skynet-Skylink"])
end
}

View File

@ -1,38 +0,0 @@
include /etc/nginx/conf.d/include/cors;
include /etc/nginx/conf.d/include/sia-auth;
limit_req zone=registry_access_by_ip burst=600 nodelay;
limit_req zone=registry_access_by_ip_throttled burst=200 nodelay;
proxy_set_header User-Agent: Sia-Agent;
proxy_read_timeout 600; # siad should timeout with 404 after 5 minutes
proxy_pass http://sia:9980/skynet/registry;
access_by_lua_block {
if require("skynet.account").accounts_enabled() then
-- check if portal is in authenticated only mode
if require("skynet.account").is_access_unauthorized() then
return require("skynet.account").exit_access_unauthorized()
end
-- check if portal is in subscription only mode
if require("skynet.account").is_access_forbidden() then
return require("skynet.account").exit_access_forbidden()
end
-- get account limits of currently authenticated user
local limits = require("skynet.account").get_account_limits()
-- apply registry rate limits (forced delay)
if limits.registry > 0 then
ngx.sleep(limits.registry / 1000)
end
end
}
log_by_lua_block {
local skynet_account = require("skynet.account")
local skynet_tracker = require("skynet.tracker")
skynet_tracker.track_registry(ngx.status, skynet_account.get_auth_headers(), ngx.req.get_method())
}

View File

@ -1,11 +0,0 @@
access_by_lua_block {
-- check portal access rules and exit if access is restricted
if require("skynet.account").is_access_unauthorized() then
return require("skynet.account").exit_access_unauthorized()
end
-- check if portal is in subscription only mode
if require("skynet.account").is_access_forbidden() then
return require("skynet.account").exit_access_forbidden()
end
}

View File

@ -1,10 +0,0 @@
# ----------------------------------------------------------------
# this file should be included on all locations that proxy_pass to
# another nginx location - internal nginx traffic
# ----------------------------------------------------------------
# increase the timeout on internal nginx proxy_pass locations to a
# value that is significantly higher than expected and let the end
# location handle correct timeout
proxy_read_timeout 30m;
proxy_send_timeout 30m;

View File

@ -1,6 +0,0 @@
# Add a list of IPs here that should be severely rate limited on upload.
# Note that it is possible to add IP ranges as well as the full IP address.
#
# Examples:
# 192.168.0.0/24 1;
# 79.85.222.247 1;

View File

@ -1,4 +0,0 @@
rewrite_by_lua_block {
-- set basic authorization header with base64 encoded apipassword
ngx.req.set_header("Authorization", require("skynet.utils").authorization_header())
}

View File

@ -1,26 +0,0 @@
# https://ssl-config.mozilla.org/#server=nginx&version=1.17.7&config=intermediate&openssl=1.1.1d&hsts=false&ocsp=false&guideline=5.6
ssl_certificate /etc/letsencrypt/live/skynet-portal/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/skynet-portal/privkey.pem;
ssl_session_timeout 1d;
ssl_session_cache shared:MozSSL:10m; # about 40000 sessions
ssl_session_tickets off;
# curl https://ssl-config.mozilla.org/ffdhe2048.txt > /path/to/dhparam
ssl_dhparam /etc/nginx/conf.d/dhparam.pem;
# intermediate configuration
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
# HSTS (ngx_http_headers_module is required) (63072000 seconds)
add_header Strict-Transport-Security "max-age=63072000" always;
# OCSP stapling
ssl_stapling on;
ssl_stapling_verify on;
# verify chain of trust of OCSP response using Root CA and Intermediate certs
ssl_trusted_certificate /etc/letsencrypt/live/skynet-portal/chain.pem;

View File

@ -1,7 +0,0 @@
# Every file from within this directory will be included in the server block
# of the nginx configuration, at the very end. See client.conf.
#
# Example:
# location /blog {
# root /var/www/blog;
# }

View File

@ -1,46 +0,0 @@
listen 443 ssl http2;
include /etc/nginx/conf.d/include/ssl-settings;
include /etc/nginx/conf.d/include/init-optional-variables;
# Uncomment to launch new Dashboard under /v2 path
location / {
proxy_pass http://dashboard-v2:9000;
}
location /health {
proxy_pass http://accounts:3000;
}
location /api {
rewrite /api/(.*) /$1 break;
proxy_pass http://accounts:3000;
}
location /api/register {
include /etc/nginx/conf.d/include/cors;
rewrite /api/(.*) /$1 break;
proxy_pass http://accounts:3000;
}
location /api/user/pubkey/register {
include /etc/nginx/conf.d/include/cors;
rewrite /api/(.*) /$1 break;
proxy_pass http://accounts:3000;
}
location /api/login {
include /etc/nginx/conf.d/include/cors;
rewrite /api/(.*) /$1 break;
proxy_pass http://accounts:3000;
}
location /api/logout {
include /etc/nginx/conf.d/include/cors;
rewrite /api/(.*) /$1 break;
proxy_pass http://accounts:3000;
}

View File

@ -1,495 +0,0 @@
listen 443 ssl http2;
include /etc/nginx/conf.d/include/ssl-settings;
include /etc/nginx/conf.d/include/init-optional-variables;
# ddos protection: closing slow connections
client_body_timeout 1h;
client_header_timeout 1h;
send_timeout 1h;
proxy_connect_timeout 1h;
proxy_read_timeout 1h;
proxy_send_timeout 1h;
# Increase the body buffer size, to ensure the internal POSTs can always
# parse the full POST contents into memory.
client_body_buffer_size 128k;
client_max_body_size 128k;
# legacy endpoint rewrite
rewrite ^/portals /skynet/portals permanent;
rewrite ^/stats /skynet/stats permanent;
rewrite ^/skynet/blacklist /skynet/blocklist permanent;
rewrite ^/docs(?:/(.*))?$ https://sdk.skynetlabs.com/$1 permanent;
location / {
include /etc/nginx/conf.d/include/cors;
proxy_pass http://website:9000;
}
location /skynet/blocklist {
include /etc/nginx/conf.d/include/cors;
add_header X-Proxy-Cache $upstream_cache_status;
proxy_cache skynet;
proxy_cache_valid any 1m; # cache blocklist for 1 minute
proxy_set_header User-Agent: Sia-Agent;
proxy_pass http://sia:9980/skynet/blocklist;
}
location /skynet/portal/blocklist {
include /etc/nginx/conf.d/include/cors;
add_header X-Proxy-Cache $upstream_cache_status;
proxy_cache skynet;
proxy_cache_valid 200 204 15m; # cache portal blocklist for 15 minutes
# 10.10.10.110 points to blocker service
proxy_pass http://10.10.10.110:4000/blocklist;
}
location /skynet/portals {
include /etc/nginx/conf.d/include/cors;
add_header X-Proxy-Cache $upstream_cache_status;
proxy_cache skynet;
proxy_cache_valid any 1m; # cache portals for 1 minute
proxy_set_header User-Agent: Sia-Agent;
proxy_pass http://sia:9980/skynet/portals;
}
location /skynet/stats {
include /etc/nginx/conf.d/include/cors;
add_header X-Proxy-Cache $upstream_cache_status;
proxy_cache skynet;
proxy_cache_valid any 1m; # cache stats for 1 minute
proxy_set_header User-Agent: Sia-Agent;
proxy_read_timeout 5m; # extend the read timeout
proxy_pass http://sia:9980/skynet/stats;
}
# Define path for server load endpoint
location /serverload {
# Define root directory in the nginx container to load file from
root /usr/local/share;
# including this because of peer pressure from the other routes
include /etc/nginx/conf.d/include/cors;
# tell nginx to expect json
default_type 'application/json';
# Allow for /serverload to load /serverload.json file
try_files $uri $uri.json =404;
}
location /skynet/health {
include /etc/nginx/conf.d/include/cors;
add_header X-Proxy-Cache $upstream_cache_status;
proxy_cache skynet;
proxy_cache_key $request_uri; # use whole request uri (uri + args) as cache key
proxy_cache_valid any 1m; # cache responses for 1 minute
proxy_set_header User-Agent: Sia-Agent;
proxy_read_timeout 5m; # extend the read timeout
proxy_pass http://sia:9980;
}
location /health-check {
include /etc/nginx/conf.d/include/cors;
access_log off; # do not log traffic to health-check endpoint
proxy_pass http://10.10.10.60:3100; # hardcoded ip because health-check waits for nginx
}
location /abuse {
return 308 /0404guluqu38oaqapku91ed11kbhkge55smh9lhjukmlrj37lfpm8no/;
}
location /abuse/report {
include /etc/nginx/conf.d/include/cors;
# 10.10.10.110 points to blocker service
proxy_pass http://10.10.10.110:4000/powblock;
}
location /hns {
include /etc/nginx/conf.d/include/cors;
# match the request_uri and extract the hns domain and anything that is passed in the uri after it
# example: /hns/something/foo/bar matches:
# > hns_domain: something
# > path: /foo/bar/
set_by_lua_block $hns_domain { return string.match(ngx.var.uri, "/hns/([^/?]+)") }
set_by_lua_block $path { return string.match(ngx.var.uri, "/hns/[^/?]+(.*)") }
proxy_set_header Host $host;
include /etc/nginx/conf.d/include/location-hns;
}
location /hnsres {
include /etc/nginx/conf.d/include/cors;
include /etc/nginx/conf.d/include/portal-access-check;
proxy_pass http://handshake-api:3100;
}
location /skynet/registry {
include /etc/nginx/conf.d/include/location-skynet-registry;
}
location /skynet/restore {
include /etc/nginx/conf.d/include/cors;
include /etc/nginx/conf.d/include/sia-auth;
include /etc/nginx/conf.d/include/portal-access-check;
client_max_body_size 5M;
# increase request timeouts
proxy_read_timeout 600;
proxy_send_timeout 600;
proxy_request_buffering off; # stream uploaded files through the proxy as it comes in
proxy_set_header Expect $http_expect;
proxy_set_header User-Agent: Sia-Agent;
# proxy this call to siad endpoint (make sure the ip is correct)
proxy_pass http://sia:9980;
}
location /skynet/registry/subscription {
include /etc/nginx/conf.d/include/cors;
# default to unlimited bandwidth and no delay
set $bandwidthlimit "0";
set $notificationdelay "0";
rewrite_by_lua_block {
local skynet_account = require("skynet.account")
if skynet_account.accounts_enabled() then
-- check if portal is in authenticated only mode
if skynet_account.is_access_unauthorized() then
return skynet_account.exit_access_unauthorized()
end
-- check if portal is in subscription only mode
if skynet_account.is_access_forbidden() then
return skynet_account.exit_access_forbidden()
end
-- get account limits of currently authenticated user
local limits = skynet_account.get_account_limits()
-- apply bandwidth limit and notification delay
ngx.var.bandwidthlimit = limits.download
ngx.var.notificationdelay = limits.registry
end
}
proxy_set_header User-Agent: Sia-Agent;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_pass http://sia:9980/skynet/registry/subscription?bandwidthlimit=$bandwidthlimit&notificationdelay=$notificationdelay;
}
location /skynet/skyfile {
include /etc/nginx/conf.d/include/cors;
include /etc/nginx/conf.d/include/sia-auth;
include /etc/nginx/conf.d/include/generate-siapath;
include /etc/nginx/conf.d/include/portal-access-check;
limit_req zone=uploads_by_ip burst=10 nodelay;
limit_req zone=uploads_by_ip_throttled;
limit_conn upload_conn 5;
limit_conn upload_conn_rl 1;
client_max_body_size 5000M; # make sure to limit the size of upload to a sane value
# increase request timeouts
proxy_read_timeout 600;
proxy_send_timeout 600;
proxy_request_buffering off; # stream uploaded files through the proxy as it comes in
proxy_set_header Expect $http_expect;
proxy_set_header User-Agent: Sia-Agent;
# proxy this call to siad endpoint (make sure the ip is correct)
proxy_pass http://sia:9980/skynet/skyfile/$dir1/$dir2/$dir3$is_args$args;
log_by_lua_block {
local skynet_account = require("skynet.account")
local skynet_modules = require("skynet.modules")
local skynet_scanner = require("skynet.scanner")
local skynet_tracker = require("skynet.tracker")
if skynet_modules.is_enabled("a") then
skynet_tracker.track_upload(
ngx.header["Skynet-Skylink"],
ngx.status,
skynet_account.get_auth_headers(),
ngx.var.remote_addr
)
end
if skynet_modules.is_enabled("s") then
skynet_scanner.scan_skylink(ngx.header["Skynet-Skylink"])
end
}
}
# endpoint implementing resumable file uploads open protocol https://tus.io
location /skynet/tus {
include /etc/nginx/conf.d/include/cors-headers; # include cors headers but do not overwrite OPTIONS response
limit_req zone=uploads_by_ip burst=10 nodelay;
limit_req zone=uploads_by_ip_throttled;
limit_conn upload_conn 5;
limit_conn upload_conn_rl 1;
# Do not limit body size in nginx, skyd will reject early on too large upload
client_max_body_size 0;
# Those timeouts need to be elevated since skyd can stall reading
# data for a while when overloaded which would terminate connection
client_body_timeout 1h;
proxy_send_timeout 1h;
# Add X-Forwarded-* headers
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
# rewrite proxy request to use correct host uri from env variable (required to return correct location header)
proxy_redirect $scheme://$host $scheme://$skynet_server_domain;
# proxy /skynet/tus requests to siad endpoint with all arguments
proxy_pass http://sia:9980;
access_by_lua_block {
local skynet_account = require("skynet.account")
if skynet_account.accounts_enabled() then
-- check if portal is in authenticated only mode
if skynet_account.is_access_unauthorized() then
return skynet_account.exit_access_unauthorized()
end
-- check if portal is in subscription only mode
if skynet_account.is_access_forbidden() then
return skynet_account.exit_access_forbidden()
end
-- get account limits of currently authenticated user
local limits = skynet_account.get_account_limits()
-- apply upload size limits
ngx.req.set_header("SkynetMaxUploadSize", limits.maxUploadSize)
end
}
# extract skylink from base64 encoded upload metadata and assign to a proper header
header_filter_by_lua_block {
ngx.header["Skynet-Portal-Api"] = ngx.var.scheme .. "://" .. ngx.var.skynet_portal_domain
ngx.header["Skynet-Server-Api"] = ngx.var.scheme .. "://" .. ngx.var.skynet_server_domain
if ngx.header["Upload-Metadata"] then
local encodedSkylink = string.match(ngx.header["Upload-Metadata"], "Skylink ([^,?]+)")
if encodedSkylink then
ngx.header["Skynet-Skylink"] = ngx.decode_base64(encodedSkylink)
end
end
}
log_by_lua_block {
local skynet_account = require("skynet.account")
local skynet_modules = require("skynet.modules")
local skynet_scanner = require("skynet.scanner")
local skynet_tracker = require("skynet.tracker")
if skynet_modules.is_enabled("a") then
skynet_tracker.track_upload(
ngx.header["Skynet-Skylink"],
ngx.status,
skynet_account.get_auth_headers(),
ngx.var.remote_addr
)
end
if skynet_modules.is_enabled("s") then
skynet_scanner.scan_skylink(ngx.header["Skynet-Skylink"])
end
}
}
location /skynet/pin {
include /etc/nginx/conf.d/include/cors;
include /etc/nginx/conf.d/include/sia-auth;
include /etc/nginx/conf.d/include/generate-siapath;
include /etc/nginx/conf.d/include/portal-access-check;
limit_req zone=uploads_by_ip burst=10 nodelay;
limit_req zone=uploads_by_ip_throttled;
limit_conn upload_conn 5;
limit_conn upload_conn_rl 1;
proxy_set_header User-Agent: Sia-Agent;
proxy_pass http://sia:9980$uri?siapath=$dir1/$dir2/$dir3&$args;
log_by_lua_block {
local skynet_account = require("skynet.account")
local skynet_modules = require("skynet.modules")
local skynet_scanner = require("skynet.scanner")
local skynet_tracker = require("skynet.tracker")
if skynet_modules.is_enabled("a") then
skynet_tracker.track_upload(
ngx.header["Skynet-Skylink"],
ngx.status,
skynet_account.get_auth_headers(),
ngx.var.remote_addr
)
end
if skynet_modules.is_enabled("s") then
skynet_scanner.scan_skylink(ngx.header["Skynet-Skylink"])
end
}
}
location /skynet/metadata {
include /etc/nginx/conf.d/include/cors;
include /etc/nginx/conf.d/include/portal-access-check;
header_filter_by_lua_block {
ngx.header["Skynet-Portal-Api"] = ngx.var.scheme .. "://" .. ngx.var.skynet_portal_domain
ngx.header["Skynet-Server-Api"] = ngx.var.scheme .. "://" .. ngx.var.skynet_server_domain
}
proxy_set_header User-Agent: Sia-Agent;
proxy_pass http://sia:9980;
}
location /skynet/resolve {
include /etc/nginx/conf.d/include/cors;
include /etc/nginx/conf.d/include/portal-access-check;
header_filter_by_lua_block {
ngx.header["Skynet-Portal-Api"] = ngx.var.scheme .. "://" .. ngx.var.skynet_portal_domain
ngx.header["Skynet-Server-Api"] = ngx.var.scheme .. "://" .. ngx.var.skynet_server_domain
}
proxy_set_header User-Agent: Sia-Agent;
proxy_pass http://sia:9980;
}
location ~ "^/(([a-zA-Z0-9-_]{46}|[a-z0-9]{55})(/.*)?)$" {
set $skylink $2;
set $path $3;
include /etc/nginx/conf.d/include/location-skylink;
}
location ~ "^/file/(([a-zA-Z0-9-_]{46}|[a-z0-9]{55})(/.*)?)$" {
set $skylink $2;
set $path $3;
set $args attachment=true&$args;
#set $is_args ?;
include /etc/nginx/conf.d/include/location-skylink;
}
location /skynet/trustless/basesector {
include /etc/nginx/conf.d/include/cors;
limit_conn downloads_by_ip 100; # ddos protection: max 100 downloads at a time
# default download rate to unlimited
set $limit_rate 0;
access_by_lua_block {
local skynet_account = require("skynet.account")
if skynet_account.accounts_enabled() then
-- check if portal is in authenticated only mode
if skynet_account.is_access_unauthorized() then
return skynet_account.exit_access_unauthorized()
end
-- check if portal is in subscription only mode
if skynet_account.is_access_forbidden() then
return skynet_account.exit_access_forbidden()
end
-- get account limits of currently authenticated user
local limits = skynet_account.get_account_limits()
-- apply download speed limit
ngx.var.limit_rate = limits.download
end
}
limit_rate_after 512k;
limit_rate $limit_rate;
proxy_set_header User-Agent: Sia-Agent;
proxy_pass http://sia:9980;
log_by_lua_block {
local skynet_account = require("skynet.account")
local skynet_modules = require("skynet.modules")
local skynet_scanner = require("skynet.scanner")
local skynet_tracker = require("skynet.tracker")
if skynet_modules.is_enabled("a") then
skynet_tracker.track_download(ngx.header["Skynet-Skylink"], ngx.status, skynet_account.get_auth_headers(), ngx.var.body_bytes_sent)
end
if skynet_modules.is_enabled("s") then
skynet_scanner.scan_skylink(ngx.header["Skynet-Skylink"])
end
}
}
location /__internal/do/not/use/accounts {
include /etc/nginx/conf.d/include/cors;
charset utf-8;
charset_types application/json;
default_type application/json;
content_by_lua_block {
local json = require('cjson')
local skynet_account = require("skynet.account")
local accounts_enabled = skynet_account.accounts_enabled()
local is_auth_required = skynet_account.is_auth_required()
local is_subscription_required = skynet_account.is_subscription_required()
local is_authenticated = skynet_account.is_authenticated()
local has_subscription = skynet_account.has_subscription()
ngx.say(json.encode{
enabled = accounts_enabled,
auth_required = is_auth_required,
subscription_required = is_subscription_required,
authenticated = is_authenticated,
subscription = has_subscription,
})
return ngx.exit(ngx.HTTP_OK)
}
}
include /etc/nginx/conf.d/server-override/*;

View File

@ -1,55 +0,0 @@
include /etc/nginx/conf.d/include/init-optional-variables;
location / {
set $skylink "";
set $path $uri;
rewrite_by_lua_block {
local cjson = require("cjson")
local cache = ngx.shared.dnslink
local cache_value = cache:get(ngx.var.host)
if cache_value == nil then
local httpc = require("resty.http").new()
-- 10.10.10.55 points to dnslink-api service (alias not available when using resty-http)
local res, err = httpc:request_uri("http://10.10.10.55:3100/dnslink/" .. ngx.var.host)
if err or (res and res.status ~= ngx.HTTP_OK) then
-- check whether we can fallback to regular skylink request
local match_skylink = ngx.re.match(ngx.var.uri, "^/([a-zA-Z0-9-_]{46}|[a-z0-9]{55})(/.*)?")
if match_skylink then
ngx.var.skylink = match_skylink[1]
ngx.var.path = match_skylink[2] or "/"
else
ngx.status = (err and ngx.HTTP_INTERNAL_SERVER_ERROR) or res.status
ngx.header["content-type"] = "text/plain"
ngx.say(err or res.body)
ngx.exit(ngx.status)
end
else
local resolved = cjson.decode(res.body)
ngx.var.skylink = resolved.skylink
if resolved.sponsor then
ngx.req.set_header("Skynet-Api-Key", resolved.sponsor)
end
local cache_ttl = 300 -- 5 minutes cache expire time
cache:set(ngx.var.host, res.body, cache_ttl)
end
else
local resolved = cjson.decode(cache_value)
ngx.var.skylink = resolved.skylink
if resolved.sponsor then
ngx.req.set_header("Skynet-Api-Key", resolved.sponsor)
end
end
ngx.var.skylink = require("skynet.skylink").parse(ngx.var.skylink)
}
include /etc/nginx/conf.d/include/location-skylink;
}

View File

@ -1,11 +0,0 @@
listen 443 ssl http2;
include /etc/nginx/conf.d/include/ssl-settings;
include /etc/nginx/conf.d/include/init-optional-variables;
location / {
set_by_lua_block $hns_domain { return string.match(ngx.var.host, "[^%.]+") }
set $path $uri;
include /etc/nginx/conf.d/include/location-hns;
}

View File

@ -1,7 +0,0 @@
listen 80;
include /etc/nginx/conf.d/include/init-optional-variables;
location / {
return 301 https://$host$request_uri;
}

View File

@ -1,16 +0,0 @@
listen 443 ssl http2;
include /etc/nginx/conf.d/include/ssl-settings;
include /etc/nginx/conf.d/include/init-optional-variables;
location / {
set_by_lua_block $skylink { return string.match(ngx.var.host, "%w+") }
set_by_lua_block $path {
-- strip ngx.var.request_uri from query params - this is basically the same as ngx.var.uri but
-- do not use ngx.var.uri because it will already be unescaped and we need to use escaped path
-- examples: escaped uri "/b%20r56+7" and unescaped uri "/b r56 7"
return string.gsub(ngx.var.request_uri, "?.*", "")
}
include /etc/nginx/conf.d/include/location-skylink;
}

View File

@ -1,59 +0,0 @@
#!/bin/sh
# https://github.com/nginxinc/docker-nginx/blob/master/entrypoint/20-envsubst-on-templates.sh
# https://github.com/nginxinc/docker-nginx/blob/master/LICENSE
# Copyright (C) 2011-2016 Nginx, Inc.
# All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
set -e
ME=$(basename $0)
auto_envsubst() {
local template_dir="${NGINX_ENVSUBST_TEMPLATE_DIR:-/etc/nginx/templates}"
local suffix="${NGINX_ENVSUBST_TEMPLATE_SUFFIX:-.template}"
local output_dir="${NGINX_ENVSUBST_OUTPUT_DIR:-/etc/nginx/conf.d}"
local template defined_envs relative_path output_path subdir
defined_envs=$(printf '${%s} ' $(env | cut -d= -f1))
[ -d "$template_dir" ] || return 0
if [ ! -w "$output_dir" ]; then
echo >&3 "$ME: ERROR: $template_dir exists, but $output_dir is not writable"
return 0
fi
find "$template_dir" -follow -type f -name "*$suffix" -print | while read -r template; do
relative_path="${template#$template_dir/}"
output_path="$output_dir/${relative_path%$suffix}"
subdir=$(dirname "$relative_path")
# create a subdirectory where the template file exists
mkdir -p "$output_dir/$subdir"
echo >&3 "$ME: Running envsubst on $template to $output_path"
envsubst "$defined_envs" < "$template" > "$output_path"
done
}
auto_envsubst
exit 0

View File

@ -1,20 +0,0 @@
#!/bin/sh
# source: https://github.com/nginxinc/docker-nginx/pull/509
set -e
ME=$(basename $0)
[ "${NGINX_ENTRYPOINT_RELOAD_EVERY_X_HOURS:-}" ] || exit 0
if [ $(echo "$NGINX_ENTRYPOINT_RELOAD_EVERY_X_HOURS > 0" | bc) = 0 ]; then
echo >&3 "$ME: Error. Provide integer or floating point number greater that 0. See 'man sleep'."
exit 1
fi
start_background_reload() {
echo >&3 "$ME: Reloading Nginx every $NGINX_ENTRYPOINT_RELOAD_EVERY_X_HOURS hour(s)"
while :; do sleep ${NGINX_ENTRYPOINT_RELOAD_EVERY_X_HOURS}h; echo >&3 "$ME: Reloading Nginx ..." && nginx -s reload; done &
}
start_background_reload

View File

@ -1,18 +0,0 @@
#!/bin/sh
# Generate locally signed ssl certificate to be used on routes
# that do not require certificate issued by trusted CA
set -e
ME=$(basename $0)
generate_local_certificate() {
echo >&3 "$ME: Generating locally signed ssl certificate"
openssl req -new -newkey rsa:2048 -days 3650 -nodes -x509 \
-subj '/CN=local-certificate' \
-keyout /etc/ssl/local-certificate.key \
-out /etc/ssl/local-certificate.crt
}
generate_local_certificate

View File

@ -1,78 +0,0 @@
#!/bin/sh
# vim:sw=4:ts=4:et
# https://github.com/nginxinc/docker-nginx/blob/master/entrypoint/docker-entrypoint.sh
# https://github.com/nginxinc/docker-nginx/blob/master/LICENSE
# Copyright (C) 2011-2016 Nginx, Inc.
# All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
set -e
if [ -z "${NGINX_ENTRYPOINT_QUIET_LOGS:-}" ]; then
exec 3>&1
else
exec 3>/dev/null
fi
# Really dirty backwards compatible workaround for single server portals:
# =======================================================================
# in the past we used to require single server portals not to include
# server domain env variable because it messed up with caddy; we switched
# to certbot and that is not the case any more but we also switched to
# using built in envsubst instead of custom mustache script for nginx
# templating and now when server domain is not defined, it messes up whole
# nginx config and nginx will not start; this workaround assigns portal
# domain as a server domain if server domain is not defined
if [ -z "${SERVER_DOMAIN}" ]; then
export SERVER_DOMAIN=${PORTAL_DOMAIN}
fi
if [ "$1" = "nginx" -o "$1" = "nginx-debug" ]; then
if /usr/bin/find "/docker-entrypoint.d/" -mindepth 1 -maxdepth 1 -type f -print -quit 2>/dev/null | read v; then
echo >&3 "$0: /docker-entrypoint.d/ is not empty, will attempt to perform configuration"
echo >&3 "$0: Looking for shell scripts in /docker-entrypoint.d/"
find "/docker-entrypoint.d/" -follow -type f -print | sort -V | while read -r f; do
case "$f" in
*.sh)
if [ -x "$f" ]; then
echo >&3 "$0: Launching $f";
"$f"
else
# warn on shell scripts without exec bit
echo >&3 "$0: Ignoring $f, not executable";
fi
;;
*) echo >&3 "$0: Ignoring $f";;
esac
done
echo >&3 "$0: Configuration complete; ready for start up"
else
echo >&3 "$0: No files found in /docker-entrypoint.d/, skipping configuration"
fi
fi
exec "$@"

View File

@ -1,301 +0,0 @@
-- source: https://github.com/aiq/basexx
-- license: MIT
-- modified: exposed from_basexx and to_basexx generic functions
--------------------------------------------------------------------------------
-- util functions
--------------------------------------------------------------------------------
local function divide_string( str, max )
local result = {}
local start = 1
for i = 1, #str do
if i % max == 0 then
table.insert( result, str:sub( start, i ) )
start = i + 1
elseif i == #str then
table.insert( result, str:sub( start, i ) )
end
end
return result
end
local function number_to_bit( num, length )
local bits = {}
while num > 0 do
local rest = math.floor( math.fmod( num, 2 ) )
table.insert( bits, rest )
num = ( num - rest ) / 2
end
while #bits < length do
table.insert( bits, "0" )
end
return string.reverse( table.concat( bits ) )
end
local function ignore_set( str, set )
if set then
str = str:gsub( "["..set.."]", "" )
end
return str
end
local function pure_from_bit( str )
return ( str:gsub( '........', function ( cc )
return string.char( tonumber( cc, 2 ) )
end ) )
end
local function unexpected_char_error( str, pos )
local c = string.sub( str, pos, pos )
return string.format( "unexpected character at position %d: '%s'", pos, c )
end
--------------------------------------------------------------------------------
local basexx = {}
--------------------------------------------------------------------------------
-- base2(bitfield) decode and encode function
--------------------------------------------------------------------------------
local bitMap = { o = "0", i = "1", l = "1" }
function basexx.from_bit( str, ignore )
str = ignore_set( str, ignore )
str = string.lower( str )
str = str:gsub( '[ilo]', function( c ) return bitMap[ c ] end )
local pos = string.find( str, "[^01]" )
if pos then return nil, unexpected_char_error( str, pos ) end
return pure_from_bit( str )
end
function basexx.to_bit( str )
return ( str:gsub( '.', function ( c )
local byte = string.byte( c )
local bits = {}
for _ = 1,8 do
table.insert( bits, byte % 2 )
byte = math.floor( byte / 2 )
end
return table.concat( bits ):reverse()
end ) )
end
--------------------------------------------------------------------------------
-- base16(hex) decode and encode function
--------------------------------------------------------------------------------
function basexx.from_hex( str, ignore )
str = ignore_set( str, ignore )
local pos = string.find( str, "[^%x]" )
if pos then return nil, unexpected_char_error( str, pos ) end
return ( str:gsub( '..', function ( cc )
return string.char( tonumber( cc, 16 ) )
end ) )
end
function basexx.to_hex( str )
return ( str:gsub( '.', function ( c )
return string.format('%02X', string.byte( c ) )
end ) )
end
--------------------------------------------------------------------------------
-- generic function to decode and encode base32/base64
--------------------------------------------------------------------------------
function basexx.from_basexx( str, alphabet, bits )
local result = {}
for i = 1, #str do
local c = string.sub( str, i, i )
if c ~= '=' then
local index = string.find( alphabet, c, 1, true )
if not index then
return nil, unexpected_char_error( str, i )
end
table.insert( result, number_to_bit( index - 1, bits ) )
end
end
local value = table.concat( result )
local pad = #value % 8
return pure_from_bit( string.sub( value, 1, #value - pad ) )
end
function basexx.to_basexx( str, alphabet, bits, pad )
local bitString = basexx.to_bit( str )
local chunks = divide_string( bitString, bits )
local result = {}
for _,value in ipairs( chunks ) do
if ( #value < bits ) then
value = value .. string.rep( '0', bits - #value )
end
local pos = tonumber( value, 2 ) + 1
table.insert( result, alphabet:sub( pos, pos ) )
end
table.insert( result, pad )
return table.concat( result )
end
--------------------------------------------------------------------------------
-- rfc 3548: http://www.rfc-editor.org/rfc/rfc3548.txt
--------------------------------------------------------------------------------
local base32Alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"
local base32PadMap = { "", "======", "====", "===", "=" }
function basexx.from_base32( str, ignore )
str = ignore_set( str, ignore )
return basexx.from_basexx( string.upper( str ), base32Alphabet, 5 )
end
function basexx.to_base32( str )
return basexx.to_basexx( str, base32Alphabet, 5, base32PadMap[ #str % 5 + 1 ] )
end
--------------------------------------------------------------------------------
-- crockford: http://www.crockford.com/wrmg/base32.html
--------------------------------------------------------------------------------
local crockfordAlphabet = "0123456789ABCDEFGHJKMNPQRSTVWXYZ"
local crockfordMap = { O = "0", I = "1", L = "1" }
function basexx.from_crockford( str, ignore )
str = ignore_set( str, ignore )
str = string.upper( str )
str = str:gsub( '[ILOU]', function( c ) return crockfordMap[ c ] end )
return basexx.from_basexx( str, crockfordAlphabet, 5 )
end
function basexx.to_crockford( str )
return basexx.to_basexx( str, crockfordAlphabet, 5, "" )
end
--------------------------------------------------------------------------------
-- base64 decode and encode function
--------------------------------------------------------------------------------
local base64Alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"..
"abcdefghijklmnopqrstuvwxyz"..
"0123456789+/"
local base64PadMap = { "", "==", "=" }
function basexx.from_base64( str, ignore )
str = ignore_set( str, ignore )
return basexx.from_basexx( str, base64Alphabet, 6 )
end
function basexx.to_base64( str )
return basexx.to_basexx( str, base64Alphabet, 6, base64PadMap[ #str % 3 + 1 ] )
end
--------------------------------------------------------------------------------
-- URL safe base64 decode and encode function
--------------------------------------------------------------------------------
local url64Alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"..
"abcdefghijklmnopqrstuvwxyz"..
"0123456789-_"
function basexx.from_url64( str, ignore )
str = ignore_set( str, ignore )
return basexx.from_basexx( str, url64Alphabet, 6 )
end
function basexx.to_url64( str )
return basexx.to_basexx( str, url64Alphabet, 6, "" )
end
--------------------------------------------------------------------------------
--
--------------------------------------------------------------------------------
local function length_error( len, d )
return string.format( "invalid length: %d - must be a multiple of %d", len, d )
end
local z85Decoder = { 0x00, 0x44, 0x00, 0x54, 0x53, 0x52, 0x48, 0x00,
0x4B, 0x4C, 0x46, 0x41, 0x00, 0x3F, 0x3E, 0x45,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x40, 0x00, 0x49, 0x42, 0x4A, 0x47,
0x51, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A,
0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32,
0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A,
0x3B, 0x3C, 0x3D, 0x4D, 0x00, 0x4E, 0x43, 0x00,
0x00, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10,
0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20,
0x21, 0x22, 0x23, 0x4F, 0x00, 0x50, 0x00, 0x00 }
function basexx.from_z85( str, ignore )
str = ignore_set( str, ignore )
if ( #str % 5 ) ~= 0 then
return nil, length_error( #str, 5 )
end
local result = {}
local value = 0
for i = 1, #str do
local index = string.byte( str, i ) - 31
if index < 1 or index >= #z85Decoder then
return nil, unexpected_char_error( str, i )
end
value = ( value * 85 ) + z85Decoder[ index ]
if ( i % 5 ) == 0 then
local divisor = 256 * 256 * 256
while divisor ~= 0 do
local b = math.floor( value / divisor ) % 256
table.insert( result, string.char( b ) )
divisor = math.floor( divisor / 256 )
end
value = 0
end
end
return table.concat( result )
end
local z85Encoder = "0123456789"..
"abcdefghijklmnopqrstuvwxyz"..
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"..
".-:+=^!/*?&<>()[]{}@%$#"
function basexx.to_z85( str )
if ( #str % 4 ) ~= 0 then
return nil, length_error( #str, 4 )
end
local result = {}
local value = 0
for i = 1, #str do
local b = string.byte( str, i )
value = ( value * 256 ) + b
if ( i % 4 ) == 0 then
local divisor = 85 * 85 * 85 * 85
while divisor ~= 0 do
local index = ( math.floor( value / divisor ) % 85 ) + 1
table.insert( result, z85Encoder:sub( index, index ) )
divisor = math.floor( divisor / 85 )
end
value = 0
end
end
return table.concat( result )
end
--------------------------------------------------------------------------------
return basexx

View File

@ -1,153 +0,0 @@
local _M = {}
-- constant tier ids
local tier_id_anonymous = 0
local tier_id_free = 1
-- fallback - remember to keep those updated
local anon_limits = {
["tierID"] = tier_id_anonymous,
["tierName"] = "anonymous",
["upload"] = 655360,
["download"] = 655360,
["maxUploadSize"] = 1073741824,
["registry"] = 250
}
-- get all non empty authentication headers from request, we want to return
-- all of them and let accounts service deal with validation and prioritisation
function _M.get_auth_headers()
local utils = require("utils")
local request_headers = ngx.req.get_headers()
local headers = {}
-- try to extract skynet-jwt cookie from cookie header
local skynet_jwt_cookie = utils.extract_cookie(request_headers["Cookie"], "skynet[-]jwt")
-- if skynet-jwt cookie is present, pass it as is
if skynet_jwt_cookie then
headers["Cookie"] = skynet_jwt_cookie
end
-- if authorization header is set, pass it as is
if request_headers["Authorization"] then
headers["Authorization"] = request_headers["Authorization"]
end
-- if skynet api key header is set, pass it as is
if request_headers["Skynet-Api-Key"] then
headers["Skynet-Api-Key"] = request_headers["Skynet-Api-Key"]
end
return headers
end
-- handle request exit when access to portal should be restricted to authenticated users only
function _M.exit_access_unauthorized(message)
ngx.status = ngx.HTTP_UNAUTHORIZED
ngx.header["content-type"] = "text/plain"
ngx.say(message or "Portal operator restricted access to authenticated users only")
return ngx.exit(ngx.status)
end
-- handle request exit when access to portal should be restricted to subscription users only
function _M.exit_access_forbidden(message)
ngx.status = ngx.HTTP_FORBIDDEN
ngx.header["content-type"] = "text/plain"
ngx.say(message or "Portal operator restricted access to users with active subscription only")
return ngx.exit(ngx.status)
end
function _M.accounts_enabled()
local skynet_modules = require("skynet.modules")
return skynet_modules.is_enabled("a")
end
function _M.get_account_limits()
local cjson = require('cjson')
local utils = require('utils')
local auth_headers = _M.get_auth_headers()
-- simple case of anonymous request - none of available auth headers exist
if utils.is_table_empty(auth_headers) then
return anon_limits
end
if ngx.var.account_limits == "" then
local httpc = require("resty.http").new()
local uri = "http://10.10.10.70:3000/user/limits"
-- include skylink if it is available in the context of request
-- todo: this should not rely on skylink variable to be defined
if ngx.var.skylink ~= nil and ngx.var.skylink ~= "" then
uri = uri .. "/" .. ngx.var.skylink
end
-- 10.10.10.70 points to accounts service (alias not available when using resty-http)
local res, err = httpc:request_uri(uri .. "?unit=byte", {
headers = auth_headers,
})
-- fail gracefully in case /user/limits failed
if err or (res and res.status ~= ngx.HTTP_OK) then
local error_response = err or ("[HTTP " .. res.status .. "] " .. res.body)
ngx.log(ngx.ERR, "Failed accounts service request /user/limits?unit=byte: ", error_response)
ngx.var.account_limits = cjson.encode(anon_limits)
elseif res and res.status == ngx.HTTP_OK then
ngx.var.account_limits = res.body
end
end
return cjson.decode(ngx.var.account_limits)
end
-- detect whether current user is authenticated
function _M.is_authenticated()
if not _M.accounts_enabled() then return false end
local limits = _M.get_account_limits()
return limits.tierID > tier_id_anonymous
end
-- detect whether current user has active subscription
function _M.has_subscription()
local limits = _M.get_account_limits()
return limits.tierID > tier_id_free
end
function _M.is_auth_required()
-- authentication is required if mode is set to "authenticated"
-- or "subscription" (require active subscription to a premium plan)
return os.getenv("ACCOUNTS_LIMIT_ACCESS") == "authenticated" or _M.is_subscription_required()
end
function _M.is_subscription_required()
return os.getenv("ACCOUNTS_LIMIT_ACCESS") == "subscription"
end
local is_access_always_allowed = function ()
-- options requests do not attach cookies - should always be available
-- requests should not be limited based on accounts if accounts are not enabled
return ngx.req.get_method() == "OPTIONS" or not _M.accounts_enabled()
end
-- check whether access is restricted if portal requires authorization
function _M.is_access_unauthorized()
if is_access_always_allowed() then return false end
-- check if authentication is required and request is not authenticated
return _M.is_auth_required() and not _M.is_authenticated()
end
-- check whether user is authenticated but does not have access to given resources
function _M.is_access_forbidden()
if is_access_always_allowed() then return false end
-- check if active subscription is required and request is from user without it
return _M.is_subscription_required() and not _M.has_subscription()
end
return _M

View File

@ -1,23 +0,0 @@
local _M = {}
local utils = require("utils")
function _M.is_enabled(module_abbr)
if type(module_abbr) ~= "string" or module_abbr:len() ~= 1 then
error("Module abbreviation '" .. tostring(module_abbr) .. "' should be exactly one character long string")
end
local enabled_modules = utils.getenv("PORTAL_MODULES")
if not enabled_modules then
return false
end
return enabled_modules:find(module_abbr) ~= nil
end
function _M.is_disabled(module_abbr)
return not _M.is_enabled(module_abbr)
end
return _M

View File

@ -1,95 +0,0 @@
-- luacheck: ignore os
local skynet_modules = require("skynet.modules")
describe("is_enabled", function()
before_each(function()
stub(os, "getenv")
end)
after_each(function()
os.getenv:revert()
end)
it("should return false if PORTAL_MODULES are not defined", function()
os.getenv.on_call_with("PORTAL_MODULES").returns(nil)
assert.is_false(skynet_modules.is_enabled("a"))
end)
it("should return false if PORTAL_MODULES are empty", function()
os.getenv.on_call_with("PORTAL_MODULES").returns("")
assert.is_false(skynet_modules.is_enabled("a"))
end)
it("should return false if module is not enabled", function()
os.getenv.on_call_with("PORTAL_MODULES").returns("qwerty")
assert.is_false(skynet_modules.is_enabled("a"))
end)
it("should return true if module is enabled", function()
os.getenv.on_call_with("PORTAL_MODULES").returns("asdfg")
assert.is_true(skynet_modules.is_enabled("a"))
end)
it("should throw an error for empty module", function()
assert.has_error(function()
skynet_modules.is_enabled()
end, "Module abbreviation 'nil' should be exactly one character long string")
end)
it("should throw an error for too long module", function()
assert.has_error(function()
skynet_modules.is_enabled("gandalf")
end, "Module abbreviation 'gandalf' should be exactly one character long string")
end)
end)
describe("is_disabled", function()
before_each(function()
stub(os, "getenv")
end)
after_each(function()
os.getenv:revert()
end)
it("should return true if PORTAL_MODULES are not defined", function()
os.getenv.on_call_with("PORTAL_MODULES").returns(nil)
assert.is_true(skynet_modules.is_disabled("a"))
end)
it("should return true if PORTAL_MODULES are empty", function()
os.getenv.on_call_with("PORTAL_MODULES").returns("")
assert.is_true(skynet_modules.is_disabled("a"))
end)
it("should return true if module is not enabled", function()
os.getenv.on_call_with("PORTAL_MODULES").returns("qwerty")
assert.is_true(skynet_modules.is_disabled("a"))
end)
it("should return false if module is enabled", function()
os.getenv.on_call_with("PORTAL_MODULES").returns("asdfg")
assert.is_false(skynet_modules.is_disabled("a"))
end)
it("should throw an error for empty module", function()
assert.has_error(function()
skynet_modules.is_disabled()
end, "Module abbreviation 'nil' should be exactly one character long string")
end)
it("should throw an error for too long module", function()
assert.has_error(function()
skynet_modules.is_disabled("gandalf")
end, "Module abbreviation 'gandalf' should be exactly one character long string")
end)
end)

View File

@ -1,26 +0,0 @@
local _M = {}
function _M.scan_skylink_timer(premature, skylink)
if premature then return end
local httpc = require("resty.http").new()
-- 10.10.10.101 points to malware-scanner service (alias not available when using resty-http)
local res, err = httpc:request_uri("http://10.10.10.101:4000/scan/" .. skylink, {
method = "POST",
})
if err or (res and res.status ~= ngx.HTTP_OK) then
local error_response = err or ("[HTTP " .. res.status .. "] " .. res.body)
ngx.log(ngx.ERR, "Failed malware-scanner request /scan/" .. skylink .. ": ", error_response)
end
end
function _M.scan_skylink(skylink)
if not skylink then return end
local ok, err = ngx.timer.at(0, _M.scan_skylink_timer, skylink)
if not ok then ngx.log(ngx.ERR, "Failed to create timer: ", err) end
end
return _M

View File

@ -1,119 +0,0 @@
-- luacheck: ignore ngx
local skynet_scanner = require("skynet.scanner")
local skylink = "AQBG8n_sgEM_nlEp3G0w3vLjmdvSZ46ln8ZXHn-eObZNjA"
describe("scan_skylink", function()
before_each(function()
stub(ngx.timer, "at")
end)
after_each(function()
ngx.timer.at:revert()
end)
it("should schedule a timer when skylink is provided", function()
ngx.timer.at.invokes(function() return true, nil end)
skynet_scanner.scan_skylink(skylink)
assert.stub(ngx.timer.at).was_called_with(0, skynet_scanner.scan_skylink_timer, skylink)
end)
it("should log an error if timer failed to create", function()
stub(ngx, "log")
ngx.timer.at.invokes(function() return false, "such a failure" end)
skynet_scanner.scan_skylink(skylink)
assert.stub(ngx.timer.at).was_called_with(0, skynet_scanner.scan_skylink_timer, skylink)
assert.stub(ngx.log).was_called_with(ngx.ERR, "Failed to create timer: ", "such a failure")
ngx.log:revert()
end)
it("should not schedule a timer if skylink is not provided", function()
skynet_scanner.scan_skylink()
assert.stub(ngx.timer.at).was_not_called()
end)
end)
describe("scan_skylink_timer", function()
before_each(function()
stub(ngx, "log")
end)
after_each(function()
local resty_http = require("resty.http")
ngx.log:revert()
resty_http.new:revert()
end)
it("should exit early on premature", function()
local resty_http = require("resty.http")
local request_uri = spy.new()
local httpc = mock({ request_uri = request_uri })
stub(resty_http, "new").returns(httpc)
skynet_scanner.scan_skylink_timer(true, skylink)
assert.stub(request_uri).was_not_called()
assert.stub(ngx.log).was_not_called()
end)
it("should make a post request with skylink to scanner service", function()
local resty_http = require("resty.http")
local request_uri = spy.new(function()
return { status = 200 } -- return 200 success
end)
local httpc = mock({ request_uri = request_uri })
stub(resty_http, "new").returns(httpc)
skynet_scanner.scan_skylink_timer(false, skylink)
local uri = "http://10.10.10.101:4000/scan/" .. skylink
assert.stub(request_uri).was_called_with(httpc, uri, { method = "POST" })
assert.stub(ngx.log).was_not_called()
end)
it("should log message on scanner request failure with response code", function()
local resty_http = require("resty.http")
local request_uri = spy.new(function()
return { status = 404, body = "baz" } -- return 404 failure
end)
local httpc = mock({ request_uri = request_uri })
stub(resty_http, "new").returns(httpc)
skynet_scanner.scan_skylink_timer(false, skylink)
local uri = "http://10.10.10.101:4000/scan/" .. skylink
assert.stub(request_uri).was_called_with(httpc, uri, { method = "POST" })
assert.stub(ngx.log).was_called_with(
ngx.ERR,
"Failed malware-scanner request /scan/AQBG8n_sgEM_nlEp3G0w3vLjmdvSZ46ln8ZXHn-eObZNjA: ",
"[HTTP 404] baz"
)
end)
it("should log message on scanner request error", function()
local resty_http = require("resty.http")
local request_uri = spy.new(function()
return nil, "foo != bar" -- return error
end)
local httpc = mock({ request_uri = request_uri })
stub(resty_http, "new").returns(httpc)
skynet_scanner.scan_skylink_timer(false, skylink)
local uri = "http://10.10.10.101:4000/scan/" .. skylink
assert.stub(request_uri).was_called_with(httpc, uri, { method = "POST" })
assert.stub(ngx.log).was_called_with(
ngx.ERR,
"Failed malware-scanner request /scan/AQBG8n_sgEM_nlEp3G0w3vLjmdvSZ46ln8ZXHn-eObZNjA: ",
"foo != bar"
)
end)
end)

View File

@ -1,40 +0,0 @@
local _M = {}
local basexx = require("basexx")
local hasher = require("hasher")
-- parse any skylink and return base64 version
function _M.parse(skylink)
if string.len(skylink) == 55 then
local decoded = basexx.from_basexx(string.upper(skylink), "0123456789ABCDEFGHIJKLMNOPQRSTUV", 5)
return basexx.to_url64(decoded)
end
return skylink
end
-- hash skylink into 32 bytes hash used in blocklist
function _M.hash(skylink)
-- ensure that the skylink is base64 encoded
local base64Skylink = _M.parse(skylink)
-- decode skylink from base64 encoding
local rawSkylink = basexx.from_url64(base64Skylink)
-- drop first two bytes and leave just merkle root
local rawMerkleRoot = string.sub(rawSkylink, 3)
-- parse with blake2b with key length of 32
local blake2bHashed = hasher.blake2b(rawMerkleRoot, 32)
-- hex encode the blake hash
local hexHashed = basexx.to_hex(blake2bHashed)
-- lowercase the hex encoded hash
local lowerHexHashed = string.lower(hexHashed)
return lowerHexHashed
end
return _M

View File

@ -1,23 +0,0 @@
local skynet_skylink = require("skynet.skylink")
describe("parse", function()
local base32 = "0404dsjvti046fsua4ktor9grrpe76erq9jot9cvopbhsvsu76r4r30"
local base64 = "AQBG8n_sgEM_nlEp3G0w3vLjmdvSZ46ln8ZXHn-eObZNjA"
it("should return unchanged base64 skylink", function()
assert.is.same(skynet_skylink.parse(base64), base64)
end)
it("should transform base32 skylink into base64", function()
assert.is.same(skynet_skylink.parse(base32), base64)
end)
end)
describe("hash", function()
local base64 = "EADi4QZWt87sSDCSjVTcmyI5tE_YAsuC90BcCi_jEmG5NA"
local hash = "6cfb9996ad74e5614bbb8e7228e72f1c1bc14dd9ce8a83b3ccabdb6d8d70f330"
it("should hash skylink", function()
assert.is.same(hash, skynet_skylink.hash(base64))
end)
end)

View File

@ -1,99 +0,0 @@
local _M = {}
local utils = require("utils")
function _M.track_download_timer(premature, skylink, status, auth_headers, body_bytes_sent)
if premature then return end
local httpc = require("resty.http").new()
local query = table.concat({ "status=" .. status, "bytes=" .. body_bytes_sent }, "&")
-- 10.10.10.70 points to accounts service (alias not available when using resty-http)
local res, err = httpc:request_uri("http://10.10.10.70:3000/track/download/" .. skylink .. "?" .. query, {
method = "POST",
headers = auth_headers,
})
if err or (res and res.status ~= 204) then
local error_response = err or ("[HTTP " .. res.status .. "] " .. res.body)
ngx.log(ngx.ERR, "Failed accounts service request /track/download/" .. skylink .. ": ", error_response)
end
end
function _M.track_download(skylink, status_code, auth_headers, body_bytes_sent)
local has_auth_headers = not utils.is_table_empty(auth_headers)
local status_success = status_code >= 200 and status_code <= 299
if skylink and status_success and has_auth_headers then
local ok, err = ngx.timer.at(0, _M.track_download_timer, skylink, status_code, auth_headers, body_bytes_sent)
if not ok then ngx.log(ngx.ERR, "Failed to create timer: ", err) end
end
end
function _M.track_upload_timer(premature, skylink, auth_headers, uploader_ip)
if premature then return end
local httpc = require("resty.http").new()
-- set correct content type header and include auth headers
local headers = {
["Content-Type"] = "application/x-www-form-urlencoded",
}
for key, value in pairs(auth_headers) do
headers[key] = value
end
-- 10.10.10.70 points to accounts service (alias not available when using resty-http)
local res, err = httpc:request_uri("http://10.10.10.70:3000/track/upload/" .. skylink, {
method = "POST",
headers = headers,
body = "ip=" .. uploader_ip,
})
if err or (res and res.status ~= 204) then
local error_response = err or ("[HTTP " .. res.status .. "] " .. res.body)
ngx.log(ngx.ERR, "Failed accounts service request /track/upload/" .. skylink .. ": ", error_response)
end
end
function _M.track_upload(skylink, status_code, auth_headers, uploader_ip)
local status_success = status_code >= 200 and status_code <= 299
if skylink and status_success then
local ok, err = ngx.timer.at(0, _M.track_upload_timer, skylink, auth_headers, uploader_ip)
if not ok then ngx.log(ngx.ERR, "Failed to create timer: ", err) end
end
end
function _M.track_registry_timer(premature, auth_headers, request_method)
if premature then return end
local httpc = require("resty.http").new()
-- based on request method we assign a registry action string used
-- in track endpoint namely "read" for GET and "write" for POST
local registry_action = request_method == "GET" and "read" or "write"
-- 10.10.10.70 points to accounts service (alias not available when using resty-http)
local res, err = httpc:request_uri("http://10.10.10.70:3000/track/registry/" .. registry_action, {
method = "POST",
headers = auth_headers,
})
if err or (res and res.status ~= 204) then
local error_response = err or ("[HTTP " .. res.status .. "] " .. res.body)
ngx.log(ngx.ERR, "Failed accounts service request /track/registry/" .. registry_action .. ": ", error_response)
end
end
function _M.track_registry(status_code, auth_headers, request_method)
local has_auth_headers = not utils.is_table_empty(auth_headers)
local tracked_status = status_code == 200 or status_code == 404
if tracked_status and has_auth_headers then
local ok, err = ngx.timer.at(0, _M.track_registry_timer, auth_headers, request_method)
if not ok then ngx.log(ngx.ERR, "Failed to create timer: ", err) end
end
end
return _M

View File

@ -1,584 +0,0 @@
-- luacheck: ignore ngx
local skynet_tracker = require("skynet.tracker")
local valid_skylink = "AQBG8n_sgEM_nlEp3G0w3vLjmdvSZ46ln8ZXHn-eObZNjA"
local valid_status_code = 200
local valid_auth_headers = { ["Skynet-Api-Key"] = "foo" }
local valid_ip = "12.34.56.78"
describe("track_download", function()
local valid_body_bytes_sent = 12345
before_each(function()
stub(ngx.timer, "at")
end)
after_each(function()
ngx.timer.at:revert()
end)
it("should schedule a timer when conditions are met", function()
ngx.timer.at.invokes(function() return true, nil end)
skynet_tracker.track_download(valid_skylink, valid_status_code, valid_auth_headers, valid_body_bytes_sent)
assert.stub(ngx.timer.at).was_called_with(
0,
skynet_tracker.track_download_timer,
valid_skylink,
valid_status_code,
valid_auth_headers,
valid_body_bytes_sent
)
end)
it("should not schedule a timer if skylink is empty", function()
ngx.timer.at.invokes(function() return true, nil end)
skynet_tracker.track_download(nil, valid_status_code, valid_auth_headers, valid_body_bytes_sent)
assert.stub(ngx.timer.at).was_not_called()
end)
it("should not schedule a timer if status code is not in 2XX range", function()
ngx.timer.at.invokes(function() return true, nil end)
-- couple of example of 4XX and 5XX codes
skynet_tracker.track_download(valid_skylink, 401, valid_auth_headers, valid_body_bytes_sent)
skynet_tracker.track_download(valid_skylink, 403, valid_auth_headers, valid_body_bytes_sent)
skynet_tracker.track_download(valid_skylink, 490, valid_auth_headers, valid_body_bytes_sent)
skynet_tracker.track_download(valid_skylink, 500, valid_auth_headers, valid_body_bytes_sent)
skynet_tracker.track_download(valid_skylink, 502, valid_auth_headers, valid_body_bytes_sent)
assert.stub(ngx.timer.at).was_not_called()
end)
it("should not schedule a timer if auth headers are empty", function()
ngx.timer.at.invokes(function() return true, nil end)
skynet_tracker.track_download(valid_skylink, valid_status_code, {}, valid_body_bytes_sent)
assert.stub(ngx.timer.at).was_not_called()
end)
it("should log an error if timer failed to create", function()
stub(ngx, "log")
ngx.timer.at.invokes(function() return false, "such a failure" end)
skynet_tracker.track_download(valid_skylink, valid_status_code, valid_auth_headers, valid_body_bytes_sent)
assert.stub(ngx.timer.at).was_called_with(
0,
skynet_tracker.track_download_timer,
valid_skylink,
valid_status_code,
valid_auth_headers,
valid_body_bytes_sent
)
assert.stub(ngx.log).was_called_with(ngx.ERR, "Failed to create timer: ", "such a failure")
ngx.log:revert()
end)
describe("track_download_timer", function()
before_each(function()
stub(ngx, "log")
end)
after_each(function()
local resty_http = require("resty.http")
ngx.log:revert()
resty_http.new:revert()
end)
it("should exit early on premature", function()
local resty_http = require("resty.http")
local request_uri = spy.new(function()
return { status = 200 } -- return 200 success
end)
local httpc = mock({ request_uri = request_uri })
stub(resty_http, "new").returns(httpc)
skynet_tracker.track_download_timer(
true,
valid_skylink,
valid_status_code,
valid_auth_headers,
valid_body_bytes_sent
)
assert.stub(request_uri).was_not_called()
assert.stub(ngx.log).was_not_called()
end)
it("should make a post request to tracker service", function()
local resty_http = require("resty.http")
local request_uri = spy.new(function()
return { status = 204 } -- return 204 success
end)
local httpc = mock({ request_uri = request_uri })
stub(resty_http, "new").returns(httpc)
skynet_tracker.track_download_timer(
false,
valid_skylink,
valid_status_code,
valid_auth_headers,
valid_body_bytes_sent
)
local uri_params = "status=" .. valid_status_code .. "&bytes=" .. valid_body_bytes_sent
local uri = "http://10.10.10.70:3000/track/download/" .. valid_skylink .. "?" .. uri_params
assert.stub(request_uri).was_called_with(httpc, uri, { method = "POST", headers = valid_auth_headers })
assert.stub(ngx.log).was_not_called()
end)
it("should log message on tracker request failure with response code", function()
local resty_http = require("resty.http")
local request_uri = spy.new(function()
return { status = 404, body = "baz" } -- return 404 failure
end)
local httpc = mock({ request_uri = request_uri })
stub(resty_http, "new").returns(httpc)
skynet_tracker.track_download_timer(
false,
valid_skylink,
valid_status_code,
valid_auth_headers,
valid_body_bytes_sent
)
local uri_params = "status=" .. valid_status_code .. "&bytes=" .. valid_body_bytes_sent
local uri = "http://10.10.10.70:3000/track/download/" .. valid_skylink .. "?" .. uri_params
assert.stub(request_uri).was_called_with(httpc, uri, { method = "POST", headers = valid_auth_headers })
assert.stub(ngx.log).was_called_with(
ngx.ERR,
"Failed accounts service request /track/download/" .. valid_skylink .. ": ",
"[HTTP 404] baz"
)
end)
it("should log message on tracker request error", function()
local resty_http = require("resty.http")
local request_uri = spy.new(function()
return nil, "foo != bar" -- return error
end)
local httpc = mock({ request_uri = request_uri })
stub(resty_http, "new").returns(httpc)
skynet_tracker.track_download_timer(
false,
valid_skylink,
valid_status_code,
valid_auth_headers,
valid_body_bytes_sent
)
local uri_params = "status=" .. valid_status_code .. "&bytes=" .. valid_body_bytes_sent
local uri = "http://10.10.10.70:3000/track/download/" .. valid_skylink .. "?" .. uri_params
assert.stub(request_uri).was_called_with(httpc, uri, { method = "POST", headers = valid_auth_headers })
assert.stub(ngx.log).was_called_with(
ngx.ERR,
"Failed accounts service request /track/download/" .. valid_skylink .. ": ",
"foo != bar"
)
end)
end)
end)
describe("track_upload", function()
before_each(function()
stub(ngx.timer, "at")
end)
after_each(function()
ngx.timer.at:revert()
end)
it("should schedule a timer when conditions are met", function()
ngx.timer.at.invokes(function() return true, nil end)
skynet_tracker.track_upload(valid_skylink, valid_status_code, valid_auth_headers, valid_ip)
assert.stub(ngx.timer.at).was_called_with(
0,
skynet_tracker.track_upload_timer,
valid_skylink,
valid_auth_headers,
valid_ip
)
end)
it("should not schedule a timer if skylink is empty", function()
ngx.timer.at.invokes(function() return true, nil end)
skynet_tracker.track_upload(nil, valid_status_code, valid_auth_headers, valid_ip)
assert.stub(ngx.timer.at).was_not_called()
end)
it("should not schedule a timer if status code is not in 2XX range", function()
ngx.timer.at.invokes(function() return true, nil end)
-- couple of example of 4XX and 5XX codes
skynet_tracker.track_upload(valid_skylink, 401, valid_auth_headers, valid_ip)
skynet_tracker.track_upload(valid_skylink, 403, valid_auth_headers, valid_ip)
skynet_tracker.track_upload(valid_skylink, 490, valid_auth_headers, valid_ip)
skynet_tracker.track_upload(valid_skylink, 500, valid_auth_headers, valid_ip)
skynet_tracker.track_upload(valid_skylink, 502, valid_auth_headers, valid_ip)
assert.stub(ngx.timer.at).was_not_called()
end)
it("should schedule a timer if auth headers are empty", function()
ngx.timer.at.invokes(function() return true, nil end)
skynet_tracker.track_upload(valid_skylink, valid_status_code, {}, valid_ip)
assert.stub(ngx.timer.at).was_called_with(
0,
skynet_tracker.track_upload_timer,
valid_skylink,
{},
valid_ip
)
end)
it("should log an error if timer failed to create", function()
stub(ngx, "log")
ngx.timer.at.invokes(function() return false, "such a failure" end)
skynet_tracker.track_upload(valid_skylink, valid_status_code, valid_auth_headers, valid_ip)
assert.stub(ngx.timer.at).was_called_with(
0,
skynet_tracker.track_upload_timer,
valid_skylink,
valid_auth_headers,
valid_ip
)
assert.stub(ngx.log).was_called_with(ngx.ERR, "Failed to create timer: ", "such a failure")
ngx.log:revert()
end)
describe("track_upload_timer", function()
before_each(function()
stub(ngx, "log")
end)
after_each(function()
local resty_http = require("resty.http")
ngx.log:revert()
resty_http.new:revert()
end)
it("should exit early on premature", function()
local resty_http = require("resty.http")
local request_uri = spy.new(function()
return { status = 200 } -- return 200 success
end)
local httpc = mock({ request_uri = request_uri })
stub(resty_http, "new").returns(httpc)
skynet_tracker.track_upload_timer(
true,
valid_skylink,
valid_auth_headers,
valid_ip
)
assert.stub(request_uri).was_not_called()
assert.stub(ngx.log).was_not_called()
end)
it("should make a post request to tracker service", function()
local resty_http = require("resty.http")
local request_uri = spy.new(function()
return { status = 204 } -- return 204 success
end)
local httpc = mock({ request_uri = request_uri })
stub(resty_http, "new").returns(httpc)
skynet_tracker.track_upload_timer(
false,
valid_skylink,
valid_auth_headers,
valid_ip
)
local uri = "http://10.10.10.70:3000/track/upload/" .. valid_skylink
assert.stub(request_uri).was_called_with(httpc, uri, {
method = "POST",
headers = {
["Content-Type"] = "application/x-www-form-urlencoded",
["Skynet-Api-Key"] = "foo",
},
body = "ip=" .. valid_ip
})
assert.stub(ngx.log).was_not_called()
end)
it("should log message on tracker request failure with response code", function()
local resty_http = require("resty.http")
local request_uri = spy.new(function()
return { status = 404, body = "baz" } -- return 404 failure
end)
local httpc = mock({ request_uri = request_uri })
stub(resty_http, "new").returns(httpc)
skynet_tracker.track_upload_timer(
false,
valid_skylink,
valid_auth_headers,
valid_ip
)
local uri = "http://10.10.10.70:3000/track/upload/" .. valid_skylink
assert.stub(request_uri).was_called_with(httpc, uri, {
method = "POST",
headers = {
["Content-Type"] = "application/x-www-form-urlencoded",
["Skynet-Api-Key"] = "foo",
},
body = "ip=" .. valid_ip
})
assert.stub(ngx.log).was_called_with(
ngx.ERR,
"Failed accounts service request /track/upload/" .. valid_skylink .. ": ",
"[HTTP 404] baz"
)
end)
it("should log message on tracker request error", function()
local resty_http = require("resty.http")
local request_uri = spy.new(function()
return nil, "foo != bar" -- return error
end)
local httpc = mock({ request_uri = request_uri })
stub(resty_http, "new").returns(httpc)
skynet_tracker.track_upload_timer(
false,
valid_skylink,
valid_auth_headers,
valid_ip
)
local uri = "http://10.10.10.70:3000/track/upload/" .. valid_skylink
assert.stub(request_uri).was_called_with(httpc, uri, {
method = "POST",
headers = {
["Content-Type"] = "application/x-www-form-urlencoded",
["Skynet-Api-Key"] = "foo",
},
body = "ip=" .. valid_ip
})
assert.stub(ngx.log).was_called_with(
ngx.ERR,
"Failed accounts service request /track/upload/" .. valid_skylink .. ": ",
"foo != bar"
)
end)
end)
end)
describe("track_registry", function()
local status_code_ok = 200
local status_code_not_found = 404
local request_method_write = "POST"
local request_method_read = "GET"
before_each(function()
stub(ngx.timer, "at")
end)
after_each(function()
ngx.timer.at:revert()
end)
it("should schedule a timer when status code was 200", function()
ngx.timer.at.invokes(function() return true, nil end)
skynet_tracker.track_registry(status_code_ok, valid_auth_headers, request_method_write)
assert.stub(ngx.timer.at).was_called_with(
0,
skynet_tracker.track_registry_timer,
valid_auth_headers,
request_method_write
)
end)
it("should schedule a timer when status code was 404", function()
ngx.timer.at.invokes(function() return true, nil end)
skynet_tracker.track_registry(status_code_not_found, valid_auth_headers, request_method_write)
assert.stub(ngx.timer.at).was_called_with(
0,
skynet_tracker.track_registry_timer,
valid_auth_headers,
request_method_write
)
end)
it("should not schedule a timer if status code is not in 200 or 404", function()
ngx.timer.at.invokes(function() return true, nil end)
-- couple of example of invalid 2XX, 4XX and 5XX codes
skynet_tracker.track_registry(204, valid_auth_headers, request_method_write)
skynet_tracker.track_registry(206, valid_auth_headers, request_method_write)
skynet_tracker.track_registry(401, valid_auth_headers, request_method_write)
skynet_tracker.track_registry(403, valid_auth_headers, request_method_write)
skynet_tracker.track_registry(490, valid_auth_headers, request_method_write)
skynet_tracker.track_registry(500, valid_auth_headers, request_method_write)
skynet_tracker.track_registry(502, valid_auth_headers, request_method_write)
assert.stub(ngx.timer.at).was_not_called()
end)
it("should not schedule a timer if auth headers are empty", function()
ngx.timer.at.invokes(function() return true, nil end)
skynet_tracker.track_registry(status_code_ok, {}, request_method_write)
assert.stub(ngx.timer.at).was_not_called()
end)
it("should log an error if timer failed to create", function()
stub(ngx, "log")
ngx.timer.at.invokes(function() return false, "such a failure" end)
skynet_tracker.track_registry(status_code_ok, valid_auth_headers, request_method_write)
assert.stub(ngx.timer.at).was_called_with(
0,
skynet_tracker.track_registry_timer,
valid_auth_headers,
request_method_write
)
assert.stub(ngx.log).was_called_with(ngx.ERR, "Failed to create timer: ", "such a failure")
ngx.log:revert()
end)
describe("track_registry_timer", function()
before_each(function()
stub(ngx, "log")
end)
after_each(function()
local resty_http = require("resty.http")
ngx.log:revert()
resty_http.new:revert()
end)
it("should exit early on premature", function()
local resty_http = require("resty.http")
local request_uri = spy.new(function()
return { status = 200 } -- return 200 success
end)
local httpc = mock({ request_uri = request_uri })
stub(resty_http, "new").returns(httpc)
skynet_tracker.track_registry_timer(
true,
valid_auth_headers,
request_method_write
)
assert.stub(request_uri).was_not_called()
assert.stub(ngx.log).was_not_called()
end)
it("should make a post request to registry write tracker service", function()
local resty_http = require("resty.http")
local request_uri = spy.new(function()
return { status = 204 } -- return 204 success
end)
local httpc = mock({ request_uri = request_uri })
stub(resty_http, "new").returns(httpc)
skynet_tracker.track_registry_timer(
false,
valid_auth_headers,
request_method_write
)
local uri = "http://10.10.10.70:3000/track/registry/write"
assert.stub(request_uri).was_called_with(httpc, uri, { method = "POST", headers = valid_auth_headers })
assert.stub(ngx.log).was_not_called()
end)
it("should make a post request to registry read tracker service", function()
local resty_http = require("resty.http")
local request_uri = spy.new(function()
return { status = 204 } -- return 204 success
end)
local httpc = mock({ request_uri = request_uri })
stub(resty_http, "new").returns(httpc)
skynet_tracker.track_registry_timer(
false,
valid_auth_headers,
request_method_read
)
local uri = "http://10.10.10.70:3000/track/registry/read"
assert.stub(request_uri).was_called_with(httpc, uri, { method = "POST", headers = valid_auth_headers })
assert.stub(ngx.log).was_not_called()
end)
it("should log message on tracker request failure with response code", function()
local resty_http = require("resty.http")
local request_uri = spy.new(function()
return { status = 404, body = "baz" } -- return 404 failure
end)
local httpc = mock({ request_uri = request_uri })
stub(resty_http, "new").returns(httpc)
skynet_tracker.track_registry_timer(
false,
valid_auth_headers,
request_method_write
)
local uri = "http://10.10.10.70:3000/track/registry/write"
assert.stub(request_uri).was_called_with(httpc, uri, { method = "POST", headers = valid_auth_headers })
assert.stub(ngx.log).was_called_with(
ngx.ERR,
"Failed accounts service request /track/registry/write: ",
"[HTTP 404] baz"
)
end)
it("should log message on tracker request error", function()
local resty_http = require("resty.http")
local request_uri = spy.new(function()
return nil, "foo != bar" -- return error
end)
local httpc = mock({ request_uri = request_uri })
stub(resty_http, "new").returns(httpc)
skynet_tracker.track_registry_timer(
false,
valid_auth_headers,
request_method_write
)
local uri = "http://10.10.10.70:3000/track/registry/write"
assert.stub(request_uri).was_called_with(httpc, uri, { method = "POST", headers = valid_auth_headers })
assert.stub(ngx.log).was_called_with(
ngx.ERR,
"Failed accounts service request /track/registry/write: ",
"foo != bar"
)
end)
end)
end)

View File

@ -1,30 +0,0 @@
local _M = {}
local ngx_base64 = require("ngx.base64")
local utils = require("utils")
function _M.authorization_header()
-- read api password from env variable
local apipassword = utils.getenv("SIA_API_PASSWORD")
-- if api password is not available as env variable, read it from disk
if not apipassword then
-- open apipassword file for reading (b flag is required for some reason)
-- (file /etc/.sia/apipassword has to be mounted from the host system)
local apipassword_file = io.open("/data/sia/apipassword", "rb")
-- make sure to throw a meaningful error if apipassword file does not exist
if not apipassword_file then
error("Error reading /data/sia/apipassword file")
end
-- read apipassword file contents and trim newline (important)
apipassword = apipassword_file:read("*all"):gsub("%s+", "")
-- make sure to close file after reading the password
apipassword_file.close()
end
-- encode the user:password authorization string
-- (in our case user is empty so it is just :password)
local content = ngx_base64.encode_base64url(":" .. apipassword)
-- set authorization header with proper base64 encoded string
return "Basic " .. content
end
return _M

View File

@ -1,65 +0,0 @@
-- luacheck: ignore io
local utils = require('utils')
local skynet_utils = require('skynet.utils')
describe("authorization_header", function()
local apipassword = "ddd0c1430fbf2708"
local expected_header = "Basic OmRkZDBjMTQzMGZiZjI3MDg"
it("reads SIA_API_PASSWORD from env variable and returns a header", function()
-- stub getenv on SIA_API_PASSWORD
stub(utils, "getenv")
utils.getenv.on_call_with("SIA_API_PASSWORD").returns(apipassword)
local header = skynet_utils.authorization_header()
assert.is_equal(header, expected_header)
-- revert stub to original function
utils.getenv:revert()
end)
it("uses /data/sia/apipassword file if SIA_API_PASSWORD env var is missing", function()
-- stub /data/sia/apipassword file
stub(io, "open")
io.open.on_call_with("/data/sia/apipassword", "rb").returns(mock({
read = spy.new(function() return apipassword end),
close = spy.new()
}))
local header = skynet_utils.authorization_header()
assert.is_equal(header, expected_header)
-- revert stub to original function
io.open:revert()
end)
it("should choose env variable over file if both are available", function()
-- stub getenv on SIA_API_PASSWORD
stub(utils, "getenv")
utils.getenv.on_call_with("SIA_API_PASSWORD").returns(apipassword)
-- stub /data/sia/apipassword file
stub(io, "open")
io.open.on_call_with("/data/sia/apipassword", "rb").returns(mock({
read = spy.new(function() return "foooooooooooooo" end),
close = spy.new()
}))
local header = skynet_utils.authorization_header()
assert.is_equal(header, "Basic OmRkZDBjMTQzMGZiZjI3MDg")
-- revert stubs to original function
utils.getenv:revert()
io.open:revert()
end)
it("should error out if neither env variable is available nor file exists", function()
assert.has_error(function()
skynet_utils.authorization_header()
end, "Error reading /data/sia/apipassword file")
end)
end)

View File

@ -1,83 +0,0 @@
local _M = {}
-- utility function for checking if table is empty
function _M.is_table_empty(check)
-- bind next to local variable to achieve ultimate efficiency
-- https://stackoverflow.com/a/1252776
local next = next
return next(check) == nil
end
-- extract full cookie name and value by its name from cookie string
-- note: name matcher argument is a pattern so you will need to escape
-- any special characters, read more https://www.lua.org/pil/20.2.html
function _M.extract_cookie(cookie_string, name_matcher)
-- nil cookie string safeguard
if cookie_string == nil then
return nil
end
local start, stop = string.find(cookie_string, name_matcher .. "=[^;]+")
if start then
return string.sub(cookie_string, start, stop)
end
return nil
end
-- extract just the cookie value by its name from cookie string
-- note: name matcher argument is a pattern so you will need to escape
-- any special characters, read more https://www.lua.org/pil/20.2.html
function _M.extract_cookie_value(cookie_string, name_matcher)
local cookie = _M.extract_cookie(cookie_string, name_matcher)
if cookie == nil then
return nil
end
local value_start = string.find(cookie, "=") + 1
return string.sub(cookie, value_start)
end
-- utility function that builds on os.getenv to get environment variable value
-- * will always return nil for both unset and empty env vars
-- * parse "boolean": "true" and "1" as true, "false" and "0" as false, throws for others
-- * parse "integer": any numerical string gets converted, otherwise returns nil
function _M.getenv(name, parse)
local value = os.getenv(name)
-- treat empty string value as nil to simplify comparisons
if value == nil or value == "" then
return nil
end
-- do not parse the value
if parse == nil then
return value
end
-- try to parse as boolean
if parse == "boolean" then
if string.lower(value) == "true" or value == "1" then
return true
end
if string.lower(value) == "false" or value == "0" then
return false
end
error("utils.getenv: Parsing value '" .. tostring(value) .. "' to boolean is not supported")
end
-- try to parse as integer
if parse == "integer" then
return tonumber(value)
end
error("utils.getenv: Parsing to '" .. parse .. "' is not supported")
end
return _M

View File

@ -1,215 +0,0 @@
-- luacheck: ignore os
local utils = require('utils')
describe("is_table_empty", function()
it("should return true for empty table", function()
assert.is_true(utils.is_table_empty({}))
end)
it("should return false for not empty table", function()
assert.is_false(utils.is_table_empty({ ["foo"] = "bar" }))
end)
end)
describe("extract_cookie", function()
local cookie_string = "aaa=bbb; skynet-jwt=MTY0NzUyr8jD-ytiWtspm0tGabKfooxeIDuWcXhJ3lnY0eEw==; xxx=yyy"
it("should return nil if cookie string is nil", function()
local cookie = utils.extract_cookie_value(nil, "aaa")
assert.is_nil(cookie)
end)
it("should return nil if cookie name is not found", function()
local cookie = utils.extract_cookie(cookie_string, "foo")
assert.is_nil(cookie)
end)
it("should return cookie if cookie_string starts with that cookie name", function()
local cookie = utils.extract_cookie(cookie_string, "aaa")
assert.are.equals(cookie, "aaa=bbb")
end)
it("should return cookie if cookie_string ends with that cookie name", function()
local cookie = utils.extract_cookie(cookie_string, "xxx")
assert.are.equals(cookie, "xxx=yyy")
end)
it("should return cookie with custom matcher", function()
local cookie = utils.extract_cookie(cookie_string, "skynet[-]jwt")
assert.are.equals(cookie, "skynet-jwt=MTY0NzUyr8jD-ytiWtspm0tGabKfooxeIDuWcXhJ3lnY0eEw==")
end)
end)
describe("extract_cookie_value", function()
local cookie_string = "aaa=bbb; skynet-jwt=MTY0NzUyr8jD-ytiWtspm0tGabKfooxeIDuWcXhJ3lnY0eEw==; xxx=yyy"
it("should return nil if cookie string is nil", function()
local value = utils.extract_cookie_value(nil, "aaa")
assert.is_nil(value)
end)
it("should return nil if cookie name is not found", function()
local value = utils.extract_cookie_value(cookie_string, "foo")
assert.is_nil(value)
end)
it("should return value if cookie_string starts with that cookie name", function()
local value = utils.extract_cookie_value(cookie_string, "aaa")
assert.are.equals(value, "bbb")
end)
it("should return cookie if cookie_string ends with that cookie name", function()
local value = utils.extract_cookie_value(cookie_string, "xxx")
assert.are.equals(value, "yyy")
end)
it("should return cookie with custom matcher", function()
local value = utils.extract_cookie_value(cookie_string, "skynet[-]jwt")
assert.are.equals(value, "MTY0NzUyr8jD-ytiWtspm0tGabKfooxeIDuWcXhJ3lnY0eEw==")
end)
end)
describe("getenv", function()
before_each(function()
stub(os, "getenv")
end)
after_each(function()
os.getenv:revert()
end)
it("should return nil for not existing env var", function()
os.getenv.on_call_with("foo").returns(nil)
assert.is_nil(utils.getenv("foo"))
end)
it("should return nil for env var that is an empty string", function()
os.getenv.on_call_with("foo").returns("")
assert.is_nil(utils.getenv("foo"))
end)
it("should return the value as is when it is non empty string", function()
os.getenv.on_call_with("foo").returns("bar")
assert.is_equal(utils.getenv("foo"), "bar")
end)
describe("parse", function()
it("should throw on not supported parser", function()
os.getenv.on_call_with("foo").returns("test")
assert.has_error(function()
utils.getenv("foo", "starwars")
end, "utils.getenv: Parsing to 'starwars' is not supported")
end)
describe("as boolean", function()
it("should return nil for not existing env var", function()
os.getenv.on_call_with("foo").returns(nil)
assert.is_nil(utils.getenv("foo", "boolean"))
end)
it("should return nil for env var that is an empty string", function()
os.getenv.on_call_with("foo").returns("")
assert.is_nil(utils.getenv("foo", "boolean"))
end)
it("should parse 'true' string as true", function()
os.getenv.on_call_with("foo").returns("true")
assert.is_true(utils.getenv("foo", "boolean"))
end)
it("should parse 'True' string as true", function()
os.getenv.on_call_with("foo").returns("True")
assert.is_true(utils.getenv("foo", "boolean"))
end)
it("should parse '1' string as true", function()
os.getenv.on_call_with("foo").returns("1")
assert.is_true(utils.getenv("foo", "boolean"))
end)
it("should parse 'false' string as false", function()
os.getenv.on_call_with("foo").returns("false")
assert.is_false(utils.getenv("foo", "boolean"))
end)
it("should parse 'False' string as false", function()
os.getenv.on_call_with("foo").returns("False")
assert.is_false(utils.getenv("foo", "boolean"))
end)
it("should parse '0' string as false", function()
os.getenv.on_call_with("foo").returns("0")
assert.is_false(utils.getenv("foo", "boolean"))
end)
it("should throw an error for not supported string", function()
os.getenv.on_call_with("foo").returns("mandalorian")
assert.has_error(function()
utils.getenv("foo", "boolean")
end, "utils.getenv: Parsing value 'mandalorian' to boolean is not supported")
end)
end)
describe("as integer", function()
it("should return nil for not existing env var", function()
os.getenv.on_call_with("foo").returns(nil)
assert.is_nil(utils.getenv("foo", "integer"))
end)
it("should return nil for env var that is an empty string", function()
os.getenv.on_call_with("foo").returns("")
assert.is_nil(utils.getenv("foo", "integer"))
end)
it("should parse '0' string as 0", function()
os.getenv.on_call_with("foo").returns("0")
assert.equals(utils.getenv("foo", "integer"), 0)
end)
it("should parse '1' string as 1", function()
os.getenv.on_call_with("foo").returns("1")
assert.equals(utils.getenv("foo", "integer"), 1)
end)
it("should parse '-1' string as -1", function()
os.getenv.on_call_with("foo").returns("-1")
assert.equals(utils.getenv("foo", "integer"), -1)
end)
it("should return nil for non numerical string", function()
os.getenv.on_call_with("foo").returns("test")
assert.is_nil(utils.getenv("foo", "integer"))
end)
end)
end)
end)

View File

@ -1,125 +0,0 @@
# nginx.conf -- docker-openresty
#
# This file is installed to:
# `/usr/local/openresty/nginx/conf/nginx.conf`
# and is the file loaded by nginx at startup,
# unless the user specifies otherwise.
#
# It tracks the upstream OpenResty's `nginx.conf`, but removes the `server`
# section and adds this directive:
# `include /etc/nginx/conf.d/*.conf;`
#
# The `docker-openresty` file `nginx.vh.default.conf` is copied to
# `/etc/nginx/conf.d/default.conf`. It contains the `server section
# of the upstream `nginx.conf`.
#
# See https://github.com/openresty/docker-openresty/blob/master/README.md#nginx-config-files
#
user root;
worker_processes auto;
# Enables the use of JIT for regular expressions to speed-up their processing.
pcre_jit on;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
# declare env variables to use it in config
env PORTAL_DOMAIN;
env SERVER_DOMAIN;
env PORTAL_MODULES;
env ACCOUNTS_LIMIT_ACCESS;
env SIA_API_PASSWORD;
events {
worker_connections 8192;
}
http {
include mime.types;
default_type application/octet-stream;
lua_package_path "/etc/nginx/libs/?.lua;;";
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" $upstream_response_time '
'$upstream_bytes_sent $upstream_bytes_received '
'"$upstream_http_content_type" "$upstream_cache_status" '
'"$server_alias" "$sent_http_skynet_skylink" '
'$upstream_connect_time $upstream_header_time '
'$request_time "$hns_domain" "$skylink" $upstream_http_skynet_cache_ratio';
access_log logs/access.log main;
# See Move default writable paths to a dedicated directory (#119)
# https://github.com/openresty/docker-openresty/issues/119
client_body_temp_path /var/run/openresty/nginx-client-body;
proxy_temp_path /var/run/openresty/nginx-proxy;
fastcgi_temp_path /var/run/openresty/nginx-fastcgi;
uwsgi_temp_path /var/run/openresty/nginx-uwsgi;
scgi_temp_path /var/run/openresty/nginx-scgi;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
# globally enable http 1.1 on all proxied requests
# http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_http_version
proxy_http_version 1.1;
# proxy cache definition
proxy_cache_path /data/nginx/cache levels=1:2 keys_zone=skynet:10m max_size=50g min_free=100g inactive=48h use_temp_path=off;
# this runs before forking out nginx worker processes
init_by_lua_block {
require "cjson"
require "resty.http"
require "skynet.skylink"
require "skynet.utils"
}
# include skynet-portal-api and skynet-server-api header on every request
header_filter_by_lua_block {
ngx.header["Skynet-Portal-Api"] = ngx.var.scheme .. "://" .. ngx.var.skynet_portal_domain
ngx.header["Skynet-Server-Api"] = ngx.var.scheme .. "://" .. ngx.var.skynet_server_domain
}
# ratelimit specified IPs
geo $limit {
default 0;
include /etc/nginx/conf.d/include/ratelimited;
}
map $limit $limit_key {
0 "";
1 $binary_remote_addr;
}
limit_req_zone $binary_remote_addr zone=uploads_by_ip:10m rate=10r/s;
limit_req_zone $limit_key zone=uploads_by_ip_throttled:10m rate=10r/m;
limit_req_zone $binary_remote_addr zone=registry_access_by_ip:10m rate=60r/m;
limit_req_zone $limit_key zone=registry_access_by_ip_throttled:10m rate=20r/m;
limit_conn_zone $binary_remote_addr zone=upload_conn:10m;
limit_conn_zone $limit_key zone=upload_conn_rl:10m;
limit_conn_zone $binary_remote_addr zone=downloads_by_ip:10m;
limit_req_status 429;
limit_conn_status 429;
# Add X-Forwarded-* headers
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/conf.extra.d/*.conf;
}

View File

@ -1,6 +0,0 @@
exclude = {
"/usr/local/openresty", -- internal openresty libraries
"rbusted", -- busted executable
"basexx", -- external library https://github.com/aiq/basexx
}
includeuntestedfiles = true

View File

@ -1,11 +0,0 @@
FROM openresty/openresty:1.19.9.1-focal
WORKDIR /etc/nginx
RUN luarocks install lua-resty-http && \
luarocks install hasher && \
luarocks install busted
COPY rbusted /etc/nginx/
CMD ["/etc/nginx/rbusted", "--verbose", "--pattern=spec", "/usr/local/openresty/site/lualib"]

View File

@ -1,3 +0,0 @@
# Running tests locally
`docker run -v $(pwd)/docker/nginx/libs:/usr/local/openresty/site/lualib --rm -it $(docker build -q docker/nginx/testing)`

View File

@ -1,8 +0,0 @@
#!/usr/bin/env resty
setmetatable(_G, nil)
pcall(require, "luarocks.loader")
-- Busted command-line runner
require "busted.runner"({ standalone = false })

View File

@ -1,16 +0,0 @@
FROM golang:1.16.7 AS sia-builder
ENV GOOS linux
ENV GOARCH amd64
ARG branch=portal-latest
RUN git clone https://gitlab.com/SkynetLabs/skyd.git Sia --single-branch --branch ${branch} && \
make release --directory Sia
FROM nebulouslabs/sia:1.5.6
COPY --from=sia-builder /go/bin/ /usr/bin/
RUN if [ -f "/usr/bin/skyd" ]; then mv /usr/bin/skyd /usr/bin/siad; fi && \
if [ -f "/usr/bin/skyc" ]; then mv /usr/bin/skyc /usr/bin/siac; fi

View File

@ -1,4 +0,0 @@
node_modules/
.cache/
public/
storybook-build/

View File

@ -1,6 +0,0 @@
module.exports = {
globals: {
__PATH_PREFIX__: true,
},
extends: ["react-app", "plugin:storybook/recommended"],
};

View File

@ -1,4 +0,0 @@
node_modules/
.cache/
public/
storybook-build/

View File

@ -1,4 +0,0 @@
node_modules/
.cache/
public/
storybook-build/

View File

@ -1,3 +0,0 @@
{
"printWidth": 120
}

View File

@ -1,19 +0,0 @@
module.exports = {
stories: ["../src/**/*.stories.@(js|jsx|ts|tsx)"],
addons: [
"@storybook/addon-links",
"@storybook/addon-essentials",
"storybook-addon-gatsby",
{
name: "@storybook/addon-postcss",
options: {
postcssLoaderOptions: {
implementation: require("postcss"),
},
},
},
],
core: {
builder: "webpack5",
},
};

View File

@ -1,20 +0,0 @@
import "tailwindcss/tailwind.css";
import "@fontsource/sora/300.css"; // light
import "@fontsource/sora/400.css"; // normal
import "@fontsource/sora/500.css"; // medium
import "@fontsource/sora/600.css"; // semibold
import "@fontsource/source-sans-pro/400.css"; // normal
import "@fontsource/source-sans-pro/600.css"; // semibold
import "../src/styles/global.css";
export const parameters = {
actions: { argTypesRegex: "^on[A-Z].*" },
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/,
},
},
layout: "fullscreen",
};

View File

@ -1,18 +0,0 @@
FROM node:16.14.2-alpine
WORKDIR /usr/app
COPY package.json \
yarn.lock \
./
RUN yarn --frozen-lockfile
COPY static ./static
COPY src ./src
COPY gatsby*.js \
postcss.config.js \
tailwind.config.js \
./
CMD ["sh", "-c", "yarn build && yarn serve --host 0.0.0.0 -p 9000"]

View File

@ -1,30 +0,0 @@
# Skynet Account Dashboard
Code behind [account.skynetpro.net](https://account.skynetpro.net/)
## Development
This is a Gatsby application. To run it locally, all you need is:
- `yarn install`
- `yarn start`
## Accessing remote APIs
To have a fully functioning local environment, you'll need to make the browser believe you're actually on the same domain as a working API (i.e. a remote dev or production server) -- otherwise the browser will block the session cookie.
To do the trick, configure proper environment variables in the `.env.development` file.
This file allows to easily control which domain name you want to use locally and which API you'd like to access.
Example:
```env
GATSBY_PORTAL_DOMAIN=skynetfree.net # Use skynetfree.net APIs
GATSBY_HOST=local.skynetfree.net # Address of your local build
```
> It's recommended to keep the 2LD the same, so any cookies dispatched by the API work without issues.
With the file configured, run `yarn develop:secure` -- it will run `gatsby develop` with `--https -p=443` options.
If you're on macOS, you may need to `sudo` the command to successfully bind to port `443` (https).
Gatsby will automatically add a proper entry to your `/etc/hosts` file and clean it up when process exits.

View File

@ -1,32 +0,0 @@
import * as React from "react";
import { SWRConfig } from "swr";
import { Elements } from "@stripe/react-stripe-js";
import { loadStripe } from "@stripe/stripe-js";
import "@fontsource/sora/300.css"; // light
import "@fontsource/sora/400.css"; // normal
import "@fontsource/sora/500.css"; // medium
import "@fontsource/sora/600.css"; // semibold
import "@fontsource/source-sans-pro/400.css"; // normal
import "@fontsource/source-sans-pro/600.css"; // semibold
import "./src/styles/global.css";
import swrConfig from "./src/lib/swrConfig";
import { MODAL_ROOT_ID } from "./src/components/Modal";
import { PortalSettingsProvider } from "./src/contexts/portal-settings";
const stripePromise = loadStripe(process.env.GATSBY_STRIPE_PUBLISHABLE_KEY);
export function wrapPageElement({ element, props }) {
const Layout = element.type.Layout ?? React.Fragment;
return (
<PortalSettingsProvider>
<SWRConfig value={swrConfig}>
<Elements stripe={stripePromise}>
<Layout {...props}>
{element}
<div id={MODAL_ROOT_ID} />
</Layout>
</Elements>
</SWRConfig>
</PortalSettingsProvider>
);
}

View File

@ -1,57 +0,0 @@
require("dotenv").config({
path: `.env.${process.env.NODE_ENV}`,
});
const { createProxyMiddleware } = require("http-proxy-middleware");
const { GATSBY_PORTAL_DOMAIN } = process.env;
module.exports = {
siteMetadata: {
title: `Account Dashboard`,
siteUrl: `https://account.${GATSBY_PORTAL_DOMAIN}`,
},
// pathPrefix: "/v2",
trailingSlash: "never",
plugins: [
"gatsby-plugin-image",
"gatsby-plugin-provide-react",
"gatsby-plugin-react-helmet",
"gatsby-plugin-sharp",
"gatsby-transformer-sharp",
"gatsby-plugin-styled-components",
"gatsby-plugin-postcss",
{
resolve: "gatsby-source-filesystem",
options: {
name: "images",
path: "./static/images/",
},
__key: "images",
},
],
developMiddleware: (app) => {
// Proxy Accounts service API requests:
app.use(
"/api/",
createProxyMiddleware({
target: `https://account.${GATSBY_PORTAL_DOMAIN}`,
secure: false, // Do not reject self-signed certificates.
changeOrigin: true,
})
);
// Proxy /skynet requests (e.g. uploads)
app.use(
["/skynet", "/__internal/"],
createProxyMiddleware({
target: `https://${GATSBY_PORTAL_DOMAIN}`,
secure: false, // Do not reject self-signed certificates.
changeOrigin: true,
pathRewrite: {
"^/skynet": "",
},
})
);
},
};

View File

@ -1,32 +0,0 @@
import * as React from "react";
import { SWRConfig } from "swr";
import { Elements } from "@stripe/react-stripe-js";
import { loadStripe } from "@stripe/stripe-js";
import "@fontsource/sora/300.css"; // light
import "@fontsource/sora/400.css"; // normal
import "@fontsource/sora/500.css"; // medium
import "@fontsource/sora/600.css"; // semibold
import "@fontsource/source-sans-pro/400.css"; // normal
import "@fontsource/source-sans-pro/600.css"; // semibold
import "./src/styles/global.css";
import swrConfig from "./src/lib/swrConfig";
import { MODAL_ROOT_ID } from "./src/components/Modal";
import { PortalSettingsProvider } from "./src/contexts/portal-settings";
const stripePromise = loadStripe(process.env.GATSBY_STRIPE_PUBLISHABLE_KEY);
export function wrapPageElement({ element, props }) {
const Layout = element.type.Layout ?? React.Fragment;
return (
<PortalSettingsProvider>
<SWRConfig value={swrConfig}>
<Elements stripe={stripePromise}>
<Layout {...props}>
{element}
<div id={MODAL_ROOT_ID} />
</Layout>
</Elements>
</SWRConfig>
</PortalSettingsProvider>
);
}

View File

@ -1,84 +0,0 @@
{
"name": "accounts-dashboard",
"version": "1.0.0",
"private": true,
"description": "Accounts Dashboard",
"author": "Skynet Labs",
"keywords": [
"gatsby"
],
"scripts": {
"develop": "gatsby develop",
"develop:secure": "dotenv -e .env.development -- gatsby develop --https -p=443",
"start": "gatsby develop",
"build": "gatsby build --prefix-paths",
"serve": "gatsby serve --prefix-paths",
"clean": "gatsby clean",
"lint": "eslint .",
"prettier": "prettier .",
"storybook": "start-storybook -p 6006",
"build-storybook": "build-storybook -o storybook-build"
},
"dependencies": {
"@fontsource/sora": "^4.5.3",
"@fontsource/source-sans-pro": "^4.5.3",
"@stripe/react-stripe-js": "^1.7.1",
"@stripe/stripe-js": "^1.27.0",
"classnames": "^2.3.1",
"copy-text-to-clipboard": "^3.0.1",
"dayjs": "^1.10.8",
"formik": "^2.2.9",
"gatsby": "^4.6.2",
"gatsby-plugin-postcss": "^5.7.0",
"http-status-codes": "^2.2.0",
"ky": "^0.30.0",
"nanoid": "^3.3.1",
"path-browserify": "^1.0.1",
"postcss": "^8.4.6",
"react": "^17.0.1",
"react-dom": "^17.0.1",
"react-dropzone": "^12.0.4",
"react-helmet": "^6.1.0",
"react-use": "^17.3.2",
"skynet-js": "4.0.27-beta",
"swr": "^1.2.2",
"tailwindcss": "^3.0.23",
"yup": "^0.32.11"
},
"devDependencies": {
"@babel/core": "^7.17.4",
"@storybook/addon-actions": "^6.4.19",
"@storybook/addon-essentials": "^6.4.19",
"@storybook/addon-interactions": "^6.4.19",
"@storybook/addon-links": "^6.4.19",
"@storybook/addon-postcss": "^2.0.0",
"@storybook/builder-webpack5": "^6.4.19",
"@storybook/manager-webpack5": "^6.4.19",
"@storybook/react": "^6.4.19",
"@storybook/testing-library": "^0.0.9",
"autoprefixer": "^10.4.2",
"babel-eslint": "^10.1.0",
"babel-loader": "^8.2.3",
"babel-plugin-preval": "^5.1.0",
"babel-plugin-styled-components": "^2.0.2",
"dotenv": "^16.0.0",
"dotenv-cli": "^5.1.0",
"eslint": "^8.9.0",
"eslint-config-react-app": "^7.0.0",
"eslint-plugin-storybook": "^0.5.6",
"gatsby-plugin-alias-imports": "^1.0.5",
"gatsby-plugin-image": "^2.6.0",
"gatsby-plugin-preval": "^1.0.0",
"gatsby-plugin-provide-react": "^1.0.2",
"gatsby-plugin-react-helmet": "^5.6.0",
"gatsby-plugin-sharp": "^4.6.0",
"gatsby-plugin-styled-components": "^5.8.0",
"gatsby-source-filesystem": "^4.6.0",
"gatsby-transformer-sharp": "^4.6.0",
"http-proxy-middleware": "^1.3.1",
"prettier": "2.5.1",
"react-is": "^17.0.2",
"storybook-addon-gatsby": "^0.0.5",
"styled-components": "^5.3.3"
}
}

View File

@ -1,3 +0,0 @@
module.exports = {
plugins: [require("tailwindcss/nesting"), require("tailwindcss"), require("autoprefixer")],
};

View File

@ -1,157 +0,0 @@
import dayjs from "dayjs";
import cn from "classnames";
import { useCallback, useState } from "react";
import { Alert } from "../Alert";
import { Button } from "../Button";
import { AddSkylinkToSponsorKeyForm } from "../forms/AddSkylinkToSponsorKeyForm";
import { CogIcon, TrashIcon } from "../Icons";
import { Modal } from "../Modal";
import { useAPIKeyEdit } from "./useAPIKeyEdit";
import { useAPIKeyRemoval } from "./useAPIKeyRemoval";
export const APIKey = ({ apiKey, onRemoved, onEdited, onRemovalError }) => {
const { id, name, createdAt, skylinks } = apiKey;
const isSponsorKey = apiKey.public === "true";
const [error, setError] = useState(null);
const onSkylinkListEdited = useCallback(() => {
setError(null);
onEdited();
}, [onEdited]);
const onSkylinkListEditFailure = (errorMessage) => setError(errorMessage);
const {
removalError,
removalInitiated,
prompt: promptRemoval,
abort: abortRemoval,
confirm: confirmRemoval,
} = useAPIKeyRemoval({
key: apiKey,
onSuccess: onRemoved,
onFailure: onRemovalError,
});
const {
editInitiated,
prompt: promptEdit,
abort: abortEdit,
addSkylink,
removeSkylink,
} = useAPIKeyEdit({
key: apiKey,
onSkylinkListUpdate: onSkylinkListEdited,
onSkylinkListUpdateFailure: onSkylinkListEditFailure,
});
const closeEditModal = useCallback(() => {
setError(null);
abortEdit();
}, [abortEdit]);
const skylinksNumber = skylinks?.length ?? 0;
const isNotConfigured = isSponsorKey && skylinksNumber === 0;
const skylinksPhrasePrefix = skylinksNumber === 0 ? "No" : skylinksNumber;
const skylinksPhrase = `${skylinksPhrasePrefix} ${skylinksNumber === 1 ? "skylink" : "skylinks"} sponsored`;
return (
<li
className={cn(
"grid grid-cols-2 sm:grid-cols-[1fr_repeat(2,_max-content)] py-3 px-4 gap-x-8 items-center bg-white odd:bg-palette-100/50"
)}
>
<span className="col-span-2 sm:col-span-1 flex items-center">
<span className="flex flex-col">
<span className={cn("truncate", { "text-palette-300": !name })}>{name || "unnamed key"}</span>
{isSponsorKey && (
<button
onClick={promptEdit}
className={cn("text-xs hover:underline decoration-dotted", {
"text-error": isNotConfigured,
"text-palette-400": !isNotConfigured,
})}
>
{skylinksPhrase}
</button>
)}
</span>
</span>
<span className="col-span-2 my-4 border-t border-t-palette-200/50 sm:hidden" />
<span className="text-palette-400">{dayjs(createdAt).format("MMM DD, YYYY")}</span>
<span className="flex items-center justify-end">
{isSponsorKey && (
<button
title="Add or remove skylinks"
aria-label="Add or remove skylinks"
className="p-1 transition-colors hover:text-primary"
onClick={promptEdit}
>
<CogIcon size={22} />
</button>
)}
<button
title="Delete this API key"
aria-label="Delete this API key"
className="p-1 transition-colors hover:text-error"
onClick={promptRemoval}
>
<TrashIcon size={16} />
</button>
</span>
{removalInitiated && (
<Modal onClose={abortRemoval} className="flex flex-col gap-4 text-center">
<h4>Delete API key</h4>
<div>
<p>Are you sure you want to delete the following API key?</p>
<p className="font-semibold">{name || id}</p>
</div>
{removalError && <Alert $variant="error">{removalError}</Alert>}
<div className="flex gap-4 justify-center mt-4">
<Button $primary onClick={abortRemoval}>
Cancel
</Button>
<Button onClick={confirmRemoval}>Delete</Button>
</div>
</Modal>
)}
{editInitiated && (
<Modal onClose={closeEditModal} className="flex flex-col gap-4 text-center sm:px-8 sm:py-6">
<h4>Sponsored skylinks</h4>
{skylinks?.length > 0 ? (
<ul className="text-xs flex flex-col gap-2">
{skylinks.map((skylink) => (
<li key={skylink} className="grid grid-cols-[1fr_min-content] w-full gap-4 items-center">
<code className="whitespace-nowrap select-all truncate bg-palette-100 odd:bg-white p-1">
{skylink}
</code>
<button
className="p-1 transition-colors hover:text-error"
onClick={() => removeSkylink(skylink)}
aria-label="Remove skylink"
>
<TrashIcon size={16} />
</button>
</li>
))}
</ul>
) : (
<Alert $variant="info">No skylinks here yet. You can add the first one below 🙃</Alert>
)}
<div className="flex flex-col gap-4">
{error && <Alert $variant="error">{error}</Alert>}
<AddSkylinkToSponsorKeyForm addSkylink={addSkylink} />
</div>
<div className="flex gap-4 justify-center mt-4">
<Button onClick={closeEditModal}>Close</Button>
</div>
</Modal>
)}
</li>
);
};

View File

@ -1,14 +0,0 @@
import { APIKey } from "./APIKey";
export const APIKeyList = ({ keys, reloadKeys, title }) => {
return (
<>
<h6 className="text-palette-300 mb-4">{title}</h6>
<ul className="mt-4">
{keys.map((key) => (
<APIKey key={key.id} apiKey={key} onEdited={reloadKeys} onRemoved={reloadKeys} />
))}
</ul>
</>
);
};

View File

@ -1 +0,0 @@
export * from "./APIKeyList";

View File

@ -1,43 +0,0 @@
import { useCallback, useState } from "react";
import accountsService from "../../services/accountsService";
export const useAPIKeyEdit = ({ key, onSkylinkListUpdate, onSkylinkListUpdateFailure }) => {
const [editInitiated, setEditInitiated] = useState(false);
const prompt = () => setEditInitiated(true);
const abort = () => setEditInitiated(false);
const updateSkylinkList = useCallback(
async (action, skylink) => {
try {
await accountsService.patch(`user/apikeys/${key.id}`, {
json: {
[action]: [skylink],
},
});
onSkylinkListUpdate();
return true;
} catch (err) {
if (err.response) {
const { message } = await err.response.json();
onSkylinkListUpdateFailure(message);
} else {
onSkylinkListUpdateFailure("Unknown error occured, please try again.");
}
return false;
}
},
[onSkylinkListUpdate, onSkylinkListUpdateFailure, key]
);
const addSkylink = (skylink) => updateSkylinkList("add", skylink);
const removeSkylink = (skylink) => updateSkylinkList("remove", skylink);
return {
editInitiated,
prompt,
abort,
addSkylink,
removeSkylink,
};
};

View File

@ -1,41 +0,0 @@
import { useCallback, useState } from "react";
import accountsService from "../../services/accountsService";
export const useAPIKeyRemoval = ({ key, onSuccess }) => {
const [removalInitiated, setRemovalInitiated] = useState(false);
const [removalError, setRemovalError] = useState(null);
const prompt = () => {
setRemovalError(null);
setRemovalInitiated(true);
};
const abort = () => setRemovalInitiated(false);
const confirm = useCallback(async () => {
setRemovalError(null);
try {
await accountsService.delete(`user/apikeys/${key.id}`);
setRemovalInitiated(false);
onSuccess();
} catch (err) {
let message = "There was an error processing your request. Please try again later.";
if (err.response) {
const response = await err.response.json();
if (response.message) {
message = response.message;
}
}
setRemovalError(message);
}
}, [onSuccess, key]);
return {
removalInitiated,
removalError,
prompt,
abort,
confirm,
};
};

View File

@ -1,10 +0,0 @@
import styled from "styled-components";
import cn from "classnames";
export const Alert = styled.div.attrs(({ $variant }) => ({
className: cn("px-3 py-2 sm:px-6 sm:py-4 rounded border", {
"bg-blue-100 border-blue-200 text-palette-400": $variant === "info",
"bg-red-100 border-red-200 text-error": $variant === "error",
"bg-green-100 border-green-200 text-palette-400": $variant === "success",
}),
}))``;

View File

@ -1 +0,0 @@
export * from "./Alert";

View File

@ -1,36 +0,0 @@
import { useEffect, useState } from "react";
import { useUser } from "../../contexts/user";
// import { SimpleUploadIcon } from "../Icons";
import avatarPlaceholder from "../../../static/images/avatar-placeholder.svg";
export const AvatarUploader = (props) => {
const { user } = useUser();
const [imageUrl, setImageUrl] = useState(avatarPlaceholder);
useEffect(() => {
setImageUrl(user.avatarUrl ?? avatarPlaceholder);
}, [user]);
return (
<div {...props}>
<div
className={`flex justify-center items-center xl:w-[245px] xl:h-[245px] bg-contain bg-none xl:bg-[url(/images/avatar-bg.svg)]`}
>
<img src={imageUrl} className="w-[160px]" alt="" />
</div>
{/* TODO: uncomment when avatar uploads work
<div className="flex justify-center">
<button
className="flex items-center gap-4 hover:underline decoration-1 decoration-dashed underline-offset-2 decoration-gray-400"
type="button"
onClick={console.info.bind(console)}
>
<SimpleUploadIcon size={20} className="shrink-0" /> Upload profile picture
</button>
</div>
*/}
</div>
);
};

View File

@ -1 +0,0 @@
export * from "./AvatarUploader";

Some files were not shown because too many files have changed in this diff Show More