Compare commits

...

328 commits

Author SHA1 Message Date
c813819c4d Merge pull request 'chore(deps): update dependency jsdom to v25.0.1' (#172) from renovate/jsdom-25.x-lockfile into master
Reviewed-on: #172
2024-09-24 17:59:22 +05:30
Renovate Bot
1660c1033c chore(deps): update dependency jsdom to v25.0.1
All checks were successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-09-22 05:06:20 +00:00
b75db26783 Merge pull request 'chore(deps): update dependency eslint to v9.11.0' (#171) from renovate/eslint-monorepo into master
Reviewed-on: #171
2024-09-21 20:05:21 +05:30
Renovate Bot
820e1aa819 chore(deps): update dependency eslint to v9.11.0
All checks were successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-09-20 16:06:19 +00:00
bba7e336dd Merge pull request 'chore(deps): update typescript-eslint monorepo to v8.6.0' (#170) from renovate/typescript-eslint-monorepo into master
Reviewed-on: #170
2024-09-17 12:06:57 +05:30
Renovate Bot
c9f8b1d0bb chore(deps): update typescript-eslint monorepo to v8.6.0
All checks were successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-09-16 17:37:36 +00:00
8a1b4c4f9a Merge pull request 'chore(deps): update dependency sinon to v19' (#169) from renovate/sinon-19.x into master
Reviewed-on: #169
2024-09-16 17:49:23 +05:30
Renovate Bot
f94dd07902 chore(deps): update dependency sinon to v19
All checks were successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-09-16 09:06:07 +00:00
7c081e9e0c Merge pull request 'chore(deps): update dependency typescript to v5.6.2' (#160) from renovate/typescript-5.x-lockfile into master
Reviewed-on: #160
2024-09-16 14:09:54 +05:30
36d1bc7018 Merge pull request 'chore(deps): update typescript-eslint monorepo to v8.5.0' (#157) from renovate/typescript-eslint-monorepo into master
Reviewed-on: #157
2024-09-16 14:08:51 +05:30
Renovate Bot
846bb4c0f6 chore(deps): update typescript-eslint monorepo to v8.5.0
All checks were successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-09-13 15:45:08 +00:00
2a3b118d0a Merge pull request 'fix(deps): update rust crate derive_builder to v0.20.1' (#167) from renovate/derive_builder-0.x-lockfile into master
Reviewed-on: #167
2024-09-13 21:07:00 +05:30
687913aad4 Merge pull request 'fix(deps): update rust crate actix-cors to 0.7.0' (#168) from renovate/actix-cors-0.x into master
Reviewed-on: #168
2024-09-13 21:06:04 +05:30
657c78f6d7 Merge pull request 'chore(deps): update dependency eslint to v9.10.0' (#159) from renovate/eslint-monorepo into master
Reviewed-on: #159
2024-09-13 21:05:52 +05:30
52eb65e545 Merge pull request 'chore(deps): update dependency sinon to v18.0.1' (#161) from renovate/sinon-18.x-lockfile into master
Reviewed-on: #161
2024-09-13 21:05:44 +05:30
Renovate Bot
8d2d4b168b fix(deps): update rust crate actix-cors to 0.7.0
All checks were successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-09-13 12:45:14 +00:00
Renovate Bot
9dadb97ad0 chore(deps): update dependency typescript to v5.6.2
All checks were successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-09-13 12:44:50 +00:00
Renovate Bot
c42e500c21 chore(deps): update dependency eslint to v9.10.0
All checks were successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-09-13 12:44:38 +00:00
Renovate Bot
b93fd63ff2 fix(deps): update rust crate derive_builder to v0.20.1
All checks were successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-09-13 12:44:23 +00:00
Renovate Bot
75c26b8783 chore(deps): update dependency sinon to v18.0.1
All checks were successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-09-13 12:44:12 +00:00
e7221e2595 Merge pull request 'fix(deps): update rust crate actix-session to v0.10.1' (#166) from renovate/actix-session-0.x-lockfile into master
Reviewed-on: #166
2024-09-13 17:56:08 +05:30
ca2cc3c7ef Merge pull request 'chore(deps): update dependency @types/jest to v29.5.13' (#165) from renovate/jest-monorepo into master
Reviewed-on: #165
2024-09-13 17:56:01 +05:30
Renovate Bot
7d953cd6ae fix(deps): update rust crate actix-session to v0.10.1
All checks were successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-09-13 09:37:56 +00:00
Renovate Bot
c9c3666c8c chore(deps): update dependency @types/jest to v29.5.13
All checks were successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-09-13 09:37:27 +00:00
92f57872ed Merge pull request 'fix(deps): update rust crate async-trait to v0.1.82' (#164) from renovate/async-trait-0.x-lockfile into master
Reviewed-on: #164
2024-09-13 14:42:22 +05:30
b518ff1b53 Merge pull request 'chore(deps): update rust crate serde_json to v1.0.128' (#163) from renovate/serde_json-1.x-lockfile into master
Reviewed-on: #163
2024-09-13 14:42:18 +05:30
22984a7a1e Merge pull request 'chore(deps): update dependency @types/node to v20.16.5' (#162) from renovate/node-20.x-lockfile into master
Reviewed-on: #162
2024-09-13 14:41:33 +05:30
Renovate Bot
d97c45a12f fix(deps): update rust crate async-trait to v0.1.82
All checks were successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-09-12 16:44:48 +00:00
Renovate Bot
2f9256c0bf chore(deps): update rust crate serde_json to v1.0.128
All checks were successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-09-12 16:44:28 +00:00
Renovate Bot
19a6aac68a chore(deps): update dependency @types/node to v20.16.5
All checks were successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-09-12 16:43:59 +00:00
e304bc8a7d Merge pull request 'fix(deps): update rust crate serde to v1.0.210' (#152) from renovate/serde-monorepo into master
Reviewed-on: #152
2024-09-12 22:09:42 +05:30
8bd0561c48 Merge pull request 'chore(deps): update dependency webpack-dev-server to v5.1.0' (#158) from renovate/webpack-dev-server-5.x-lockfile into master
Reviewed-on: #158
2024-09-12 22:03:43 +05:30
9ad6cdce87 Merge pull request 'chore(deps): update jamesives/github-pages-deploy-action action to v4.6.4' (#156) from renovate/jamesives-github-pages-deploy-action-4.x into master
Reviewed-on: #156
2024-09-12 22:03:34 +05:30
Renovate Bot
6aa4958dfa fix(deps): update rust crate serde to v1.0.210
All checks were successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-09-11 14:15:17 +00:00
Renovate Bot
06ccb1438e chore(deps): update dependency webpack-dev-server to v5.1.0
All checks were successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-09-03 18:09:11 +00:00
Renovate Bot
cdfea981b1 chore(deps): update jamesives/github-pages-deploy-action action to v4.6.4
All checks were successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-09-02 16:07:03 +00:00
426b6a2e78 Merge pull request 'chore(deps): update dependency @types/node to v20.16.3' (#155) from renovate/node-20.x-lockfile into master
Reviewed-on: #155
2024-09-02 12:57:28 +05:30
e7635c8ebf Merge pull request 'fix(deps): update rust crate actix-cors to 0.7.0' (#45) from renovate/actix-cors-0.x into master
Reviewed-on: #45
2024-09-02 12:56:53 +05:30
Renovate Bot
6680038ce6 chore(deps): update dependency @types/node to v20.16.3
All checks were successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-09-01 12:36:14 +00:00
Renovate Bot
fef5e21874 fix(deps): update rust crate actix-cors to 0.7.0
All checks were successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-08-30 06:44:20 +00:00
25f5683278 Merge pull request 'chore(deps): update typescript-eslint monorepo to v8.3.0' (#153) from renovate/typescript-eslint-monorepo into master
Reviewed-on: #153
2024-08-30 12:07:17 +05:30
Renovate Bot
34b8c60553 chore(deps): update typescript-eslint monorepo to v8.3.0
All checks were successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-08-29 05:36:09 +00:00
0a9bbea35d Merge pull request 'chore(deps): update dependency @types/node to v20.16.2' (#141) from renovate/node-20.x-lockfile into master
Reviewed-on: #141
2024-08-29 10:46:22 +05:30
Renovate Bot
5b88b3c3e4 chore(deps): update dependency @types/node to v20.16.2
All checks were successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-08-28 16:36:12 +00:00
ce0f375388 Merge pull request 'chore(deps): update dependency jsdom to v25' (#154) from renovate/jsdom-25.x into master
Reviewed-on: #154
2024-08-28 21:42:18 +05:30
02329c694f Merge pull request 'chore(deps): update dependency eslint to v9.9.1' (#150) from renovate/eslint-monorepo into master
Reviewed-on: #150
2024-08-28 21:41:55 +05:30
Renovate Bot
910b95f853 chore(deps): update dependency jsdom to v25
All checks were successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-08-28 08:37:35 +00:00
Renovate Bot
55bd0c5684 chore(deps): update dependency eslint to v9.9.1
All checks were successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-08-28 08:36:29 +00:00
7d34e25109 Merge pull request 'fix(deps): update rust crate serde to v1.0.209' (#147) from renovate/serde-monorepo into master
Reviewed-on: #147
2024-08-28 13:43:56 +05:30
ac3dbd757c Merge pull request 'chore(deps): update dependency ts-jest to v29.2.5' (#149) from renovate/ts-jest-29.x-lockfile into master
Reviewed-on: #149
2024-08-28 13:42:22 +05:30
0bf415a7a4 Merge pull request 'chore(deps): update dependency webpack to v5.94.0' (#148) from renovate/webpack-5.x-lockfile into master
Reviewed-on: #148
2024-08-28 13:42:02 +05:30
Renovate Bot
9f16c7f33a chore(deps): update dependency ts-jest to v29.2.5
All checks were successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-08-23 15:06:04 +00:00
Renovate Bot
24d656d384 chore(deps): update dependency webpack to v5.94.0
All checks were successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-08-22 13:05:53 +00:00
Renovate Bot
734133246c fix(deps): update rust crate serde to v1.0.208
All checks were successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
ci/woodpecker/pr/woodpecker Pipeline was successful
2024-08-19 08:35:30 +00:00
e158480950 Merge pull request 'chore(deps): update rust crate serde_json to v1.0.125' (#144) from renovate/serde_json-1.x-lockfile into master
Reviewed-on: https://git.batsense.net///mCaptcha/survey/pulls/144
2024-08-19 13:52:44 +05:30
38e26ab078 Merge pull request 'fix(deps): update rust crate actix-web to v4.9.0' (#146) from renovate/actix-web-4.x-lockfile into master
Reviewed-on: https://git.batsense.net///mCaptcha/survey/pulls/146
2024-08-19 13:51:11 +05:30
9fa6faa315 Merge pull request 'chore(deps): update typescript-eslint monorepo to v8.1.0' (#145) from renovate/typescript-eslint-monorepo into master
Reviewed-on: https://git.batsense.net///mCaptcha/survey/pulls/145
2024-08-19 13:51:08 +05:30
948a475b35 Merge pull request 'chore(deps): update postgres docker tag to v16.4' (#140) from renovate/postgres-16.x into master
Reviewed-on: https://git.batsense.net///mCaptcha/survey/pulls/140
2024-08-19 13:49:33 +05:30
a7d7707859 Merge pull request 'fix(deps): update rust crate actix-session to 0.10.0' (#50) from renovate/actix-session-0.x into master
Reviewed-on: https://git.batsense.net///mCaptcha/survey/pulls/50
2024-08-19 13:49:03 +05:30
Renovate Bot
0a4b337acd chore(deps): update rust crate serde_json to v1.0.125
All checks were successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-08-15 06:06:33 +00:00
Renovate Bot
388f9f86e6 fix(deps): update rust crate actix-web to v4.9.0
All checks were successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-08-13 10:06:32 +00:00
Renovate Bot
75cb05f44a chore(deps): update typescript-eslint monorepo to v8.1.0
All checks were successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-08-13 10:06:20 +00:00
3435774235 Merge pull request 'fix(deps): update rust crate serde to v1.0.207' (#139) from renovate/serde-monorepo into master
Reviewed-on: https://git.batsense.net///mCaptcha/survey/pulls/139
2024-08-13 15:34:40 +05:30
634075240c Merge pull request 'fix(deps): update rust crate actix-http to v3.9.0' (#143) from renovate/actix-http-3.x-lockfile into master
Reviewed-on: https://git.batsense.net///mCaptcha/survey/pulls/143
2024-08-13 15:31:44 +05:30
193b9037b5 Merge branch 'master' into renovate/actix-http-3.x-lockfile
All checks were successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
ci/woodpecker/pr/woodpecker Pipeline was successful
2024-08-13 15:30:58 +05:30
2d68b2d527 Merge pull request 'chore(deps): update dependency eslint to v9.9.0' (#142) from renovate/eslint-monorepo into master
Reviewed-on: https://git.batsense.net///mCaptcha/survey/pulls/142
2024-08-13 15:29:37 +05:30
Renovate Bot
3dbe0f9ec0 fix(deps): update rust crate serde to v1.0.207
All checks were successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-08-12 20:37:14 +00:00
Renovate Bot
c1db73984c fix(deps): update rust crate actix-http to v3.9.0
All checks were successful
ci/woodpecker/pr/woodpecker Pipeline was successful
2024-08-10 02:36:17 +00:00
Renovate Bot
1acd1ea9dc chore(deps): update dependency eslint to v9.9.0
All checks were successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-08-09 20:35:45 +00:00
Renovate Bot
4c4c840a88 chore(deps): update postgres docker tag to v16.4
All checks were successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-08-08 20:35:21 +00:00
Renovate Bot
a8caa90f1e fix(deps): update rust crate actix-session to 0.10.0
All checks were successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-08-07 00:38:40 +00:00
b0969f23be Merge pull request 'chore(deps): update typescript-eslint monorepo to v8.0.1' (#137) from renovate/typescript-eslint-monorepo into master
Reviewed-on: https://git.batsense.net///mCaptcha/survey/pulls/137
2024-08-06 16:36:49 +05:30
Renovate Bot
bc17778e3d chore(deps): update typescript-eslint monorepo to v8.0.1
All checks were successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-08-05 17:35:20 +00:00
d2b6843f32 Merge pull request 'chore(deps): update dependency @types/node to v20.14.14' (#136) from renovate/node-20.x-lockfile into master
Reviewed-on: https://git.batsense.net///mCaptcha/survey/pulls/136
2024-08-02 15:39:08 +05:30
Renovate Bot
1b3a38b9b2 chore(deps): update dependency @types/node to v20.14.14
All checks were successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-08-02 09:06:03 +00:00
7a61b93405 Merge pull request 'chore(deps): update rust crate serde_json to v1.0.122' (#135) from renovate/serde_json-1.x-lockfile into master
Reviewed-on: https://git.batsense.net///mCaptcha/survey/pulls/135
2024-08-02 11:49:04 +05:30
Renovate Bot
740034d469 chore(deps): update rust crate serde_json to v1.0.122
All checks were successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-08-01 21:37:15 +00:00
67ff07ed12 Merge pull request 'chore(deps): update dependency ts-jest to v29.2.4' (#134) from renovate/ts-jest-29.x-lockfile into master
Reviewed-on: https://git.batsense.net///mCaptcha/survey/pulls/134
2024-08-01 16:20:25 +05:30
Renovate Bot
f8a1754218 chore(deps): update dependency ts-jest to v29.2.4
All checks were successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-08-01 09:04:10 +00:00
e02f8ab354 Merge pull request 'chore(deps): update dependency webpack to v5.93.0' (#133) from renovate/webpack-5.x-lockfile into master
Reviewed-on: https://git.batsense.net///mCaptcha/survey/pulls/133
2024-08-01 11:10:54 +05:30
Renovate Bot
ff4a9c78d8 chore(deps): update dependency webpack to v5.93.0
All checks were successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-08-01 05:34:55 +00:00
8e3a548f39 Merge pull request 'chore(deps): update dependency ts-jest to v29.2.3' (#131) from renovate/ts-jest-29.x-lockfile into master
Reviewed-on: https://git.batsense.net///mCaptcha/survey/pulls/131
2024-08-01 10:50:06 +05:30
Renovate Bot
e8a55135ae chore(deps): update dependency ts-jest to v29.2.3
All checks were successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-08-01 04:34:55 +00:00
90a07c7460 Merge pull request 'chore(deps): update dependency eslint to v9.8.0' (#130) from renovate/eslint-monorepo into master
Reviewed-on: https://git.batsense.net///mCaptcha/survey/pulls/130
2024-08-01 09:55:51 +05:30
Renovate Bot
ffaed65744 chore(deps): update dependency eslint to v9.8.0
All checks were successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-08-01 04:04:14 +00:00
8a3ab62126 Merge pull request 'chore(deps): update dependency typescript to v5.5.4' (#132) from renovate/typescript-5.x-lockfile into master
Reviewed-on: https://git.batsense.net///mCaptcha/survey/pulls/132
2024-08-01 09:21:06 +05:30
4c79e6ce29 Merge pull request 'chore(deps): update dependency jsdom to v24.1.1' (#129) from renovate/jsdom-24.x-lockfile into master
Reviewed-on: https://git.batsense.net///mCaptcha/survey/pulls/129
2024-08-01 09:20:48 +05:30
9c38283fc7 Merge pull request 'chore(deps): update dependency @types/node to v20.14.13' (#128) from renovate/node-20.x-lockfile into master
Reviewed-on: https://git.batsense.net///mCaptcha/survey/pulls/128
2024-08-01 09:20:42 +05:30
Renovate Bot
643b15fa84 chore(deps): update dependency typescript to v5.5.4
All checks were successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-07-31 22:06:22 +00:00
Renovate Bot
2ade878fd6 chore(deps): update dependency jsdom to v24.1.1
All checks were successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-07-31 22:05:41 +00:00
Renovate Bot
c7c0eac818 chore(deps): update dependency @types/node to v20.14.13
All checks were successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-07-31 22:05:29 +00:00
780daffb6f Merge pull request 'chore(deps): update typescript-eslint monorepo to v8 (major)' (#127) from renovate/major-typescript-eslint-monorepo into master
Reviewed-on: https://git.batsense.net///mCaptcha/survey/pulls/127
2024-08-01 03:26:53 +05:30
Renovate Bot
dac0a91e98 chore(deps): update typescript-eslint monorepo to v8
All checks were successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-07-31 18:04:53 +00:00
f6af8dad1f Merge pull request 'chore(deps): update dependency jsdom to v24.1.1' (#118) from renovate/jsdom-24.x-lockfile into master
Reviewed-on: #118
2024-07-30 21:39:44 +05:30
Renovate Bot
a63ada21d9 chore(deps): update dependency jsdom to v24.1.1
Some checks failed
renovate/artifacts Artifact file update failure
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-07-30 13:07:59 +00:00
029f286c50 Merge pull request 'chore(deps): update typescript-eslint monorepo to v7.18.0' (#126) from renovate/typescript-eslint-monorepo into master
Reviewed-on: #126
2024-07-30 18:00:26 +05:30
Renovate Bot
50b76783e2 chore(deps): update typescript-eslint monorepo to v7.18.0
Some checks failed
renovate/artifacts Artifact file update failure
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline is running
2024-07-29 19:34:25 +00:00
ef78076d26 Merge pull request 'chore(deps): update rust crate serde_json to v1.0.121' (#125) from renovate/serde_json-1.x-lockfile into master
Reviewed-on: #125
2024-07-29 16:10:28 +05:30
Renovate Bot
df38dd1b7f chore(deps): update rust crate serde_json to v1.0.121
All checks were successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-07-28 21:34:59 +00:00
2237463682 Merge pull request 'chore(deps): update dependency @types/node to v20.14.13' (#124) from renovate/node-20.x-lockfile into master
Reviewed-on: #124
2024-07-28 20:48:48 +05:30
Renovate Bot
ffe68716cd chore(deps): update dependency @types/node to v20.14.13
Some checks failed
renovate/artifacts Artifact file update failure
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-07-28 12:33:46 +00:00
4969f8b9bd Merge pull request 'chore(deps): update dependency eslint to v9.8.0' (#123) from renovate/eslint-monorepo into master
Reviewed-on: #123
2024-07-27 20:29:01 +05:30
Renovate Bot
bbd31726f6 chore(deps): update dependency eslint to v9.8.0
Some checks failed
renovate/artifacts Artifact file update failure
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-07-26 23:04:42 +00:00
fb9c2bf79b Merge pull request 'chore(deps): update dependency @types/node to v20.14.12' (#122) from renovate/node-20.x-lockfile into master
Reviewed-on: #122
2024-07-24 11:41:36 +05:30
Renovate Bot
9aaf64a1cd chore(deps): update dependency @types/node to v20.14.12
Some checks failed
renovate/artifacts Artifact file update failure
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-07-23 20:33:44 +00:00
75d30bbbfd Merge pull request 'chore(deps): update rust crate sqlx to 0.8' (#121) from renovate/sqlx-0.x into master
Reviewed-on: #121
2024-07-23 14:29:09 +05:30
d89f92fa61 Merge pull request 'chore(deps): update dependency typescript to v5.5.4' (#120) from renovate/typescript-5.x-lockfile into master
Reviewed-on: #120
2024-07-23 14:29:06 +05:30
5870ed74b3 Merge pull request 'chore(deps): update typescript-eslint monorepo to v7.17.0' (#119) from renovate/typescript-eslint-monorepo into master
Reviewed-on: #119
2024-07-23 14:29:02 +05:30
Renovate Bot
442b891da3 chore(deps): update rust crate sqlx to 0.8
All checks were successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-07-23 02:04:51 +00:00
Renovate Bot
adb11eb3a8 chore(deps): update dependency typescript to v5.5.4
Some checks failed
renovate/artifacts Artifact file update failure
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-07-23 01:04:11 +00:00
Renovate Bot
65ea05b085 chore(deps): update typescript-eslint monorepo to v7.17.0
Some checks failed
renovate/artifacts Artifact file update failure
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-07-22 19:33:57 +00:00
945663a08b Merge pull request 'chore(deps): update dependency ts-jest to v29.2.3' (#117) from renovate/ts-jest-29.x-lockfile into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #117
2024-07-19 01:02:05 +05:30
Renovate Bot
4ebbae064c chore(deps): update dependency ts-jest to v29.2.3
Some checks failed
renovate/artifacts Artifact file update failure
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-07-18 18:04:28 +00:00
20d6adee2c Merge pull request 'chore(deps): update dependency @types/node to v20.14.11' (#116) from renovate/node-20.x-lockfile into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #116
2024-07-18 22:45:01 +05:30
Renovate Bot
5d0c95520d chore(deps): update dependency @types/node to v20.14.11
Some checks failed
renovate/artifacts Artifact file update failure
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-07-18 16:46:02 +00:00
6f7d959b01 Merge pull request 'fix(deps): update rust crate tokio to v1.38.1' (#115) from renovate/tokio-1.x-lockfile into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #115
2024-07-17 09:52:18 +05:30
Renovate Bot
09555eaa7e fix(deps): update rust crate tokio to v1.38.1
All checks were successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-07-16 17:35:10 +00:00
77360122c0 Merge pull request 'chore(deps): update typescript-eslint monorepo to v7.16.1' (#114) from renovate/typescript-eslint-monorepo into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #114
2024-07-16 10:34:57 +05:30
Renovate Bot
127053d0d4 chore(deps): update typescript-eslint monorepo to v7.16.1
Some checks failed
renovate/artifacts Artifact file update failure
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-07-15 19:33:36 +00:00
e76bed7f17 Merge pull request 'chore(deps): update typescript-eslint monorepo to v7.16.0' (#109) from renovate/typescript-eslint-monorepo into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #109
2024-07-13 12:58:19 +05:30
5711c84386 Merge pull request 'chore(deps): update dependency eslint to v9.7.0' (#113) from renovate/eslint-monorepo into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #113
2024-07-13 12:57:51 +05:30
Renovate Bot
901b8f52d8 chore(deps): update dependency eslint to v9.7.0
Some checks failed
renovate/artifacts Artifact file update failure
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-07-12 23:04:37 +00:00
e868ac0379 Merge pull request 'chore(deps): update dependency webpack to v5.93.0' (#112) from renovate/webpack-5.x-lockfile into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #112
2024-07-12 16:35:08 +05:30
Renovate Bot
d2ad8bd7de chore(deps): update dependency webpack to v5.93.0
Some checks failed
renovate/artifacts Artifact file update failure
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-07-11 21:04:26 +00:00
444b675f22 Merge pull request 'chore(deps): update dependency ts-jest to v29.2.2' (#111) from renovate/ts-jest-29.x-lockfile into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #111
2024-07-11 01:56:08 +05:30
Renovate Bot
81d00312ba chore(deps): update dependency ts-jest to v29.2.2
Some checks failed
renovate/artifacts Artifact file update failure
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-07-10 18:35:09 +00:00
67dc419eff Merge pull request 'fix(deps): update rust crate rust-embed to v8.5.0' (#110) from renovate/rust-embed-8.x-lockfile into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #110
2024-07-09 14:04:19 +05:30
Renovate Bot
b31177df45 fix(deps): update rust crate rust-embed to v8.5.0
All checks were successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-07-09 06:34:14 +00:00
Renovate Bot
a7b911abde chore(deps): update typescript-eslint monorepo to v7.16.0
Some checks failed
renovate/artifacts Artifact file update failure
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-07-08 19:33:57 +00:00
b9e1e6a6df Merge pull request 'chore(deps): update dependency ts-jest to v29.2.0' (#108) from renovate/ts-jest-29.x-lockfile into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #108
2024-07-08 23:58:24 +05:30
Renovate Bot
71c1e6969a chore(deps): update dependency ts-jest to v29.2.0
Some checks failed
renovate/artifacts Artifact file update failure
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-07-08 17:04:32 +00:00
b4143619b1 Merge pull request 'fix(deps): update rust crate async-trait to v0.1.81' (#107) from renovate/async-trait-0.x-lockfile into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #107
2024-07-08 18:53:31 +05:30
180754ca72 Merge pull request 'fix(deps): update rust crate serde to v1.0.204' (#106) from renovate/serde-monorepo into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #106
2024-07-08 18:53:27 +05:30
233a779e23 Merge pull request 'chore(deps): update dependency @types/node to v20.14.10' (#105) from renovate/node-20.x-lockfile into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #105
2024-07-08 18:53:23 +05:30
Renovate Bot
94e165c194 fix(deps): update rust crate async-trait to v0.1.81
All checks were successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-07-07 20:34:49 +00:00
Renovate Bot
f329f75cdd fix(deps): update rust crate serde to v1.0.204
All checks were successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-07-06 21:07:04 +00:00
Renovate Bot
b669887498 chore(deps): update dependency @types/node to v20.14.10
Some checks failed
renovate/artifacts Artifact file update failure
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-07-05 21:33:30 +00:00
5b03f41e06 Merge pull request 'chore(deps): update typescript-eslint monorepo to v7.15.0' (#103) from renovate/typescript-eslint-monorepo into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #103
2024-07-02 11:36:58 +05:30
b75e9143eb Merge pull request 'chore(deps): update dependency typescript to v5.5.3' (#102) from renovate/typescript-5.x-lockfile into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #102
2024-07-02 11:36:53 +05:30
a2766c4c57 Merge pull request 'chore(deps): update rust crate serde_json to v1.0.120' (#101) from renovate/serde_json-1.x-lockfile into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #101
2024-07-02 11:36:19 +05:30
Renovate Bot
bccf22ac63 chore(deps): update typescript-eslint monorepo to v7.15.0
Some checks failed
renovate/artifacts Artifact file update failure
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-07-01 21:04:45 +00:00
Renovate Bot
fd22df83ba chore(deps): update dependency typescript to v5.5.3
Some checks failed
renovate/artifacts Artifact file update failure
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-07-01 21:04:24 +00:00
Renovate Bot
77731be1c7 chore(deps): update rust crate serde_json to v1.0.120
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-07-01 17:38:03 +00:00
0d4034d286 Merge pull request 'chore(deps): update rust crate serde_json to v1.0.119' (#100) from renovate/serde_json-1.x-lockfile into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #100
2024-07-01 03:55:08 +05:30
Renovate Bot
2dfc7fddd1 chore(deps): update rust crate serde_json to v1.0.119
All checks were successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-06-30 18:36:25 +00:00
1e120ff30e Merge pull request 'chore(deps): update dependency eslint to v9.6.0' (#98) from renovate/eslint-monorepo into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #98
2024-06-30 22:11:26 +05:30
a370faa3f7 Merge pull request 'fix(deps): update rust crate mime_guess to v2.0.5' (#99) from renovate/mime_guess-2.x-lockfile into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #99
2024-06-30 22:08:37 +05:30
7987576d43 Merge pull request 'fix(deps): update rust crate log to v0.4.22' (#97) from renovate/log-0.x-lockfile into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #97
2024-06-30 22:08:29 +05:30
Renovate Bot
0e5cedbe31 fix(deps): update rust crate mime_guess to v2.0.5
All checks were successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-06-29 08:04:34 +00:00
Renovate Bot
8b1ce6c2a7 chore(deps): update dependency eslint to v9.6.0
Some checks failed
renovate/artifacts Artifact file update failure
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-06-29 05:40:09 +00:00
Renovate Bot
775aa130f2 fix(deps): update rust crate log to v0.4.22
All checks were successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-06-28 00:34:41 +00:00
7fbd6f3dc4 Merge pull request 'chore(deps): update dependency @types/node to v20.14.9' (#96) from renovate/node-20.x-lockfile into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #96
2024-06-26 19:37:02 +05:30
Renovate Bot
87088e5352 chore(deps): update dependency @types/node to v20.14.9
Some checks failed
renovate/artifacts Artifact file update failure
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-06-26 00:34:00 +00:00
354be7219d Merge pull request 'chore(deps): update dependency webpack to v5.92.1' (#90) from renovate/webpack-5.x-lockfile into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #90
2024-06-26 00:37:04 +05:30
a8fec032c3 Merge pull request 'fix(deps): update rust crate lazy_static to v1.5.0' (#95) from renovate/lazy_static-1.x-lockfile into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #95
2024-06-26 00:35:47 +05:30
2d17a4e9af Merge pull request 'fix(deps): update rust crate actix-web to v4.8.0' (#94) from renovate/actix-web-4.x-lockfile into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #94
2024-06-26 00:35:44 +05:30
bfaf8dcbd5 Merge pull request 'chore(deps): update dependency typescript to v5.5.2' (#93) from renovate/typescript-5.x-lockfile into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #93
2024-06-26 00:35:39 +05:30
899deadd7b Merge pull request 'chore(deps): update rust crate serde_json to v1.0.118' (#92) from renovate/serde_json-1.x-lockfile into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #92
2024-06-26 00:35:35 +05:30
59027f4e52 Merge pull request 'chore(deps): update dependency ts-jest to v29.1.5' (#87) from renovate/ts-jest-29.x-lockfile into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #87
2024-06-26 00:35:29 +05:30
Renovate Bot
9e3da7f535 fix(deps): update rust crate lazy_static to v1.5.0
All checks were successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-06-25 06:37:02 +00:00
Renovate Bot
9630b0e960 fix(deps): update rust crate actix-web to v4.8.0
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-06-25 06:36:56 +00:00
Renovate Bot
873ce697e9 chore(deps): update dependency typescript to v5.5.2
Some checks failed
renovate/artifacts Artifact file update failure
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-06-25 06:36:40 +00:00
Renovate Bot
8d154dddbf chore(deps): update rust crate serde_json to v1.0.118
All checks were successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-06-25 06:36:26 +00:00
Renovate Bot
42fb307332 chore(deps): update dependency webpack to v5.92.1
Some checks failed
renovate/artifacts Artifact file update failure
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-06-25 06:36:16 +00:00
Renovate Bot
7f04ea8392 chore(deps): update dependency ts-jest to v29.1.5
Some checks failed
renovate/artifacts Artifact file update failure
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-06-25 06:36:07 +00:00
884012970d Merge pull request 'fix(deps): update rust crate actix-http to v3.8.0' (#91) from renovate/actix-http-3.x-lockfile into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #91
2024-06-25 11:49:39 +05:30
48572b0a0e Merge pull request 'fix(deps): update rust crate url to v2.5.2' (#89) from renovate/url-2.x-lockfile into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #89
2024-06-25 11:49:31 +05:30
d8848e50d7 Merge pull request 'chore(deps): update typescript-eslint monorepo to v7.14.1' (#88) from renovate/typescript-eslint-monorepo into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #88
2024-06-25 11:49:27 +05:30
ce9fb50738 Merge pull request 'chore(deps): update dependency @types/node to v20.14.8' (#86) from renovate/node-20.x-lockfile into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #86
2024-06-25 11:49:18 +05:30
Renovate Bot
8580984e50 chore(deps): update typescript-eslint monorepo to v7.14.1
Some checks failed
renovate/artifacts Artifact file update failure
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-06-24 18:35:04 +00:00
Renovate Bot
969be4993b chore(deps): update dependency @types/node to v20.14.8
Some checks failed
renovate/artifacts Artifact file update failure
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-06-22 08:05:32 +00:00
Renovate Bot
000be3e63b fix(deps): update rust crate actix-http to v3.8.0
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-06-19 23:35:35 +00:00
Renovate Bot
058dda3d38 fix(deps): update rust crate url to v2.5.2
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-06-18 20:36:02 +00:00
8b492cb55a Merge pull request 'chore(deps): update dependency eslint to v9.5.0' (#84) from renovate/eslint-monorepo into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #84
2024-06-15 21:08:41 +05:30
55a250fd95 Merge pull request 'fix(deps): update rust crate derive_more to v0.99.18' (#85) from renovate/derive_more-0.x-lockfile into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #85
2024-06-15 21:08:35 +05:30
Renovate Bot
bfcf224172 fix(deps): update rust crate derive_more to v0.99.18
All checks were successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-06-15 12:33:19 +00:00
Renovate Bot
09ae40ec5d chore(deps): update dependency eslint to v9.5.0
Some checks failed
renovate/artifacts Artifact file update failure
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-06-14 21:32:59 +00:00
6728e9c8c4 Merge pull request 'chore(deps): update dependency webpack to v5.92.0' (#83) from renovate/webpack-5.x-lockfile into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #83
2024-06-12 03:06:31 +05:30
Renovate Bot
a7e86d10a7 chore(deps): update dependency webpack to v5.92.0
Some checks failed
renovate/artifacts Artifact file update failure
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-06-11 17:03:40 +00:00
1077812e63 Merge pull request 'chore(deps): update typescript-eslint monorepo to v7.13.0' (#82) from renovate/typescript-eslint-monorepo into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #82
2024-06-11 11:53:36 +05:30
Renovate Bot
18e148f354 chore(deps): update typescript-eslint monorepo to v7.13.0
Some checks failed
renovate/artifacts Artifact file update failure
ci/woodpecker/pr/woodpecker Pipeline failed
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-06-10 19:33:00 +00:00
324a1179bb Merge pull request 'fix(deps): update rust crate url to v2.5.1' (#81) from renovate/url-2.x-lockfile into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #81
2024-06-10 19:04:24 +05:30
Renovate Bot
16b049b0f6 fix(deps): update rust crate url to v2.5.1
All checks were successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-06-10 13:05:32 +00:00
ca76bf9caf Merge pull request 'fix(deps): update rust crate actix-files to v0.6.6' (#80) from renovate/actix-files-0.x-lockfile into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #80
2024-06-10 01:20:55 +05:30
e8e9fb6392 Merge pull request 'fix(deps): update rust crate actix-rt to v2.10.0' (#79) from renovate/actix-rt-2.x-lockfile into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #79
2024-06-10 01:07:46 +05:30
Renovate Bot
775aff77a4 fix(deps): update rust crate actix-files to v0.6.6
All checks were successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-06-09 19:35:27 +00:00
Renovate Bot
27054b9025 fix(deps): update rust crate actix-rt to v2.10.0
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-06-09 17:34:49 +00:00
0fbf91200e Merge pull request 'fix(deps): update rust crate actix-web to v4.7.0' (#78) from renovate/actix-web-4.x-lockfile into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #78
2024-06-09 12:07:46 +05:30
Renovate Bot
ecdfcf110d fix(deps): update rust crate actix-web to v4.7.0
All checks were successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-06-09 00:06:28 +00:00
bbba3f8d97 Merge pull request 'chore(deps): update typescript-eslint monorepo to v7 (major)' (#76) from renovate/major-typescript-eslint-monorepo into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #76
2024-06-08 22:38:52 +05:30
Renovate Bot
f76073dacf chore(deps): update typescript-eslint monorepo to v7
Some checks failed
renovate/artifacts Artifact file update failure
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-06-08 16:24:30 +00:00
2b85036aa6 Merge pull request 'chore(deps): update jest monorepo to v29 (major)' (#73) from renovate/major-jest-monorepo into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #73
2024-06-08 21:44:10 +05:30
Renovate Bot
c1878ed382 chore(deps): update jest monorepo to v29
All checks were successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-06-08 15:21:34 +00:00
3115eeedee Merge pull request 'chore(deps): update node.js to v20' (#74) from renovate/node-20.x into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #74
2024-06-08 20:36:51 +05:30
c811e77bd7 Merge pull request 'chore(deps): update dependency jsdom to v24' (#67) from renovate/jsdom-24.x into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #67
2024-06-08 20:36:41 +05:30
9524a9fd15 Merge pull request 'chore(deps): update typescript-eslint monorepo to v5.62.0' (#44) from renovate/typescript-eslint-monorepo into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #44
2024-06-08 20:36:36 +05:30
Renovate Bot
05f27518d4 chore(deps): update node.js to v20
Some checks failed
renovate/artifacts Artifact file update failure
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-06-08 13:05:35 +00:00
Renovate Bot
3e7de1d759 chore(deps): update dependency jsdom to v24
Some checks failed
renovate/artifacts Artifact file update failure
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-06-08 13:05:09 +00:00
Renovate Bot
e12a802619 chore(deps): update typescript-eslint monorepo to v5.62.0
Some checks failed
renovate/artifacts Artifact file update failure
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-06-08 13:04:50 +00:00
a19795a340 Merge pull request 'chore(deps): update dependency webpack-dev-server to v5' (#71) from renovate/webpack-dev-server-5.x into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #71
2024-06-08 18:34:13 +05:30
64554b057c Merge pull request 'chore(deps): update dependency @types/sinon to v17' (#65) from renovate/sinon-17.x into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #65
2024-06-08 18:34:04 +05:30
a83cc9b05e Merge pull request 'chore(deps): update dependency webpack to v5.91.0' (#41) from renovate/webpack-5.x-lockfile into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #41
2024-06-08 18:33:55 +05:30
3678fca26a Merge pull request 'fix(deps): update rust crate rust-embed to v8' (#77) from renovate/rust-embed-8.x into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #77
2024-06-08 16:10:52 +05:30
Renovate Bot
e2df341f19 chore(deps): update dependency webpack-dev-server to v5
Some checks failed
renovate/artifacts Artifact file update failure
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-06-08 10:04:48 +00:00
Renovate Bot
49afa8c94b chore(deps): update dependency webpack to v5.91.0
Some checks failed
renovate/artifacts Artifact file update failure
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-06-08 10:04:13 +00:00
98220fcbc8 Merge pull request 'chore(deps): update dependency sinon to v18' (#68) from renovate/sinon-18.x into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #68
2024-06-08 15:15:03 +05:30
89e2f00382 Merge pull request 'chore(deps): update dependency eslint to v9' (#66) from renovate/major-eslint-monorepo into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #66
2024-06-08 15:14:57 +05:30
518a5d58cb Merge pull request 'fix(deps): update rust crate validator to 0.18' (#60) from renovate/validator-0.x into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #60
2024-06-08 14:36:07 +05:30
Renovate Bot
e0b777bc04 chore(deps): update dependency @types/sinon to v17
Some checks failed
renovate/artifacts Artifact file update failure
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-06-08 09:05:59 +00:00
b2a06a4883 Merge pull request 'fix(deps): update rust crate tokio to v1.38.0' (#58) from renovate/tokio-1.x-lockfile into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #58
2024-06-08 14:35:38 +05:30
cd81262f69 Merge pull request 'fix(deps): update rust crate reqwest to 0.12.0' (#55) from renovate/reqwest-0.x into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #55
2024-06-08 14:35:32 +05:30
316cc0589a Merge pull request 'fix(deps): update rust crate csv-async to v1.3.0' (#53) from renovate/csv-async-1.x-lockfile into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #53
2024-06-08 14:35:25 +05:30
3b3dc7b346 Merge pull request 'chore(deps): update dependency webpack-dev-server to v4.15.2' (#42) from renovate/webpack-dev-server-4.x-lockfile into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #42
2024-06-08 14:09:02 +05:30
Renovate Bot
cad1334fe4 fix(deps): update rust crate rust-embed to v8
All checks were successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-06-08 07:38:17 +00:00
Renovate Bot
416fff2227 chore(deps): update dependency sinon to v18
Some checks failed
renovate/artifacts Artifact file update failure
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-06-08 07:37:39 +00:00
Renovate Bot
4b1e58456d chore(deps): update dependency eslint to v9
Some checks failed
renovate/artifacts Artifact file update failure
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-06-08 07:37:26 +00:00
Renovate Bot
d937fe257f fix(deps): update rust crate validator to 0.18
All checks were successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-06-08 07:37:10 +00:00
Renovate Bot
b74b069727 fix(deps): update rust crate tokio to v1.38.0
All checks were successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-06-08 07:37:07 +00:00
Renovate Bot
ba89f7f378 fix(deps): update rust crate reqwest to 0.12.0
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-06-08 07:36:55 +00:00
Renovate Bot
3dec37e8b8 fix(deps): update rust crate csv-async to v1.3.0
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-06-08 07:36:52 +00:00
Renovate Bot
8da9c17714 chore(deps): update dependency webpack-dev-server to v4.15.2
Some checks failed
renovate/artifacts Artifact file update failure
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-06-08 07:36:26 +00:00
648424fdf3 Merge pull request 'chore(deps): update postgres docker tag to v16' (#75) from renovate/postgres-16.x into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #75
2024-06-08 13:04:39 +05:30
c066d42272 Merge pull request 'chore(deps): update jamesives/github-pages-deploy-action action to v4' (#72) from renovate/jamesives-github-pages-deploy-action-4.x into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #72
2024-06-08 13:04:13 +05:30
bb9e8bae33 Merge pull request 'chore(deps): update dependency webpack-cli to v5' (#70) from renovate/webpack-cli-5.x into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #70
2024-06-08 13:04:06 +05:30
acd1dddcf4 Merge pull request 'chore(deps): update dependency typescript to v5' (#69) from renovate/typescript-5.x into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #69
2024-06-08 13:04:01 +05:30
8e129c64d9 Merge pull request 'chore(deps): update dependency @types/jsdom to v21' (#64) from renovate/jsdom-21.x into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #64
2024-06-08 13:03:45 +05:30
37fc8897af Merge pull request 'fix(deps): update rust crate url to v2.5.0' (#59) from renovate/url-2.x-lockfile into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #59
2024-06-08 13:03:38 +05:30
858fae15f6 Merge pull request 'fix(deps): update rust crate rust-embed to v6.8.1' (#56) from renovate/rust-embed-6.x-lockfile into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #56
2024-06-08 13:01:49 +05:30
8c3fe53071 Merge pull request 'fix(deps): update rust crate derive_builder to 0.20' (#54) from renovate/derive_builder-0.x into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #54
2024-06-08 13:01:39 +05:30
bacacdd192 Merge pull request 'fix(deps): update rust crate config to 0.14' (#52) from renovate/config-0.x into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #52
2024-06-08 13:01:28 +05:30
1d7c8640de Merge pull request 'fix(deps): update rust crate actix-web to v4.6.0' (#51) from renovate/actix-web-4.x-lockfile into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #51
2024-06-08 13:01:21 +05:30
a561059cce Merge pull request 'fix(deps): update rust crate actix-http to v3.7.0' (#46) from renovate/actix-http-3.x-lockfile into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #46
2024-06-08 13:01:16 +05:30
0e08bb1b77 Merge pull request 'chore(deps): update dependency ts-loader to v9.5.1' (#40) from renovate/ts-loader-9.x-lockfile into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #40
2024-06-08 13:00:07 +05:30
Renovate Bot
eb98fea3b0 chore(deps): update postgres docker tag to v16
All checks were successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-06-07 22:05:19 +00:00
290f6c5cc1 Merge pull request 'fix(deps): update rust crate actix-rt to v2.9.0' (#49) from renovate/actix-rt-2.x-lockfile into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #49
2024-06-08 03:28:12 +05:30
bbf64ba1fb Merge pull request 'chore(deps): update postgres docker tag to v13.15' (#43) from renovate/postgres-13.x into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #43
2024-06-08 03:18:25 +05:30
Renovate Bot
6e6b814b86 fix(deps): update rust crate actix-web to v4.6.0
Some checks failed
ci/woodpecker/pr/woodpecker Pipeline failed
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-06-07 21:34:32 +00:00
Renovate Bot
171718b788 fix(deps): update rust crate actix-http to v3.7.0
Some checks failed
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pr/woodpecker Pipeline failed
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-06-07 21:34:24 +00:00
Renovate Bot
f30463b0ac chore(deps): update dependency ts-loader to v9.5.1
Some checks failed
ci/woodpecker/pr/woodpecker Pipeline failed
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-06-07 21:33:28 +00:00
6e68747978 Merge pull request 'chore(deps): update rust crate sqlx to v0.7.4' (#47) from renovate/sqlx-0.x-lockfile into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #47
2024-06-08 02:58:02 +05:30
ab2915ece1 Merge pull request 'chore(deps): update dependency @wasm-tool/wasm-pack-plugin to v1.7.0' (#38) from renovate/wasm-tool-wasm-pack-plugin-1.x-lockfile into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #38
2024-06-08 02:57:57 +05:30
Renovate Bot
f00aba852c chore(deps): update jamesives/github-pages-deploy-action action to v4
Some checks failed
ci/woodpecker/pr/woodpecker Pipeline failed
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-06-07 19:58:08 +00:00
Renovate Bot
38b73dac8c chore(deps): update dependency webpack-cli to v5
Some checks failed
ci/woodpecker/pr/woodpecker Pipeline failed
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-06-07 19:57:48 +00:00
Renovate Bot
4f53b67d9b chore(deps): update dependency typescript to v5
Some checks failed
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pr/woodpecker Pipeline failed
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-06-07 19:57:40 +00:00
Renovate Bot
9e7b1740f4 chore(deps): update dependency @types/jsdom to v21
Some checks failed
ci/woodpecker/pr/woodpecker Pipeline failed
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-06-07 19:56:56 +00:00
Renovate Bot
06a5669157 fix(deps): update rust crate url to v2.5.0
Some checks failed
ci/woodpecker/pr/woodpecker Pipeline failed
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-06-07 19:56:37 +00:00
Renovate Bot
dcd6e5619b fix(deps): update rust crate rust-embed to v6.8.1
Some checks failed
ci/woodpecker/pr/woodpecker Pipeline failed
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-06-07 19:56:10 +00:00
Renovate Bot
0737797c26 fix(deps): update rust crate derive_builder to 0.20
Some checks failed
renovate/artifacts Artifact file update failure
ci/woodpecker/pr/woodpecker Pipeline failed
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-06-07 19:55:59 +00:00
Renovate Bot
5630b2e41c fix(deps): update rust crate config to 0.14
Some checks failed
ci/woodpecker/pr/woodpecker Pipeline failed
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-06-07 19:55:47 +00:00
Renovate Bot
18d59fc61b fix(deps): update rust crate actix-rt to v2.9.0
Some checks failed
ci/woodpecker/pr/woodpecker Pipeline failed
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-06-07 19:55:33 +00:00
Renovate Bot
da0ce2c61b chore(deps): update postgres docker tag to v13.15
Some checks failed
ci/woodpecker/pr/woodpecker Pipeline failed
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-06-07 19:55:09 +00:00
Renovate Bot
c421692595 chore(deps): update dependency @wasm-tool/wasm-pack-plugin to v1.7.0
All checks were successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-06-07 19:54:35 +00:00
Renovate Bot
d54c238529 chore(deps): update rust crate sqlx to v0.7.4
All checks were successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-06-07 19:54:23 +00:00
dade31ba60 Merge pull request 'fix(deps): update rust crate urlencoding to v2.1.3' (#37) from renovate/urlencoding-2.x-lockfile into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #37
2024-06-08 01:15:11 +05:30
af79e82881 Merge pull request 'chore(deps): update dependency eslint to v8.57.0' (#39) from renovate/eslint-monorepo into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #39
2024-06-08 01:15:02 +05:30
3a619a681d Merge pull request 'chore(deps): update rust crate serde_json to v1.0.117' (#35) from renovate/serde_json-1.x-lockfile into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #35
2024-06-08 00:38:05 +05:30
Renovate Bot
48186185c5 chore(deps): update dependency eslint to v8.57.0
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-06-07 17:07:18 +00:00
Renovate Bot
0efb1b7555 fix(deps): update rust crate urlencoding to v2.1.3
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-06-07 17:06:52 +00:00
Renovate Bot
d15589d118 chore(deps): update rust crate serde_json to v1.0.117
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-06-07 17:06:44 +00:00
88136c8ab5 Merge pull request 'chore(deps): update dependency @types/node to v16.18.98' (#24) from renovate/node-16.x-lockfile into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #24
2024-06-07 22:23:44 +05:30
2685fdbe0e Merge pull request 'chore(deps): update dependency @types/sinon to v10.0.20' (#25) from renovate/sinon-10.x-lockfile into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #25
2024-06-07 22:23:39 +05:30
9192b32904 Merge pull request 'chore(deps): update dependency ts-node to v10.9.2' (#26) from renovate/ts-node-10.x-lockfile into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #26
2024-06-07 22:23:35 +05:30
ed190a9f1a Merge pull request 'chore(deps): update dependency typescript to v4.9.5' (#27) from renovate/typescript-4.x-lockfile into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #27
2024-06-07 22:23:31 +05:30
d44e982acd Merge pull request 'chore(deps): update rust crate mime to v0.3.17' (#28) from renovate/mime-0.x-lockfile into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #28
2024-06-07 22:23:28 +05:30
9d212797d5 Merge pull request 'fix(deps): update rust crate actix-files to v0.6.5' (#29) from renovate/actix-files-0.x-lockfile into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #29
2024-06-07 22:23:24 +05:30
d2651f0800 Merge pull request 'fix(deps): update rust crate async-trait to v0.1.80' (#30) from renovate/async-trait-0.x-lockfile into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #30
2024-06-07 22:23:21 +05:30
5cb3bcdca5 Merge pull request 'fix(deps): update rust crate futures to v0.3.30' (#31) from renovate/rust-futures-monorepo into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #31
2024-06-07 22:23:17 +05:30
21e89209a1 Merge pull request 'fix(deps): update rust crate log to v0.4.21' (#32) from renovate/log-0.x-lockfile into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #32
2024-06-07 22:23:13 +05:30
39011330f3 Merge pull request 'fix(deps): update rust crate tracing to v0.1.40' (#33) from renovate/tokio-tracing-monorepo into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #33
2024-06-07 22:22:55 +05:30
Renovate Bot
d94d6d7717 fix(deps): update rust crate tracing to v0.1.40
All checks were successful
ci/woodpecker/manual/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-06-04 08:08:40 +00:00
Renovate Bot
84a8a4331c fix(deps): update rust crate log to v0.4.21
All checks were successful
ci/woodpecker/manual/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-06-04 08:08:33 +00:00
Renovate Bot
aad5797299 fix(deps): update rust crate futures to v0.3.30
All checks were successful
ci/woodpecker/manual/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-06-04 08:08:28 +00:00
Renovate Bot
bcc489c577 fix(deps): update rust crate async-trait to v0.1.80
All checks were successful
ci/woodpecker/manual/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-06-04 08:08:24 +00:00
Renovate Bot
79cdf68b8f fix(deps): update rust crate actix-files to v0.6.5
All checks were successful
ci/woodpecker/manual/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-06-04 08:08:21 +00:00
Renovate Bot
07910c1190 chore(deps): update rust crate mime to v0.3.17
All checks were successful
ci/woodpecker/manual/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-06-04 08:08:07 +00:00
Renovate Bot
86b044703c chore(deps): update dependency typescript to v4.9.5
All checks were successful
ci/woodpecker/manual/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-06-04 08:07:54 +00:00
Renovate Bot
253aaf4542 chore(deps): update dependency ts-node to v10.9.2
All checks were successful
ci/woodpecker/manual/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-06-04 08:07:47 +00:00
Renovate Bot
34a203ec49 chore(deps): update dependency @types/sinon to v10.0.20
All checks were successful
ci/woodpecker/manual/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-06-04 08:07:40 +00:00
Renovate Bot
f46d680405 chore(deps): update dependency @types/node to v16.18.98
All checks were successful
ci/woodpecker/manual/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
2024-06-04 08:07:33 +00:00
5ffbed57e0 Merge pull request 'chore: Configure Renovate' (#23) from renovate/configure into master
Reviewed-on: #23
2024-06-04 13:07:59 +05:30
Renovate Bot
711cdd64d2 Add renovate.json 2024-06-04 07:36:41 +00:00
ab2f2c0a90 Merge pull request 'fix: install libssk-dev to compile openssl' (#22) from fix-docker into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #22
2023-11-05 02:04:40 +05:30
ba379f1999
fix: use bookworm
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pr/woodpecker Pipeline was successful
2023-11-05 00:07:53 +05:30
0ba21e184d
fix: install libssk-dev to compile openssl
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
ci/woodpecker/pr/woodpecker Pipeline failed
2023-11-02 17:06:44 +05:30
abf4ded284 Merge pull request 'fix: use individual database for each test' (#21) from fix-flaky-tests into master
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
Reviewed-on: #21
2023-11-02 04:29:40 +05:30
cfc459dde1
fix: use individual database for each test
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
ci/woodpecker/pr/woodpecker Pipeline failed
2023-11-02 04:24:49 +05:30
ae1bc888f3 Merge pull request 'feat: API to retrieve percentile for benches' (#20) from feat-percentile into master
Some checks failed
ci/woodpecker/push/woodpecker Pipeline was canceled
Reviewed-on: #20
2023-11-02 03:15:57 +05:30
3ba7b591f5
feat: API to retrieve percentile for benches
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
ci/woodpecker/pr/woodpecker Pipeline failed
2023-11-01 19:47:52 +05:30
b48cc8ffc7 Merge pull request 'feat: reuse init' (#19) from reuse into master
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
Reviewed-on: #19
2023-11-01 19:47:35 +05:30
76075099be
fix: CI: install libssl-dev
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
ci/woodpecker/pr/woodpecker Pipeline failed
2023-11-01 19:30:26 +05:30
241ccab5fc
fix: use vendored openssl
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
ci/woodpecker/pr/woodpecker Pipeline failed
2023-11-01 17:59:02 +05:30
802bf71325
feat: reuse
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
ci/woodpecker/pr/woodpecker Pipeline failed
2023-11-01 17:12:16 +05:30
2879a4da01 Merge pull request 'mcaptcha-upload' (#17) from mcaptcha-upload into master
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
Reviewed-on: #17
2023-10-20 03:18:14 +05:30
be03da096e
fix: run tests sequentially to avoid race cond
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
ci/woodpecker/pr/woodpecker Pipeline failed
2023-10-20 03:07:44 +05:30
f17e38c531
fix: dont use mod db while migrating with tests-migrate
Some checks failed
ci/woodpecker/push/woodpecker Pipeline is pending
ci/woodpecker/pr/woodpecker Pipeline failed
2023-10-20 02:57:47 +05:30
dfa83b1031
feat: offline sqlx data
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
ci/woodpecker/pr/woodpecker Pipeline failed
2023-10-20 01:49:26 +05:30
5e7d1cae65
feat: schedule download jobs on reqs from mCaptcha/mCaptcha 2023-10-20 01:42:54 +05:30
3e5dca9069
feat: clean up auth method and include hostname in scheduler ctx 2023-10-20 01:41:46 +05:30
c8ecd29e94
feat: job runner to execute download requests from mCaptcha/mCaptcha 2023-10-20 01:40:32 +05:30
c0a125d5f1
feat: add db methods to manage scheduled jobs and their states 2023-10-19 22:11:31 +05:30
6b93524027
feat: schedule and record job states. Create job states during migration 2023-10-19 11:29:59 +05:30
b5b83b955a
fix: make archive shutdown responsive
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
ci/woodpecker/pr/woodpecker Pipeline failed
2023-10-19 10:10:33 +05:30
3c445411e9
fix: update parameters to mCaptcha/mCaptcha 2023-10-19 09:55:00 +05:30
786a9afe22
feat: routes to accept analytics from mCaptcha/mCaptcha 2023-10-18 10:28:50 +05:30
cdbf6788f0
feat: HTTP client to talk to mCaptcha/mCaptcha 2023-10-18 10:28:50 +05:30
0dc74c1c05
feat: helper subroutines to spin up docker DB container in make 2023-10-18 10:28:50 +05:30
8e0e94f98b
feat: DB methods to save analytics from mCaptcha/mCaptcha 2023-10-18 10:28:48 +05:30
ca34646b0c Merge pull request 'update-sqlx' (#18) from update-sqlx into master
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Reviewed-on: #18
2023-10-17 22:48:41 +05:30
43dc36554d
fix: upgrade docker img
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pr/woodpecker Pipeline was successful
2023-10-17 22:30:22 +05:30
d4d08e9d9a
debug: disable linting 2023-10-17 22:30:21 +05:30
fb472ed6c6
chore: update deps, docker img and woodpecker ci def 2023-10-17 22:30:19 +05:30
dcfc290099
fix: sqlx offline data
Some checks failed
ci/woodpecker/push/woodpecker Pipeline was canceled
2023-03-14 20:47:51 +05:30
6620cc6857 Merge pull request 'feat: Publish links to exports page and list puiblicly list all campaigns' (#16) from publish-results into master
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
Reviewed-on: #16
2023-03-14 20:20:40 +05:30
4bfc6a180f
feat: add public navbars to home and bench pages
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
ci/woodpecker/pr/woodpecker Pipeline failed
2023-03-14 15:56:51 +05:30
b8e52ff82a
feat: add export page 2023-03-14 15:51:53 +05:30
1e33e5303a
feat: serve files from export dir 2023-03-14 15:51:46 +05:30
3d74a8ce89
feat: add public navbar 2023-03-14 15:51:28 +05:30
740b1a331e
feat: get all campaigns on an instance 2023-03-14 15:50:27 +05:30
1c1617d684
fix: sqlx offline data
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
2023-03-13 00:34:04 +05:30
6657dba05b Merge pull request 'Periodically publish results from mCaptcha/survey.' (#15) from publish-results into master
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
Reviewed-on: #15
2023-03-12 21:15:42 +05:30
a3f2c3632e
feat: publish benchmark data periodically (configurable)
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
ci/woodpecker/pr/woodpecker Pipeline failed
2023-03-12 20:11:06 +05:30
9411c2ba9f
feat: read publication dir config and serve it 2023-03-12 20:10:40 +05:30
d2c52cc62c
feat: cleanup archiver and include tests 2023-03-08 17:38:24 +05:30
604fca0a62
feat: archive campaign and benchmark data
DESCRIPTION
    FORMATS
	- Campaign configuration is stored in JSON format
	- Benchmark data is stored in CSV format

    DIRECTORY STRUCTURE
	Each campaign gets a separate directory. A campaign can have
	multiple archives. Archives are stored in directories whose names
	would be the same as the UNIX timestamp of when they were
	recorded.

	EXAMPLE
	    The example below shows three campaigns with one archive
	    each. Each archive is stored in a directory denoting the
	    moment in which the archive was generated. Each archive
	    includes campaign configuration and benchmark.

	    ```bash
		14:53 atm@lab archive → tree
		.
		├── 4e951e01-71ee-4a18-9b97-782965495ae3
		│   └── 1675329764
		│       ├── benchmark.csv
		│       └── challenge.json
		├── 9d16df08-dffc-484e-bbe2-10c00b431c7e
		│   └── 1675329764
		│       ├── benchmark.csv
		│       └── challenge.json
		└── fa9f7c24-afec-4505-adb9-8e0c3ce54d37
		    └── 1675329764
			├── benchmark.csv
			└── challenge.json

		7 directories, 6 files
		```
2023-03-08 17:36:45 +05:30
a44f6f1748
feat: add archive base_path in settings 2023-03-08 17:36:45 +05:30
ca0c847f04
feat: add NLnet funding details
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
2023-03-08 17:19:47 +05:30
9e153b22ca
fix: update sqlx and fix container build
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
closes: #14
2023-02-14 17:25:27 +05:30
4f224d782a
Merge pull request #14 from mCaptcha/js-bench
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
Collect JavaScript polyfill benchmark using mCaptcha/survey
2023-02-13 14:14:44 +05:30
127 changed files with 12747 additions and 8514 deletions

View file

@ -84,7 +84,7 @@ jobs:
- name: Deploy to GitHub Pages
if: matrix.version == 'stable' && (github.repository == 'mcapthca/survey')
uses: JamesIves/github-pages-deploy-action@3.7.1
uses: JamesIves/github-pages-deploy-action@v4.6.4
with:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
BRANCH: gh-pages

1
.gitignore vendored
View file

@ -17,3 +17,4 @@ __pycache__/
*.py[cod]
*$py.class
src/sailfish/
src/libcachebust_data.json

View file

@ -0,0 +1,22 @@
{
"db_name": "PostgreSQL",
"query": "SELECT\n synced_till\n FROM\n survey_mcaptcha_campaign\n WHERE \n campaign_id = $1;",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "synced_till",
"type_info": "Int4"
}
],
"parameters": {
"Left": [
"Text"
]
},
"nullable": [
false
]
},
"hash": "05b7fe6d93a4c988e9eae32f4a57e369f9ddc703b8fd3251c6baa52b60c98a1d"
}

View file

@ -0,0 +1,16 @@
{
"db_name": "PostgreSQL",
"query": "INSERT INTO survey_admins \n (name , password, secret) VALUES ($1, $2, $3)",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Varchar",
"Text",
"Varchar"
]
},
"nullable": []
},
"hash": "0d22134cc5076304b7895827f006ee8269cc500f400114a7472b83f0f1c568b5"
}

View file

@ -0,0 +1,26 @@
{
"db_name": "PostgreSQL",
"query": "SELECT name, id FROM survey_campaigns ORDER BY id;",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "name",
"type_info": "Varchar"
},
{
"ordinal": 1,
"name": "id",
"type_info": "Uuid"
}
],
"parameters": {
"Left": []
},
"nullable": [
false,
false
]
},
"hash": "10924f3726a45c3bc709118375d691f2867bbcd50dc47a000ac9bf3ff878c97c"
}

View file

@ -0,0 +1,28 @@
{
"db_name": "PostgreSQL",
"query": "INSERT INTO survey_responses (\n user_id,\n campaign_id,\n device_user_provided,\n device_software_recognised,\n threads,\n submitted_at,\n submission_bench_type_id\n ) VALUES (\n $1, $2, $3, $4, $5, $6,\n (SELECT ID FROM survey_bench_type WHERE name = $7)\n )\n RETURNING ID;",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "id",
"type_info": "Int4"
}
],
"parameters": {
"Left": [
"Uuid",
"Uuid",
"Varchar",
"Varchar",
"Int4",
"Timestamptz",
"Text"
]
},
"nullable": [
false
]
},
"hash": "117f1ae18f6a3936f27446b75b555951fe217d3a3cefe40a006fdd3cb31f0ac4"
}

View file

@ -0,0 +1,14 @@
{
"db_name": "PostgreSQL",
"query": "INSERT INTO survey_mcaptcha_upload_job_states \n (name) VALUES ($1) ON CONFLICT (name) DO NOTHING;",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Varchar"
]
},
"nullable": []
},
"hash": "11ff04344412d1a2e5fdb1ab654fe4e90c2ba897bb4889426031ffacc2ae06e4"
}

View file

@ -0,0 +1,22 @@
{
"db_name": "PostgreSQL",
"query": "SELECT password FROM survey_admins WHERE name = ($1)",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "password",
"type_info": "Text"
}
],
"parameters": {
"Left": [
"Text"
]
},
"nullable": [
false
]
},
"hash": "1373df097fa0e58b23a374753318ae53a44559aa0e7eb64680185baf1c481723"
}

View file

@ -0,0 +1,22 @@
{
"db_name": "PostgreSQL",
"query": "SELECT\n survey_admins.name\n FROM\n survey_admins\n INNER JOIN survey_campaigns ON\n survey_admins.ID = survey_campaigns.user_id\n WHERE\n survey_campaigns.ID = $1\n ",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "name",
"type_info": "Varchar"
}
],
"parameters": {
"Left": [
"Uuid"
]
},
"nullable": [
false
]
},
"hash": "15a8484de6f035e56c34ce3f6979eadea81f125933f76261c8b3c8319d43bbe0"
}

View file

@ -0,0 +1,15 @@
{
"db_name": "PostgreSQL",
"query": "UPDATE\n survey_mcaptcha_campaign\n SET\n synced_till = $1\n WHERE \n campaign_id = $2; ",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Int4",
"Text"
]
},
"nullable": []
},
"hash": "163a1ab861234bbf52b1b1c03bbac0d37bbbb539146f93c6fba24ffd80ad1485"
}

View file

@ -0,0 +1,16 @@
{
"db_name": "PostgreSQL",
"query": "\n UPDATE\n survey_mcaptcha_upload_jobs\n SET\n job_state = (SELECT ID FROM survey_mcaptcha_upload_job_states WHERE name = $1),\n scheduled_at = $2\n WHERE public_id = $3;",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Text",
"Timestamptz",
"Text"
]
},
"nullable": []
},
"hash": "18495d6198079fdb8e4806d8a59aa0a1abee44a8b568ce74fa275ab936e8362f"
}

View file

@ -0,0 +1,28 @@
{
"db_name": "PostgreSQL",
"query": "SELECT name, password FROM survey_admins WHERE email = ($1)",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "name",
"type_info": "Varchar"
},
{
"ordinal": 1,
"name": "password",
"type_info": "Text"
}
],
"parameters": {
"Left": [
"Text"
]
},
"nullable": [
false,
false
]
},
"hash": "19686bfe8772cbc6831d46d18994e2b9aa40c7181eae9a31e51451cce95f04e8"
}

View file

@ -0,0 +1,15 @@
{
"db_name": "PostgreSQL",
"query": "DELETE \n FROM survey_campaigns \n WHERE \n user_id = (\n SELECT \n ID \n FROM \n survey_admins \n WHERE \n name = $1\n )\n AND\n id = ($2)",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Text",
"Uuid"
]
},
"nullable": []
},
"hash": "1972be28a6bda2c3a3764a836e95c8cb0c5db277fc4c8a9b19951a03166c6492"
}

View file

@ -0,0 +1,17 @@
{
"db_name": "PostgreSQL",
"query": "insert into survey_admins \n (name , password, email, secret) values ($1, $2, $3, $4)",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Varchar",
"Text",
"Varchar",
"Varchar"
]
},
"nullable": []
},
"hash": "1b7e17bfc949fa97e8dec1f95e35a02bcf3aa1aa72a1f6f6c8884e885fc3b953"
}

View file

@ -0,0 +1,64 @@
{
"db_name": "PostgreSQL",
"query": "\n SELECT\n survey_mcaptcha_upload_jobs.ID,\n survey_mcaptcha_upload_jobs.public_id,\n survey_mcaptcha_campaign.campaign_id,\n survey_mcaptcha_campaign.public_id as campaign_public_id,\n survey_mcaptcha_upload_job_states.name,\n survey_mcaptcha_upload_jobs.created_at,\n survey_mcaptcha_upload_jobs.scheduled_at,\n survey_mcaptcha_upload_jobs.finished_at\n\n FROM survey_mcaptcha_upload_jobs\n INNER JOIN\n survey_mcaptcha_upload_job_states\n ON\n survey_mcaptcha_upload_job_states.ID = survey_mcaptcha_upload_jobs.job_state\n INNER JOIN\n survey_mcaptcha_campaign\n ON\n survey_mcaptcha_campaign.ID = survey_mcaptcha_upload_jobs.campaign_id\n WHERE\n survey_mcaptcha_upload_job_states.name = $1;",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "id",
"type_info": "Int4"
},
{
"ordinal": 1,
"name": "public_id",
"type_info": "Varchar"
},
{
"ordinal": 2,
"name": "campaign_id",
"type_info": "Varchar"
},
{
"ordinal": 3,
"name": "campaign_public_id",
"type_info": "Varchar"
},
{
"ordinal": 4,
"name": "name",
"type_info": "Varchar"
},
{
"ordinal": 5,
"name": "created_at",
"type_info": "Timestamptz"
},
{
"ordinal": 6,
"name": "scheduled_at",
"type_info": "Timestamptz"
},
{
"ordinal": 7,
"name": "finished_at",
"type_info": "Timestamptz"
}
],
"parameters": {
"Left": [
"Text"
]
},
"nullable": [
false,
false,
false,
false,
false,
false,
true,
true
]
},
"hash": "1e41c42d89762ff4dc4b60a534a54db2741b325727c01852cbc68ea8442d15ef"
}

View file

@ -0,0 +1,23 @@
{
"db_name": "PostgreSQL",
"query": "SELECT\n public_id\n FROM\n survey_mcaptcha_campaign\n WHERE\n campaign_id = $1\n AND\n url_id = (SELECT ID FROM survey_mcaptcha_hostname WHERE secret = $2);",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "public_id",
"type_info": "Varchar"
}
],
"parameters": {
"Left": [
"Text",
"Text"
]
},
"nullable": [
false
]
},
"hash": "2904486838bed381aa00f6a1b1e9b860a74b07b15256f3764434901471ff820b"
}

View file

@ -0,0 +1,14 @@
{
"db_name": "PostgreSQL",
"query": "DELETE FROM survey_admins WHERE name = ($1)",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Text"
]
},
"nullable": []
},
"hash": "2ccaecfee4d2f29ef5278188b304017719720aa986d680d4727a1facbb869c7a"
}

View file

@ -0,0 +1,22 @@
{
"db_name": "PostgreSQL",
"query": "SELECT EXISTS (SELECT 1 from survey_mcaptcha_upload_job_states WHERE name = $1)",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "exists",
"type_info": "Bool"
}
],
"parameters": {
"Left": [
"Text"
]
},
"nullable": [
null
]
},
"hash": "2d18e0fad79c6df26465f82eca20cdfca35a710f34a54ac115d23435762a3038"
}

View file

@ -0,0 +1,16 @@
{
"db_name": "PostgreSQL",
"query": "INSERT INTO\n survey_mcaptcha_campaign (campaign_id, public_id, url_id)\n VALUES ($1, $2, (SELECT ID FROM survey_mcaptcha_hostname WHERE secret = $3));",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Varchar",
"Varchar",
"Text"
]
},
"nullable": []
},
"hash": "38a517b011519ec80d35d12ea463e7aed1f25290a5f3e8b19c5aa781da362ae3"
}

View file

@ -0,0 +1,15 @@
{
"db_name": "PostgreSQL",
"query": "\n INSERT INTO survey_users (created_at, id) VALUES($1, $2)",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Timestamptz",
"Uuid"
]
},
"nullable": []
},
"hash": "43b3e771f38bf8059832169227705be06a28925af1b3799ffef5371d511fd138"
}

View file

@ -0,0 +1,23 @@
{
"db_name": "PostgreSQL",
"query": "SELECT\n difficulty\n FROM\n survey_benches\n WHERE\n duration <= $1\n ORDER BY difficulty ASC LIMIT 1 OFFSET $2;",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "difficulty",
"type_info": "Int4"
}
],
"parameters": {
"Left": [
"Float4",
"Int8"
]
},
"nullable": [
false
]
},
"hash": "52c16c2c0759140af6348ef7de56b74151a20532ceebc8ee41d079decee3acb5"
}

View file

@ -0,0 +1,22 @@
{
"db_name": "PostgreSQL",
"query": "SELECT EXISTS (SELECT 1 from survey_admins WHERE name = $1)",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "exists",
"type_info": "Bool"
}
],
"parameters": {
"Left": [
"Text"
]
},
"nullable": [
null
]
},
"hash": "536541ecf2e1c0403c74b6e2e09b42b73a7741ae4a348ff539ac410022e03ace"
}

View file

@ -0,0 +1,15 @@
{
"db_name": "PostgreSQL",
"query": "UPDATE survey_admins set password = $1\n WHERE name = $2",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Text",
"Text"
]
},
"nullable": []
},
"hash": "55dde28998a6d12744806035f0a648494a403c7d09ea3caf91bf54869a81aa73"
}

View file

@ -0,0 +1,61 @@
{
"db_name": "PostgreSQL",
"query": "SELECT\n survey_responses.ID,\n survey_responses.device_software_recognised,\n survey_responses.threads,\n survey_responses.user_id,\n survey_responses.submitted_at,\n survey_responses.device_user_provided,\n survey_bench_type.name\n FROM\n survey_responses\n INNER JOIN survey_bench_type ON\n survey_responses.submission_bench_type_id = survey_bench_type.ID\n WHERE\n survey_responses.campaign_id = (\n SELECT ID FROM survey_campaigns\n WHERE\n ID = $1\n AND\n user_id = (SELECT ID FROM survey_admins WHERE name = $2)\n )\n LIMIT $3 OFFSET $4",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "id",
"type_info": "Int4"
},
{
"ordinal": 1,
"name": "device_software_recognised",
"type_info": "Varchar"
},
{
"ordinal": 2,
"name": "threads",
"type_info": "Int4"
},
{
"ordinal": 3,
"name": "user_id",
"type_info": "Uuid"
},
{
"ordinal": 4,
"name": "submitted_at",
"type_info": "Timestamptz"
},
{
"ordinal": 5,
"name": "device_user_provided",
"type_info": "Varchar"
},
{
"ordinal": 6,
"name": "name",
"type_info": "Varchar"
}
],
"parameters": {
"Left": [
"Uuid",
"Text",
"Int8",
"Int8"
]
},
"nullable": [
false,
false,
true,
false,
false,
false,
false
]
},
"hash": "57c673ad8529371d77aa305917cf680dd2273ead74c3583ef0322f472b1d33fd"
}

View file

@ -0,0 +1,23 @@
{
"db_name": "PostgreSQL",
"query": "SELECT name \n FROM survey_campaigns\n WHERE \n id = $1\n AND\n user_id = (SELECT ID from survey_admins WHERE name = $2)",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "name",
"type_info": "Varchar"
}
],
"parameters": {
"Left": [
"Uuid",
"Text"
]
},
"nullable": [
false
]
},
"hash": "58ec3b8f98c27e13ec2732f8ee23f6eb9845ac5d9fd97b1e5c9f2eed4b1f5693"
}

View file

@ -0,0 +1,22 @@
{
"db_name": "PostgreSQL",
"query": "SELECT EXISTS (SELECT 1 from survey_mcaptcha_hostname WHERE url = $1)",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "exists",
"type_info": "Bool"
}
],
"parameters": {
"Left": [
"Text"
]
},
"nullable": [
null
]
},
"hash": "5c1ad3208ece06ba7a503d650e15d06906e56018798cba2b4672c393327131aa"
}

View file

@ -0,0 +1,22 @@
{
"db_name": "PostgreSQL",
"query": "SELECT COUNT(difficulty) FROM survey_benches WHERE duration <= $1;",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "count",
"type_info": "Int8"
}
],
"parameters": {
"Left": [
"Float4"
]
},
"nullable": [
null
]
},
"hash": "63370a30a4ff6d31292a3cb632c66184ccff75583e21df5ddf5e8872f710d3d2"
}

View file

@ -0,0 +1,15 @@
{
"db_name": "PostgreSQL",
"query": "UPDATE survey_admins set email = $1\n WHERE name = $2",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Varchar",
"Text"
]
},
"nullable": []
},
"hash": "683707dbc847b37c58c29aaad0d1a978c9fe0657da13af99796e4461134b5a43"
}

View file

@ -0,0 +1,22 @@
{
"db_name": "PostgreSQL",
"query": "SELECT EXISTS (SELECT 1 from survey_admins WHERE email = $1)",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "exists",
"type_info": "Bool"
}
],
"parameters": {
"Left": [
"Text"
]
},
"nullable": [
null
]
},
"hash": "6a26daa84578aed2b2085697cb8358ed7c0a50ba9597fd387b4b09b0a8a154db"
}

View file

@ -0,0 +1,17 @@
{
"db_name": "PostgreSQL",
"query": "INSERT INTO\n survey_mcaptcha_analytics (\n campaign_id, time, difficulty_factor, worker_type\n )\n VALUES ((\n SELECT\n ID\n FROM\n survey_mcaptcha_campaign\n WHERE \n campaign_id = $1\n ), $2, $3, $4\n );",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Text",
"Int4",
"Int4",
"Varchar"
]
},
"nullable": []
},
"hash": "6c8fda20aa4a9174a5b008032d493773274ebfbf9dc204d89609cdff1ebc0335"
}

View file

@ -0,0 +1,28 @@
{
"db_name": "PostgreSQL",
"query": "SELECT \n name, id\n FROM \n survey_campaigns \n WHERE\n user_id = (\n SELECT \n ID\n FROM \n survey_admins\n WHERE\n name = $1\n )",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "name",
"type_info": "Varchar"
},
{
"ordinal": 1,
"name": "id",
"type_info": "Uuid"
}
],
"parameters": {
"Left": [
"Text"
]
},
"nullable": [
false,
false
]
},
"hash": "70cc7bfc9b6ff5b68db70c069c0947d51bfc4a53cedc020016ee25ff98586c93"
}

View file

@ -0,0 +1,42 @@
{
"db_name": "PostgreSQL",
"query": "SELECT id, time, difficulty_factor, worker_type FROM survey_mcaptcha_analytics\n WHERE \n campaign_id = (\n SELECT \n ID FROM survey_mcaptcha_campaign \n WHERE \n public_id = $1\n )\n ORDER BY ID\n OFFSET $2 LIMIT $3\n ",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "id",
"type_info": "Int4"
},
{
"ordinal": 1,
"name": "time",
"type_info": "Int4"
},
{
"ordinal": 2,
"name": "difficulty_factor",
"type_info": "Int4"
},
{
"ordinal": 3,
"name": "worker_type",
"type_info": "Varchar"
}
],
"parameters": {
"Left": [
"Text",
"Int8",
"Int8"
]
},
"nullable": [
false,
false,
false,
false
]
},
"hash": "714925a5209400a17bcafe23c34ce9546106e8bdd788c27ee579b278e671bcb0"
}

View file

@ -0,0 +1,64 @@
{
"db_name": "PostgreSQL",
"query": "\n SELECT\n survey_mcaptcha_upload_jobs.ID,\n survey_mcaptcha_upload_jobs.public_id,\n survey_mcaptcha_campaign.campaign_id,\n survey_mcaptcha_campaign.public_id as campaign_public_id,\n survey_mcaptcha_upload_job_states.name,\n survey_mcaptcha_upload_jobs.created_at,\n survey_mcaptcha_upload_jobs.scheduled_at,\n survey_mcaptcha_upload_jobs.finished_at\n\n FROM survey_mcaptcha_upload_jobs\n INNER JOIN\n survey_mcaptcha_upload_job_states\n ON\n survey_mcaptcha_upload_job_states.ID = survey_mcaptcha_upload_jobs.job_state\n INNER JOIN\n survey_mcaptcha_campaign\n ON\n survey_mcaptcha_campaign.ID = survey_mcaptcha_upload_jobs.campaign_id\n WHERE\n survey_mcaptcha_upload_jobs.public_id = $1",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "id",
"type_info": "Int4"
},
{
"ordinal": 1,
"name": "public_id",
"type_info": "Varchar"
},
{
"ordinal": 2,
"name": "campaign_id",
"type_info": "Varchar"
},
{
"ordinal": 3,
"name": "campaign_public_id",
"type_info": "Varchar"
},
{
"ordinal": 4,
"name": "name",
"type_info": "Varchar"
},
{
"ordinal": 5,
"name": "created_at",
"type_info": "Timestamptz"
},
{
"ordinal": 6,
"name": "scheduled_at",
"type_info": "Timestamptz"
},
{
"ordinal": 7,
"name": "finished_at",
"type_info": "Timestamptz"
}
],
"parameters": {
"Left": [
"Text"
]
},
"nullable": [
false,
false,
false,
false,
false,
false,
true,
true
]
},
"hash": "722f2d297a318f9804c1388d427d069a315b45c0c85c0b344d34cd8928b22c9c"
}

View file

@ -0,0 +1,62 @@
{
"db_name": "PostgreSQL",
"query": "SELECT\n survey_responses.ID,\n survey_responses.device_software_recognised,\n survey_responses.threads,\n survey_responses.user_id,\n survey_responses.submitted_at,\n survey_responses.device_user_provided,\n survey_bench_type.name\n FROM\n survey_responses\n INNER JOIN survey_bench_type ON\n survey_responses.submission_bench_type_id = survey_bench_type.ID\n WHERE\n survey_bench_type.name = $3\n AND\n survey_responses.campaign_id = (\n SELECT ID FROM survey_campaigns\n WHERE\n ID = $1\n AND\n user_id = (SELECT ID FROM survey_admins WHERE name = $2)\n )\n LIMIT $4 OFFSET $5",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "id",
"type_info": "Int4"
},
{
"ordinal": 1,
"name": "device_software_recognised",
"type_info": "Varchar"
},
{
"ordinal": 2,
"name": "threads",
"type_info": "Int4"
},
{
"ordinal": 3,
"name": "user_id",
"type_info": "Uuid"
},
{
"ordinal": 4,
"name": "submitted_at",
"type_info": "Timestamptz"
},
{
"ordinal": 5,
"name": "device_user_provided",
"type_info": "Varchar"
},
{
"ordinal": 6,
"name": "name",
"type_info": "Varchar"
}
],
"parameters": {
"Left": [
"Uuid",
"Text",
"Text",
"Int8",
"Int8"
]
},
"nullable": [
false,
false,
true,
false,
false,
false,
false
]
},
"hash": "74c41e33f91cf31ea13582c8b3ca464544374842450d580517ca2bd01d67402e"
}

View file

@ -0,0 +1,22 @@
{
"db_name": "PostgreSQL",
"query": "SELECT EXISTS (\n SELECT\n url\n FROM\n survey_mcaptcha_hostname\n WHERE secret = $1\n )",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "exists",
"type_info": "Bool"
}
],
"parameters": {
"Left": [
"Text"
]
},
"nullable": [
null
]
},
"hash": "7d764a7b1c2991dda7498f243c6e4bd83fdf431e3510f9afb0ef5e9b10f35181"
}

View file

@ -0,0 +1,18 @@
{
"db_name": "PostgreSQL",
"query": "\n INSERT INTO survey_campaigns (\n user_id, ID, name, difficulties, created_at\n ) VALUES(\n (SELECT id FROM survey_admins WHERE name = $1),\n $2, $3, $4, $5\n );",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Text",
"Uuid",
"Varchar",
"Int4Array",
"Timestamptz"
]
},
"nullable": []
},
"hash": "82feafc36533144e49ba374c8c47ca4aa0d6558a9803778ad28cfa7b62382c3e"
}

View file

@ -0,0 +1,28 @@
{
"db_name": "PostgreSQL",
"query": "SELECT\n created_at,\n ID\n FROM\n survey_users\n WHERE\n ID = $1\n ",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "created_at",
"type_info": "Timestamptz"
},
{
"ordinal": 1,
"name": "id",
"type_info": "Uuid"
}
],
"parameters": {
"Left": [
"Uuid"
]
},
"nullable": [
false,
false
]
},
"hash": "858a4c06a5c1ba7adb79bcac7d42d106d09d0cbff10c197f2242dcb5c437a1df"
}

View file

@ -0,0 +1,15 @@
{
"db_name": "PostgreSQL",
"query": "INSERT INTO survey_mcaptcha_hostname (url, secret) VALUES ($1, $2)",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Varchar",
"Varchar"
]
},
"nullable": []
},
"hash": "94205e3e65a8f6bf315a282ec8fcc64119dc08e5565925bb2a3f5fccf663b5ab"
}

View file

@ -0,0 +1,22 @@
{
"db_name": "PostgreSQL",
"query": "SELECT difficulties FROM survey_campaigns WHERE id = $1;",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "difficulties",
"type_info": "Int4Array"
}
],
"parameters": {
"Left": [
"Uuid"
]
},
"nullable": [
false
]
},
"hash": "9cdade613ce724631cc3f187510758ee0929e93ff3f8ce81fe35594756644246"
}

View file

@ -0,0 +1,23 @@
{
"db_name": "PostgreSQL",
"query": "SELECT EXISTS (\n SELECT\n ID\n FROM\n survey_mcaptcha_campaign\n WHERE\n campaign_id = $1\n AND\n url_id = (\n SELECT\n ID\n FROM\n survey_mcaptcha_hostname\n WHERE\n secret = $2\n )\n )",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "exists",
"type_info": "Bool"
}
],
"parameters": {
"Left": [
"Text",
"Text"
]
},
"nullable": [
null
]
},
"hash": "9da39f618b9dea08360d4c1625650b5055de47a7e89f99ffc589b99d22b8ac9d"
}

View file

@ -0,0 +1,15 @@
{
"db_name": "PostgreSQL",
"query": "DELETE FROM survey_mcaptcha_hostname WHERE secret = $1 AND url =$2",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Text",
"Text"
]
},
"nullable": []
},
"hash": "a3cddc0ace32cfb7df70e171b2618c7fe6d7824bbfcbae8248905e927049528b"
}

View file

@ -0,0 +1,16 @@
{
"db_name": "PostgreSQL",
"query": "INSERT INTO survey_benches \n (resp_id, difficulty, duration) \n VALUES ($1, $2, $3);",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Int4",
"Int4",
"Float4"
]
},
"nullable": []
},
"hash": "a721cfa249acf328c2f29c4cf8c2aeba1a635bcf49d18ced5474caa10b7cae4f"
}

View file

@ -0,0 +1,15 @@
{
"db_name": "PostgreSQL",
"query": "UPDATE survey_admins set secret = $1\n WHERE name = $2",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Varchar",
"Text"
]
},
"nullable": []
},
"hash": "ab951c5c318174c6538037947c2f52c61bcfe5e5be1901379b715e77f5214dd2"
}

View file

@ -0,0 +1,28 @@
{
"db_name": "PostgreSQL",
"query": "SELECT\n duration,\n difficulty\n FROM\n survey_benches\n WHERE\n resp_id = $1\n ",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "duration",
"type_info": "Float4"
},
{
"ordinal": 1,
"name": "difficulty",
"type_info": "Int4"
}
],
"parameters": {
"Left": [
"Int4"
]
},
"nullable": [
false,
false
]
},
"hash": "b2619292aa6bd1ac38dca152cbe607b795a151ddc212361a3c6d8c70ea1c93eb"
}

View file

@ -0,0 +1,15 @@
{
"db_name": "PostgreSQL",
"query": "UPDATE survey_mcaptcha_hostname set secret = $1 WHERE url = $2",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Varchar",
"Text"
]
},
"nullable": []
},
"hash": "baabef729999fe63426b3b2373f1ecbf294d4bfddbce04209269644f4a7511ed"
}

View file

@ -0,0 +1,15 @@
{
"db_name": "PostgreSQL",
"query": "UPDATE survey_admins set name = $1\n WHERE name = $2",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Varchar",
"Text"
]
},
"nullable": []
},
"hash": "c757589ef26a005e3285e7ab20d8a44c4f2e1cb125f8db061dd198cc380bf807"
}

View file

@ -0,0 +1,65 @@
{
"db_name": "PostgreSQL",
"query": "\n SELECT\n survey_mcaptcha_upload_jobs.ID,\n survey_mcaptcha_upload_jobs.public_id,\n survey_mcaptcha_campaign.campaign_id,\n survey_mcaptcha_campaign.public_id as campaign_public_id,\n survey_mcaptcha_upload_job_states.name,\n survey_mcaptcha_upload_jobs.created_at,\n survey_mcaptcha_upload_jobs.scheduled_at,\n survey_mcaptcha_upload_jobs.finished_at\n\n FROM survey_mcaptcha_upload_jobs\n INNER JOIN\n survey_mcaptcha_upload_job_states\n ON\n survey_mcaptcha_upload_job_states.ID = survey_mcaptcha_upload_jobs.job_state\n INNER JOIN\n survey_mcaptcha_campaign\n ON\n survey_mcaptcha_campaign.ID = survey_mcaptcha_upload_jobs.campaign_id\n WHERE\n survey_mcaptcha_campaign.campaign_id = $1\n AND\n survey_mcaptcha_upload_job_states.name = $2;",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "id",
"type_info": "Int4"
},
{
"ordinal": 1,
"name": "public_id",
"type_info": "Varchar"
},
{
"ordinal": 2,
"name": "campaign_id",
"type_info": "Varchar"
},
{
"ordinal": 3,
"name": "campaign_public_id",
"type_info": "Varchar"
},
{
"ordinal": 4,
"name": "name",
"type_info": "Varchar"
},
{
"ordinal": 5,
"name": "created_at",
"type_info": "Timestamptz"
},
{
"ordinal": 6,
"name": "scheduled_at",
"type_info": "Timestamptz"
},
{
"ordinal": 7,
"name": "finished_at",
"type_info": "Timestamptz"
}
],
"parameters": {
"Left": [
"Text",
"Text"
]
},
"nullable": [
false,
false,
false,
false,
false,
false,
true,
true
]
},
"hash": "ca41f4e15fa5c5657a525ed9385a92214b644194443ae165957d9659d30dc3f9"
}

View file

@ -0,0 +1,34 @@
{
"db_name": "PostgreSQL",
"query": "SELECT\n survey_mcaptcha_campaign.campaign_id,\n survey_mcaptcha_upload_jobs.public_id,\n survey_mcaptcha_hostname.url\n FROM\n survey_mcaptcha_campaign\n INNER JOIN\n survey_mcaptcha_upload_jobs\n ON\n survey_mcaptcha_upload_jobs.campaign_id = survey_mcaptcha_campaign.ID\n INNER JOIN\n survey_mcaptcha_hostname\n ON\n survey_mcaptcha_hostname.ID = survey_mcaptcha_campaign.url_id\n WHERE\n survey_mcaptcha_upload_jobs.job_state = (\n SELECT ID FROM survey_mcaptcha_upload_job_states WHERE name = $1\n )\n AND\n survey_mcaptcha_upload_jobs.finished_at is NULL\n AND\n survey_mcaptcha_upload_jobs.scheduled_at is NULL\n ORDER BY created_at ASC;",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "campaign_id",
"type_info": "Varchar"
},
{
"ordinal": 1,
"name": "public_id",
"type_info": "Varchar"
},
{
"ordinal": 2,
"name": "url",
"type_info": "Varchar"
}
],
"parameters": {
"Left": [
"Text"
]
},
"nullable": [
false,
false,
false
]
},
"hash": "d7a099c6f381fd02ad6a114b0146e4e52f7886f0164d05ccd3f1818a2a70cf67"
}

View file

@ -0,0 +1,15 @@
{
"db_name": "PostgreSQL",
"query": "DELETE FROM\n survey_mcaptcha_campaign\n WHERE\n campaign_id = $1\n AND\n url_id = (\n SELECT\n ID\n FROM\n survey_mcaptcha_hostname\n WHERE\n secret = $2\n )",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Text",
"Text"
]
},
"nullable": []
},
"hash": "dbe5d5c450a50bb829a39e6149eb4e6307547120b10762140d250f163b584a23"
}

View file

@ -0,0 +1,22 @@
{
"db_name": "PostgreSQL",
"query": "SELECT secret FROM survey_admins WHERE name = ($1)",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "secret",
"type_info": "Varchar"
}
],
"parameters": {
"Left": [
"Text"
]
},
"nullable": [
false
]
},
"hash": "e9cf5d6d8c9e8327d5c809d47a14a933f324e267f1e7dbb48e1caf1c021adc3f"
}

View file

@ -0,0 +1,17 @@
{
"db_name": "PostgreSQL",
"query": "INSERT INTO survey_mcaptcha_upload_jobs\n (campaign_id, job_state, created_at, public_id)\n VALUES (\n (SELECT ID FROM survey_mcaptcha_campaign WHERE campaign_id = $1),\n (SELECT ID FROM survey_mcaptcha_upload_job_states WHERE name = $2),\n $3, $4)",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Text",
"Text",
"Timestamptz",
"Varchar"
]
},
"nullable": []
},
"hash": "ebfc456dd76b3fb2e5484f935703ad6aa4712c782222f2015b92916827f81079"
}

View file

@ -0,0 +1,38 @@
{
"db_name": "PostgreSQL",
"query": "SELECT ID, name, difficulties, created_at FROM survey_campaigns",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "id",
"type_info": "Uuid"
},
{
"ordinal": 1,
"name": "name",
"type_info": "Varchar"
},
{
"ordinal": 2,
"name": "difficulties",
"type_info": "Int4Array"
},
{
"ordinal": 3,
"name": "created_at",
"type_info": "Timestamptz"
}
],
"parameters": {
"Left": []
},
"nullable": [
false,
false,
false,
false
]
},
"hash": "efa0e41910fa5bcb187ba9e2fc8f37bee5b25ffe9a2d175f39a69899bc559965"
}

View file

@ -0,0 +1,16 @@
{
"db_name": "PostgreSQL",
"query": "\n UPDATE\n survey_mcaptcha_upload_jobs\n SET\n job_state = (SELECT ID FROM survey_mcaptcha_upload_job_states WHERE name = $1),\n finished_at = $2\n WHERE public_id = $3;",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Text",
"Timestamptz",
"Text"
]
},
"nullable": []
},
"hash": "fade9f99846165c34486f6492ece38148bf0dd2d79e1a4f97b8cbf04015ceff0"
}

View file

@ -0,0 +1,16 @@
{
"db_name": "PostgreSQL",
"query": "INSERT INTO survey_response_tokens \n (resp_id, user_id, id)\n VALUES ($1, $2, $3);",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Int4",
"Uuid",
"Uuid"
]
},
"nullable": []
},
"hash": "fcdc5fe5d496eb516c805e64ec96d9626b74ab33cd6e75e5a08ae88967403b72"
}

View file

@ -7,15 +7,18 @@ pipeline:
- OPEN_API_DOCS=8e77345f1597e40c2e266cb4e6dee74888918a61
- COMPILED_DATE=2021-07-21
commands:
- curl -fsSL https://deb.nodesource.com/setup_16.x | bash - &&\
- apt update && apt-get -y --no-install-recommends install nodejs tar gpg curl wget
- apt-get update
- apt-get install -y ca-certificates curl gnupg tar wget libssl-dev
- mkdir -p /etc/apt/keyrings
- curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg
- NODE_MAJOR=18 echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_MAJOR.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list
- apt-get -y install nodejs npm
- npm install --global yarn
- rustup component add rustfmt
- rustup component add clippy
- make dev-env
- make migrate
- make frontend
- make lint
- make test
build_docker_img:

2657
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -8,7 +8,7 @@ documentation = "https://github.con/mCaptcha/survey"
readme = "https://github.com/mCaptcha/survey/blob/master/README.md"
license = "AGPLv3 or later version"
authors = ["realaravinth <realaravinth@batsense.net>"]
edition = "2018"
edition = "2021"
default-run = "survey"
build = "build.rs"
@ -22,34 +22,36 @@ name = "tests-migrate"
path = "./src/tests-migrate.rs"
[dependencies]
actix-web = "4.0.1"
actix-web = "4.3"
actix-identity = "0.4.0"
actix-session = { version = "0.6.1", features = ["cookie-session"]}
actix-session = { version = "0.10.0", features = ["cookie-session"]}
actix-http = "3.0.4"
actix-rt = "2"
actix-cors = "0.6.1"
actix-cors = "0.7.0"
actix-files = "0.6.0"
actix-service = "2.0.0"
#actix = "0.12"
actix-web-codegen-const-routes = { version = "0.1.0", tag = "0.1.0", git = "https://github.com/realaravinth/actix-web-codegen-const-routes" }
actix-web-codegen-const-routes = "0.2.0"
#libmcaptcha = { branch = "master", git = "https://github.com/mCaptcha/libmcaptcha", features = ["full"] }
futures = "0.3.15"
sqlx = { version = "0.5.9", features = [ "runtime-actix-rustls", "postgres", "time", "offline" ] }
sqlx = { version = "0.8", features = [ "runtime-tokio-rustls", "postgres", "time", "uuid" ] }
#argon2-creds = "0.2.3"
argon2-creds = { branch = "master", git = "https://github.com/realaravinth/argon2-creds"}
derive_builder = "0.11"
validator = { version = "0.14", features = ["derive"]}
derive_builder = "0.20"
validator = { version = "0.18", features = ["derive"]}
derive_more = "0.99"
config = "0.11"
config = "0.14"
serde = "1"
serde_json = "1"
pretty_env_logger = "0.4"
pretty_env_logger = "0.5"
log = "0.4"
lazy_static = "1.4"
@ -57,16 +59,21 @@ url = { version = "2.2", features = ["serde"] }
urlencoding = "2.1.0"
rand = "0.8"
uuid = { version = "0.8.2", features = ["v4", "serde"] }
uuid = { version = "1.4.1", features = ["v4", "serde"] }
mime_guess = "2.0.3"
rust-embed = "6.0.0"
rust-embed = "8.0.0"
#libcachebust = "0.3.0"
cache-buster = { git = "https://github.com/realaravinth/cache-buster" }
mime = "0.3.16"
#sailfish = "0.3.2"
tracing = { version = "0.1.37", features = ["log"] }
tera = { version="1.17.1", features=["builtins"]}
tokio = { version = "1.25.0", features = ["fs", "macros"] }
csv-async = { version = "1.2.5", features = ["serde", "tokio"] }
async-trait = "0.1.68"
reqwest = { version = "0.12.0", features = ["json", "gzip", "native-tls-vendored"] }
#tokio = "1.11.0"
@ -78,9 +85,11 @@ version = "0.2"
[build-dependencies]
sqlx = { version = "0.5.9", features = [ "runtime-actix-rustls", "uuid", "postgres", "time", "offline" ] }
#serde_yaml = "0.8.17"
sqlx = { version = "0.8", features = [ "runtime-tokio-rustls", "uuid", "postgres", "time"] }
serde_json = "1"
#yaml-rust = "0.4.5"
cache-buster = { version = "0.2.0", git = "https://github.com/realaravinth/cache-buster" }
mime = "0.3.16"
[dev-dependencies]
mktemp = "0.5.0"

View file

@ -1,4 +1,4 @@
FROM node:16.11-bullseye-slim as frontend
FROM node:20-bookworm-slim as frontend
LABEL org.opencontainers.image.source https://github.com/mCaptcha/survey
RUN apt-get update && apt-get install -y make
COPY package.json yarn.lock /src/
@ -8,14 +8,14 @@ RUN yarn install
COPY . .
RUN make frontend
FROM rust:1-slim-bullseye as rust
FROM rust:latest as rust
WORKDIR /src
RUN apt-get update && apt-get install -y git
RUN apt-get update && apt-get install -y git libssl-dev
COPY . /src
COPY --from=frontend /src/static/cache/bundle /src/static/cache/bundle
RUN cargo build --release
FROM debian:bullseye-slim
FROM debian:bookworm
RUN useradd -ms /bin/bash -u 1001 mcaptcha-survey
WORKDIR /home/mcaptcha-survey
COPY --from=rust /src/target/release/survey /usr/local/bin/

View file

@ -1,3 +1,15 @@
define deploy_dependencies
@-docker create --name ${db} \
-e POSTGRES_PASSWORD=password \
-p 5433:5432 \
postgres
docker start ${db}
endef
define run_migrations
cargo run --bin tests-migrate
endef
default: frontend ## Debug build
cargo build
@ -19,11 +31,25 @@ dev-env: ## Download development dependencies
cargo fetch
yarn install
env.db.recreate: ## Deploy dependencies
@-docker rm -f ${db}
$(call deploy_dependencies)
sleep 5
$(call run_migrations)
env.db: ## Deploy dependencies
$(call deploy_dependencies)
sleep 5
$(call run_migrations)
doc: ## Prepare documentation
cargo doc --no-deps --workspace --all-features
docker: ## Build docker images
docker build -t mcaptcha/survey:master -t mcaptcha/survey:latest .
docker buildx build -t mcaptcha/survey:master -t mcaptcha/survey:latest . --load
docker-publish: docker ## Build and publish docker images
docker push mcaptcha/survey:master
@ -43,7 +69,7 @@ lint: ## Lint codebase
yarn lint
migrate: ## Run database migrations
cargo run --bin tests-migrate
$(call run_migrations)
release: frontend ## Release build
cargo build --release
@ -60,7 +86,7 @@ sqlx-offline-data: ## prepare sqlx offline data
test: frontend ## Run tests
echo 'static/' && tree static || true
echo 'tree/' && tree assets || true
cargo test --all-features --no-fail-fast
cargo test --all-features --no-fail-fast -j 1
xml-test-coverage: migrate ## Generate cobertura.xml test coverage
cargo tarpaulin -t 1200 --out Xml

View file

@ -40,3 +40,21 @@ published to fine-tune their CAPTCHA deployment.
## What data do you collect?
TODO: run program, record and share actual network traffic logs
## Funding
### NLnet
<div align="center">
<img
height="150px"
alt="NLnet NGIZero logo"
src="./docs/third-party/NGIZero-green.hex.svg"
/>
</div>
<br />
2023 development is funded through the [NGI0 Entrust
Fund](https://nlnet.nl/entrust), via [NLnet](https://nlnet.nl/). Please
see [here](https://nlnet.nl/project/mCaptcha/) for more details.

View file

@ -34,6 +34,10 @@ password = "password"
name = "postgres"
pool = 4
[publish]
dir = "/tmp/mcaptcha-survey"
duration = 3600
[footer]
about = "https://mcapthca.org/about"
donate = "https://mcapthca.org/donate"

View file

@ -10,7 +10,7 @@ services:
RUST_LOG: debug
postgres:
image: postgres:13.2
image: postgres:16.4
volumes:
- mcaptcha-survey-data:/var/lib/postgresql/
environment:

103
docs/third-party/NGIZero-green.hex.svg vendored Normal file
View file

@ -0,0 +1,103 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Generator: Adobe Illustrator 16.0.4, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
id="Ebene_1"
x="0px"
y="0px"
width="165.92125"
height="191.45087"
viewBox="0 0 165.92125 191.45086"
enable-background="new 0 0 198.425 198.425"
xml:space="preserve"
sodipodi:docname="NGIZero-green.svg"
inkscape:version="0.92.4 (5da689c313, 2019-01-14)"><metadata
id="metadata4142"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
id="defs4140" /><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="1007"
id="namedview4138"
showgrid="false"
inkscape:zoom="1.6820179"
inkscape:cx="-191.39267"
inkscape:cy="54.855534"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="Ebene_1"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0" />
<polygon
points="36.911,63.104 36.911,66.116 36.911,132.309 36.911,135.321 39.346,136.825 96.715,169.921 99.273,171.419 101.853,169.921 159.319,136.825 161.938,135.321 161.938,132.309 161.938,66.116 161.938,63.104 159.308,61.6 101.841,28.504 99.234,27.006 96.629,28.504 39.347,61.6 "
id="polygon4013"
style="fill:#96c00a;fill-opacity:1"
transform="matrix(1.3249745,0,0,1.3249745,-48.642464,-35.674938)" />
<polygon
points="161.712,62.925 161.712,131.589 99.212,167.589 36.712,131.589 36.712,62.925 99.212,26.925 "
id="polygon4015"
style="fill:#97bf00;fill-opacity:0.91764706"
transform="matrix(1.3249745,0,0,1.3249745,-48.642464,-35.674938)" />
<polygon
stroke-miterlimit="10"
points="157.712,65.379 157.712,133.046 99.212,166.88 40.712,133.046 40.712,65.379 99.212,31.546 "
id="Outerline"
transform="matrix(1.3249745,0,0,1.3249745,-48.642464,-35.674938)"
style="fill:none;stroke:#ffffff;stroke-width:2;stroke-miterlimit:10"
inkscape:label="#outerline" />
<g
id="g4281"
transform="matrix(1.3249745,0,0,1.3249745,-47.067006,-23.859001)"><path
inkscape:connector-curvature="0"
id="path42"
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.55783975"
d="m 133.45691,60.461638 v 0 c 2.27263,0 4.11462,1.841988 4.11462,4.114628 v 27.330241 c 0,2.27264 -1.84199,4.114628 -4.11462,4.114628 -2.27264,0 -4.11463,-1.841988 -4.11463,-4.114628 V 64.576266 c 0,-2.27264 1.84199,-4.114628 4.11463,-4.114628" /><g
transform="matrix(0.55783976,0,0,-0.55783976,120.13631,77.682765)"
id="g44"><path
inkscape:connector-curvature="0"
id="path46"
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="M 0,0 H -0.506 C -0.57,0 -0.633,-0.008 -0.698,-0.01 -0.762,-0.008 -0.825,0 -0.89,0 h -7.283 c -3.929,0 -7.359,-2.965 -7.613,-6.885 -0.278,-4.296 3.124,-7.867 7.361,-7.867 0.776,0 1.343,-0.754 1.111,-1.494 -0.658,-2.088 -2.341,-3.751 -4.547,-4.333 -2.074,-0.547 -4.276,-0.821 -6.605,-0.821 -4.007,0 -7.574,0.865 -10.7,2.595 -3.127,1.73 -5.57,4.144 -7.331,7.24 -1.761,3.096 -2.641,6.617 -2.641,10.564 0,4.006 0.88,7.558 2.641,10.654 1.761,3.097 4.219,5.493 7.377,7.195 3.156,1.698 6.768,2.549 10.836,2.549 4.681,0 8.865,-1.269 12.55,-3.807 2.341,-1.612 5.524,-1.588 7.757,0.171 3.48,2.741 3.289,8.045 -0.315,10.452 -1.7,1.136 -3.538,2.112 -5.512,2.928 -4.553,1.881 -9.623,2.823 -15.208,2.823 -6.679,0 -12.69,-1.412 -18.03,-4.235 -5.344,-2.822 -9.517,-6.738 -12.522,-11.747 -3.005,-5.008 -4.508,-10.67 -4.508,-16.983 0,-6.315 1.503,-11.975 4.508,-16.984 3.005,-5.009 7.148,-8.924 12.43,-11.747 5.282,-2.824 11.231,-4.235 17.849,-4.235 4.613,0 9.197,0.699 13.751,2.095 0.045,0.014 0.091,0.028 0.136,0.042 7.104,2.202 11.884,8.86 11.884,16.297 v 9.047 C 6.486,-2.904 3.583,0 0,0" /></g><g
transform="matrix(0.55783976,0,0,-0.55783976,85.80763,64.525332)"
id="g48"><path
inkscape:connector-curvature="0"
id="path50"
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 0,0 v -49.176 c 0,-4.023 -3.262,-7.285 -7.286,-7.285 h -1.381 c -2.181,0 -4.247,0.977 -5.631,2.662 l -24.229,29.505 c -1.804,2.197 -5.368,0.921 -5.368,-1.922 v -22.96 c 0,-4.023 -3.261,-7.285 -7.285,-7.285 -4.023,0 -7.285,3.262 -7.285,7.285 V 0 c 0,4.024 3.262,7.285 7.285,7.285 h 1.468 c 2.184,0 4.253,-0.979 5.636,-2.669 l 24.135,-29.475 c 1.802,-2.202 5.37,-0.927 5.37,1.918 V 0 c 0,4.024 3.261,7.285 7.285,7.285 C -3.262,7.285 0,4.024 0,0" /></g></g><g
aria-label="Z E R O"
transform="matrix(0.94681934,0,0,0.94681934,-209.97267,182.03385)"
style="font-variant:normal;font-weight:600;font-stretch:normal;font-size:31.76000023px;font-family:'Montserrat SemiBold';-inkscape-font-specification:Montserrat-SemiBold;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:0.7171717;fill-rule:nonzero;stroke:none"
id="text56"><path
inkscape:connector-curvature="0"
d="m 243.58117,-73.015206 h 19.46231 v 3.613321 l -12.42176,15.02707 h 12.77844 v 4.512774 h -20.17567 v -3.613321 l 12.42176,-15.02707 h -12.06508 z"
id="path2325" /><path
inkscape:connector-curvature="0"
d="m 278.7684,-73.015206 h 16.11262 v 4.512774 h -10.14211 v 4.311172 h 9.5373 v 4.512773 h -9.5373 v 5.303672 h 10.48328 v 4.512774 H 278.7684 Z"
id="path2327" /><path
inkscape:connector-curvature="0"
d="m 320.00367,-62.749034 q 1.87645,0 2.68285,-0.697851 0.82192,-0.697852 0.82192,-2.295157 0,-1.581796 -0.82192,-2.26414 -0.8064,-0.682344 -2.68285,-0.682344 h -2.51226 v 5.939492 z m -2.51226,4.125078 v 8.761915 h -5.97051 v -23.153165 h 9.11859 q 4.57481,0 6.69938,1.535274 2.14008,1.535273 2.14008,4.853945 0,2.295156 -1.11657,3.768399 -1.10105,1.473242 -3.33418,2.171093 1.22512,0.279141 2.18661,1.271641 0.97699,0.976992 1.96949,2.9775 l 3.24113,6.575313 h -6.3582 l -2.82242,-5.753399 q -0.85293,-1.736875 -1.73688,-2.372695 -0.86844,-0.635821 -2.32617,-0.635821 z"
id="path2329" /><path
inkscape:connector-curvature="0"
d="m 357.57911,-69.107237 q -2.72938,0 -4.23364,2.016016 -1.50425,2.016015 -1.50425,5.675859 0,3.644336 1.50425,5.660352 1.50426,2.016015 4.23364,2.016015 2.74488,0 4.24914,-2.016015 1.50426,-2.016016 1.50426,-5.660352 0,-3.659844 -1.50426,-5.675859 -1.50426,-2.016016 -4.24914,-2.016016 z m 0,-4.32668 q 5.58281,0 8.7464,3.19461 3.1636,3.194609 3.1636,8.823945 0,5.613828 -3.1636,8.808438 -3.16359,3.194609 -8.7464,3.194609 -5.56731,0 -8.74641,-3.194609 -3.16359,-3.19461 -3.16359,-8.808438 0,-5.629336 3.16359,-8.823945 3.1791,-3.19461 8.74641,-3.19461 z"
id="path2331" /></g></svg>

After

Width:  |  Height:  |  Size: 7.3 KiB

View file

@ -1,3 +1,7 @@
-- SPDX-FileCopyrightText: 2023 Aravinth Manivannan <realaravinth@batsense.net>
--
-- SPDX-License-Identifier: AGPL-3.0-or-later
CREATE TABLE IF NOT EXISTS survey_users (
ID UUID PRIMARY KEY NOT NULL UNIQUE,
created_at TIMESTAMPTZ NOT NULL

View file

@ -1,3 +1,7 @@
-- SPDX-FileCopyrightText: 2023 Aravinth Manivannan <realaravinth@batsense.net>
--
-- SPDX-License-Identifier: AGPL-3.0-or-later
-- Add migration script here
CREATE TABLE IF NOT EXISTS survey_admins (
name VARCHAR(100) NOT NULL UNIQUE,

View file

@ -1,2 +1,6 @@
-- SPDX-FileCopyrightText: 2023 Aravinth Manivannan <realaravinth@batsense.net>
--
-- SPDX-License-Identifier: AGPL-3.0-or-later
ALTER TABLE survey_responses
ADD COLUMN submitted_at TIMESTAMPTZ NOT NULL DEFAULT now();

View file

@ -1,3 +1,7 @@
-- SPDX-FileCopyrightText: 2023 Aravinth Manivannan <realaravinth@batsense.net>
--
-- SPDX-License-Identifier: AGPL-3.0-or-later
CREATE TABLE IF NOT EXISTS survey_bench_type (
name VARCHAR(30) UNIQUE NOT NULL,
ID SERIAL PRIMARY KEY NOT NULL

View file

@ -0,0 +1,42 @@
-- SPDX-FileCopyrightText: 2023 Aravinth Manivannan <realaravinth@batsense.net>
--
-- SPDX-License-Identifier: AGPL-3.0-or-later
CREATE TABLE IF NOT EXISTS survey_mcaptcha_hostname (
url VARCHAR(3000) UNIQUE NOT NULL,
secret VARCHAR(100) UNIQUE NOT NULL,
ID SERIAL PRIMARY KEY NOT NULL
);
CREATE TABLE IF NOT EXISTS survey_mcaptcha_campaign (
campaign_id VARCHAR(100) NOT NULL,
public_id VARCHAR(100) NOT NULL,
url_id INTEGER NOT NULL references survey_mcaptcha_hostname(ID) ON DELETE CASCADE,
synced_till INTEGER NOT NULL DEFAULT 0,
ID SERIAL PRIMARY KEY NOT NULL
);
CREATE TABLE IF NOT EXISTS survey_mcaptcha_analytics (
campaign_id INTEGER references survey_mcaptcha_campaign(ID) ON DELETE CASCADE,
time INTEGER NOT NULL,
difficulty_factor INTEGER NOT NULL,
worker_type VARCHAR(100) NOT NULL,
ID SERIAL PRIMARY KEY NOT NULL
);
CREATE TABLE IF NOT EXISTS survey_mcaptcha_upload_job_states (
name VARCHAR(20) NOT NULL UNIQUE,
ID SERIAL PRIMARY KEY NOT NULL
);
CREATE TABLE IF NOT EXISTS survey_mcaptcha_upload_jobs (
campaign_id INTEGER references survey_mcaptcha_campaign(ID) ON DELETE CASCADE,
public_id varchar(100) NOT NULL UNIQUE,
created_at timestamptz NOT NULL DEFAULT now(),
scheduled_at timestamptz DEFAULT NULL,
finished_at timestamptz DEFAULT NULL,
job_state INTEGER references survey_mcaptcha_upload_job_states(ID) ON DELETE CASCADE,
ID SERIAL PRIMARY KEY NOT NULL
);

8920
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -10,26 +10,26 @@
"test": "jest"
},
"devDependencies": {
"@types/jest": "^27.0.2",
"@types/jsdom": "^16.2.10",
"@types/node": "^16.10.5",
"@types/sinon": "^10.0.0",
"@typescript-eslint/eslint-plugin": "^5.0.0",
"@typescript-eslint/parser": "^5.0.0",
"@types/jest": "^29.0.0",
"@types/jsdom": "^21.0.0",
"@types/node": "^20.0.0",
"@types/sinon": "^17.0.0",
"@typescript-eslint/eslint-plugin": "^8.0.0",
"@typescript-eslint/parser": "^8.0.0",
"@wasm-tool/wasm-pack-plugin": "^1.6.0",
"dart-sass": "^1.25.0",
"eslint": "^8.0.1",
"jest": "^27.2.5",
"eslint": "^9.0.0",
"jest": "^29.0.0",
"jest-fetch-mock": "^3.0.3",
"jsdom": "^18.0.0",
"sinon": "^11.1.2",
"ts-jest": "^27.0.5",
"jsdom": "^25.0.0",
"sinon": "^19.0.0",
"ts-jest": "^29.0.0",
"ts-loader": "^9.2.6",
"ts-node": "^10.3.0",
"typescript": "^4.4.4",
"typescript": "^5.0.0",
"webpack": "^5.0.0",
"webpack-cli": "^4.6.0",
"webpack-dev-server": "^4.3.1"
"webpack-cli": "^5.0.0",
"webpack-dev-server": "^5.0.0"
},
"dependencies": {
"@mcaptcha/vanilla-glue": "^0.1.0-alpha-3",

21
renovate.json Normal file
View file

@ -0,0 +1,21 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"config:recommended",
":dependencyDashboard"
],
"labels": [
"renovate-bot"
],
"prHourlyLimit": 0,
"timezone": "Asia/kolkata",
"prCreation": "immediate",
"vulnerabilityAlerts": {
"enabled": true,
"labels": [
"renovate-bot",
"renovate-security",
"security"
]
}
}

View file

@ -1,376 +1,3 @@
{
"db": "PostgreSQL",
"03c9789e83a398bed96354924a0e63ccaa97bec667fda1b8277bb9afda9a6fcd": {
"describe": {
"columns": [],
"nullable": [],
"parameters": {
"Left": [
"Text",
"Uuid"
]
}
},
"query": "DELETE \n FROM survey_campaigns \n WHERE \n user_id = (\n SELECT \n ID \n FROM \n survey_admins \n WHERE \n name = $1\n )\n AND\n id = ($2)"
},
"0d22134cc5076304b7895827f006ee8269cc500f400114a7472b83f0f1c568b5": {
"describe": {
"columns": [],
"nullable": [],
"parameters": {
"Left": [
"Varchar",
"Text",
"Varchar"
]
}
},
"query": "INSERT INTO survey_admins \n (name , password, secret) VALUES ($1, $2, $3)"
},
"1373df097fa0e58b23a374753318ae53a44559aa0e7eb64680185baf1c481723": {
"describe": {
"columns": [
{
"name": "password",
"ordinal": 0,
"type_info": "Text"
}
],
"nullable": [
false
],
"parameters": {
"Left": [
"Text"
]
}
},
"query": "SELECT password FROM survey_admins WHERE name = ($1)"
},
"19686bfe8772cbc6831d46d18994e2b9aa40c7181eae9a31e51451cce95f04e8": {
"describe": {
"columns": [
{
"name": "name",
"ordinal": 0,
"type_info": "Varchar"
},
{
"name": "password",
"ordinal": 1,
"type_info": "Text"
}
],
"nullable": [
false,
false
],
"parameters": {
"Left": [
"Text"
]
}
},
"query": "SELECT name, password FROM survey_admins WHERE email = ($1)"
},
"1b7e17bfc949fa97e8dec1f95e35a02bcf3aa1aa72a1f6f6c8884e885fc3b953": {
"describe": {
"columns": [],
"nullable": [],
"parameters": {
"Left": [
"Varchar",
"Text",
"Varchar",
"Varchar"
]
}
},
"query": "insert into survey_admins \n (name , password, email, secret) values ($1, $2, $3, $4)"
},
"2ccaecfee4d2f29ef5278188b304017719720aa986d680d4727a1facbb869c7a": {
"describe": {
"columns": [],
"nullable": [],
"parameters": {
"Left": [
"Text"
]
}
},
"query": "DELETE FROM survey_admins WHERE name = ($1)"
},
"43b3e771f38bf8059832169227705be06a28925af1b3799ffef5371d511fd138": {
"describe": {
"columns": [],
"nullable": [],
"parameters": {
"Left": [
"Timestamptz",
"Uuid"
]
}
},
"query": "\n INSERT INTO survey_users (created_at, id) VALUES($1, $2)"
},
"536541ecf2e1c0403c74b6e2e09b42b73a7741ae4a348ff539ac410022e03ace": {
"describe": {
"columns": [
{
"name": "exists",
"ordinal": 0,
"type_info": "Bool"
}
],
"nullable": [
null
],
"parameters": {
"Left": [
"Text"
]
}
},
"query": "SELECT EXISTS (SELECT 1 from survey_admins WHERE name = $1)"
},
"55dde28998a6d12744806035f0a648494a403c7d09ea3caf91bf54869a81aa73": {
"describe": {
"columns": [],
"nullable": [],
"parameters": {
"Left": [
"Text",
"Text"
]
}
},
"query": "UPDATE survey_admins set password = $1\n WHERE name = $2"
},
"58ec3b8f98c27e13ec2732f8ee23f6eb9845ac5d9fd97b1e5c9f2eed4b1f5693": {
"describe": {
"columns": [
{
"name": "name",
"ordinal": 0,
"type_info": "Varchar"
}
],
"nullable": [
false
],
"parameters": {
"Left": [
"Uuid",
"Text"
]
}
},
"query": "SELECT name \n FROM survey_campaigns\n WHERE \n id = $1\n AND\n user_id = (SELECT ID from survey_admins WHERE name = $2)"
},
"683707dbc847b37c58c29aaad0d1a978c9fe0657da13af99796e4461134b5a43": {
"describe": {
"columns": [],
"nullable": [],
"parameters": {
"Left": [
"Varchar",
"Text"
]
}
},
"query": "UPDATE survey_admins set email = $1\n WHERE name = $2"
},
"6a26daa84578aed2b2085697cb8358ed7c0a50ba9597fd387b4b09b0a8a154db": {
"describe": {
"columns": [
{
"name": "exists",
"ordinal": 0,
"type_info": "Bool"
}
],
"nullable": [
null
],
"parameters": {
"Left": [
"Text"
]
}
},
"query": "SELECT EXISTS (SELECT 1 from survey_admins WHERE email = $1)"
},
"70cc7bfc9b6ff5b68db70c069c0947d51bfc4a53cedc020016ee25ff98586c93": {
"describe": {
"columns": [
{
"name": "name",
"ordinal": 0,
"type_info": "Varchar"
},
{
"name": "id",
"ordinal": 1,
"type_info": "Uuid"
}
],
"nullable": [
false,
false
],
"parameters": {
"Left": [
"Text"
]
}
},
"query": "SELECT \n name, id\n FROM \n survey_campaigns \n WHERE\n user_id = (\n SELECT \n ID\n FROM \n survey_admins\n WHERE\n name = $1\n )"
},
"82feafc36533144e49ba374c8c47ca4aa0d6558a9803778ad28cfa7b62382c3e": {
"describe": {
"columns": [],
"nullable": [],
"parameters": {
"Left": [
"Text",
"Uuid",
"Varchar",
"Int4Array",
"Timestamptz"
]
}
},
"query": "\n INSERT INTO survey_campaigns (\n user_id, ID, name, difficulties, created_at\n ) VALUES(\n (SELECT id FROM survey_admins WHERE name = $1),\n $2, $3, $4, $5\n );"
},
"8320dda2b3e107d1451fdfb35eb2a4b8e97364e7b1b74ffe4d6913faf132fb61": {
"describe": {
"columns": [
{
"name": "id",
"ordinal": 0,
"type_info": "Int4"
}
],
"nullable": [
false
],
"parameters": {
"Left": [
"Uuid",
"Text"
]
}
},
"query": "SELECT ID \n FROM survey_responses \n WHERE \n user_id = $1 \n AND \n device_software_recognised = $2;"
},
"9cdade613ce724631cc3f187510758ee0929e93ff3f8ce81fe35594756644246": {
"describe": {
"columns": [
{
"name": "difficulties",
"ordinal": 0,
"type_info": "Int4Array"
}
],
"nullable": [
false
],
"parameters": {
"Left": [
"Uuid"
]
}
},
"query": "SELECT difficulties FROM survey_campaigns WHERE id = $1;"
},
"a721cfa249acf328c2f29c4cf8c2aeba1a635bcf49d18ced5474caa10b7cae4f": {
"describe": {
"columns": [],
"nullable": [],
"parameters": {
"Left": [
"Int4",
"Int4",
"Float4"
]
}
},
"query": "INSERT INTO survey_benches \n (resp_id, difficulty, duration) \n VALUES ($1, $2, $3);"
},
"ab951c5c318174c6538037947c2f52c61bcfe5e5be1901379b715e77f5214dd2": {
"describe": {
"columns": [],
"nullable": [],
"parameters": {
"Left": [
"Varchar",
"Text"
]
}
},
"query": "UPDATE survey_admins set secret = $1\n WHERE name = $2"
},
"b4cd1e5240de1968c8b6d56672cec639b22f41ebf2754dadbf00efe0948c7e68": {
"describe": {
"columns": [],
"nullable": [],
"parameters": {
"Left": [
"Uuid",
"Uuid",
"Varchar",
"Varchar",
"Int4"
]
}
},
"query": "INSERT INTO survey_responses (\n user_id, \n campaign_id,\n device_user_provided,\n device_software_recognised,\n threads\n ) VALUES ($1, $2, $3, $4, $5);"
},
"c757589ef26a005e3285e7ab20d8a44c4f2e1cb125f8db061dd198cc380bf807": {
"describe": {
"columns": [],
"nullable": [],
"parameters": {
"Left": [
"Varchar",
"Text"
]
}
},
"query": "UPDATE survey_admins set name = $1\n WHERE name = $2"
},
"e9cf5d6d8c9e8327d5c809d47a14a933f324e267f1e7dbb48e1caf1c021adc3f": {
"describe": {
"columns": [
{
"name": "secret",
"ordinal": 0,
"type_info": "Varchar"
}
],
"nullable": [
false
],
"parameters": {
"Left": [
"Text"
]
}
},
"query": "SELECT secret FROM survey_admins WHERE name = ($1)"
},
"fcdc5fe5d496eb516c805e64ec96d9626b74ab33cd6e75e5a08ae88967403b72": {
"describe": {
"columns": [],
"nullable": [],
"parameters": {
"Left": [
"Int4",
"Uuid",
"Uuid"
]
}
},
"query": "INSERT INTO survey_response_tokens \n (resp_id, user_id, id)\n VALUES ($1, $2, $3);"
}
"db": "PostgreSQL"
}

View file

@ -1,18 +1,6 @@
/*
* Copyright (C) 2021 Aravinth Manivannan <realaravinth@batsense.net>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
// Copyright (C) 2021 Aravinth Manivannan <realaravinth@batsense.net>
// SPDX-FileCopyrightText: 2023 Aravinth Manivannan <realaravinth@batsense.net>
//
// SPDX-License-Identifier: AGPL-3.0-or-later
pub mod v1;

View file

@ -1,19 +1,7 @@
/*
* Copyright (C) 2021 Aravinth Manivannan <realaravinth@batsense.net>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
// Copyright (C) 2021 Aravinth Manivannan <realaravinth@batsense.net>
// SPDX-FileCopyrightText: 2023 Aravinth Manivannan <realaravinth@batsense.net>
//
// SPDX-License-Identifier: AGPL-3.0-or-later
use actix_identity::Identity;
use actix_web::{web, HttpResponse, Responder};

View file

@ -1,19 +1,8 @@
/*
* Copyright (C) 2021 Aravinth Manivannan <realaravinth@batsense.net>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
// Copyright (C) 2021 Aravinth Manivannan <realaravinth@batsense.net>
// SPDX-FileCopyrightText: 2023 Aravinth Manivannan <realaravinth@batsense.net>
//
// SPDX-License-Identifier: AGPL-3.0-or-later
use std::borrow::Cow;
use actix_identity::Identity;

View file

@ -1,19 +1,7 @@
/*
* Copyright (C) 2021 Aravinth Manivannan <realaravinth@batsense.net>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
// Copyright (C) 2021 Aravinth Manivannan <realaravinth@batsense.net>
// SPDX-FileCopyrightText: 2023 Aravinth Manivannan <realaravinth@batsense.net>
//
// SPDX-License-Identifier: AGPL-3.0-or-later
use serde::{Deserialize, Serialize};

View file

@ -1,19 +1,8 @@
/*
* Copyright (C) 2021 Aravinth Manivannan <realaravinth@batsense.net>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
// Copyright (C) 2021 Aravinth Manivannan <realaravinth@batsense.net>
// SPDX-FileCopyrightText: 2023 Aravinth Manivannan <realaravinth@batsense.net>
//
// SPDX-License-Identifier: AGPL-3.0-or-later
use actix_identity::Identity;
use actix_web::{web, HttpResponse, Responder};
use argon2_creds::Config;
@ -126,12 +115,12 @@ mod tests {
const PASSWORD: &str = "longpassword2";
const EMAIL: &str = "updatepassuser@a.com";
let data = get_test_data().await;
{
let data = get_test_data().await;
delete_user(NAME, &data).await;
}
let (data, _, signin_resp) = register_and_signin(NAME, EMAIL, PASSWORD).await;
let (_, signin_resp) = register_and_signin(&data, NAME, EMAIL, PASSWORD).await;
let cookies = get_cookie!(signin_resp);
let app = get_app!(data).await;
@ -164,6 +153,7 @@ mod tests {
};
bad_post_req_test(
&data,
NAME,
new_password,
ROUTES.admin.account.update_password,
@ -179,6 +169,7 @@ mod tests {
};
bad_post_req_test(
&data,
NAME,
new_password,
ROUTES.admin.account.update_password,

View file

@ -1,19 +1,8 @@
/*
* Copyright (C) 2021 Aravinth Manivannan <realaravinth@batsense.net>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
// Copyright (C) 2021 Aravinth Manivannan <realaravinth@batsense.net>
// SPDX-FileCopyrightText: 2023 Aravinth Manivannan <realaravinth@batsense.net>
//
// SPDX-License-Identifier: AGPL-3.0-or-later
use std::borrow::Cow;
use actix_identity::Identity;

View file

@ -1,19 +1,7 @@
/*
* Copyright (C) 2021 Aravinth Manivannan <realaravinth@batsense.net>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
// Copyright (C) 2021 Aravinth Manivannan <realaravinth@batsense.net>
// SPDX-FileCopyrightText: 2023 Aravinth Manivannan <realaravinth@batsense.net>
//
// SPDX-License-Identifier: AGPL-3.0-or-later
use actix_web::http::StatusCode;
use actix_web::test;
@ -34,12 +22,12 @@ async fn uname_email_exists_works() {
const PASSWORD: &str = "longpassword2";
const EMAIL: &str = "testuserexists@a.com2";
let data = get_test_data().await;
{
let data = get_test_data().await;
delete_user(NAME, &data).await;
}
let (data, _, signin_resp) = register_and_signin(NAME, EMAIL, PASSWORD).await;
let (_, signin_resp) = register_and_signin(&data, NAME, EMAIL, PASSWORD).await;
let cookies = get_cookie!(signin_resp);
let app = get_app!(data).await;
@ -124,14 +112,14 @@ async fn email_udpate_password_validation_del_userworks() {
const NAME2: &str = "eupdauser";
const EMAIL2: &str = "eupdauser@a.com";
let data = get_test_data().await;
{
let data = get_test_data().await;
delete_user(NAME, &data).await;
delete_user(NAME2, &data).await;
}
let _ = register_and_signin(NAME2, EMAIL2, PASSWORD).await;
let (data, _creds, signin_resp) = register_and_signin(NAME, EMAIL, PASSWORD).await;
let _ = register_and_signin(&data, NAME2, EMAIL2, PASSWORD).await;
let (_creds, signin_resp) = register_and_signin(&data, NAME, EMAIL, PASSWORD).await;
let cookies = get_cookie!(signin_resp);
let app = get_app!(data).await;
@ -152,6 +140,7 @@ async fn email_udpate_password_validation_del_userworks() {
// check duplicate email while duplicate email
email_payload.email = EMAIL2.into();
bad_post_req_test(
&data,
NAME,
PASSWORD,
ROUTES.admin.account.update_email,
@ -165,6 +154,7 @@ async fn email_udpate_password_validation_del_userworks() {
password: NAME.into(),
};
bad_post_req_test(
&data,
NAME,
PASSWORD,
ROUTES.admin.account.delete,
@ -207,9 +197,8 @@ async fn username_update_works() {
const NAME2: &str = "terstusrtds";
const NAME_CHANGE: &str = "terstusrtdsxx";
let data = get_test_data().await;
{
let data = get_test_data().await;
futures::join!(
delete_user(NAME, &data),
delete_user(NAME2, &data),
@ -217,8 +206,8 @@ async fn username_update_works() {
);
}
let _ = register_and_signin(NAME2, EMAIL2, PASSWORD).await;
let (data, _creds, signin_resp) = register_and_signin(NAME, EMAIL, PASSWORD).await;
let _ = register_and_signin(&data, NAME2, EMAIL2, PASSWORD).await;
let (_creds, signin_resp) = register_and_signin(&data, NAME, EMAIL, PASSWORD).await;
let cookies = get_cookie!(signin_resp);
let app = get_app!(data).await;
@ -238,6 +227,7 @@ async fn username_update_works() {
// check duplicate username with duplicate username
username_udpate.username = NAME2.into();
bad_post_req_test(
&data,
NAME_CHANGE,
PASSWORD,
ROUTES.admin.account.update_username,

View file

@ -1,19 +1,8 @@
/*
* Copyright (C) 2021 Aravinth Manivannan <realaravinth@batsense.net>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
// Copyright (C) 2021 Aravinth Manivannan <realaravinth@batsense.net>
// SPDX-FileCopyrightText: 2023 Aravinth Manivannan <realaravinth@batsense.net>
//
// SPDX-License-Identifier: AGPL-3.0-or-later
use std::borrow::Cow;
use actix_identity::Identity;

View file

@ -1,19 +1,7 @@
/*
* Copyright (C) 2021 Aravinth Manivannan <realaravinth@batsense.net>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
// Copyright (C) 2021 Aravinth Manivannan <realaravinth@batsense.net>
// SPDX-FileCopyrightText: 2023 Aravinth Manivannan <realaravinth@batsense.net>
//
// SPDX-License-Identifier: AGPL-3.0-or-later
use actix_identity::Identity;
use actix_web::http::header;

View file

@ -1,26 +1,15 @@
/*
* Copyright (C) 2021 Aravinth Manivannan <realaravinth@batsense.net>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
// Copyright (C) 2021 Aravinth Manivannan <realaravinth@batsense.net>
// SPDX-FileCopyrightText: 2023 Aravinth Manivannan <realaravinth@batsense.net>
//
// SPDX-License-Identifier: AGPL-3.0-or-later
use std::borrow::Cow;
use actix_identity::Identity;
use actix_web::{web, HttpResponse, Responder};
use serde::{Deserialize, Serialize};
use sqlx::types::time::OffsetDateTime;
use uuid::Uuid;
use sqlx::types::Uuid;
use super::{get_admin_check_login, get_uuid};
use crate::api::v1::bench::Bench;
@ -102,7 +91,7 @@ pub mod runners {
username: &str,
payload: &mut AddCapmaign,
data: &AppData,
) -> ServiceResult<uuid::Uuid> {
) -> ServiceResult<sqlx::types::Uuid> {
let mut uuid;
let now = OffsetDateTime::now_utc();
@ -143,6 +132,32 @@ pub mod runners {
Ok(uuid)
}
pub async fn list_all_campaigns(
data: &AppData,
) -> ServiceResult<Vec<ListCampaignResp>> {
struct ListCampaign {
name: String,
id: Uuid,
}
let mut campaigns = sqlx::query_as!(
ListCampaign,
"SELECT name, id FROM survey_campaigns ORDER BY id;"
)
.fetch_all(&data.db)
.await?;
let mut list_resp = Vec::with_capacity(campaigns.len());
campaigns.drain(0..).for_each(|c| {
list_resp.push(ListCampaignResp {
name: c.name,
uuid: c.id.to_string(),
});
});
Ok(list_resp)
}
pub async fn list_campaign_runner(
username: &str,
data: &AppData,
@ -203,7 +218,7 @@ pub mod runners {
impl From<InnerU> for SurveyUser {
fn from(u: InnerU) -> Self {
Self {
id: u.id,
id: uuid::Uuid::parse_str(&u.id.to_string()).unwrap(),
created_at: u.created_at.unix_timestamp(),
}
}
@ -254,13 +269,13 @@ pub mod runners {
} else {
#[derive(Debug)]
struct I {
id: Option<i32>,
submitted_at: Option<OffsetDateTime>,
user_id: Option<Uuid>,
id: i32,
submitted_at: OffsetDateTime,
user_id: Uuid,
threads: Option<i32>,
device_user_provided: Option<String>,
device_software_recognised: Option<String>,
name: Option<String>,
device_user_provided: String,
device_software_recognised: String,
name: String,
}
let mut i = sqlx::query_as!(
I,
@ -296,13 +311,13 @@ pub mod runners {
let mut res = Vec::with_capacity(i.len());
i.drain(0..).for_each(|x| {
res.push(InternalSurveyResp {
id: x.id.unwrap(),
submitted_at: x.submitted_at.unwrap(),
user_id: x.user_id.unwrap(),
id: x.id,
submitted_at: x.submitted_at,
user_id: x.user_id,
threads: x.threads,
device_user_provided: x.device_user_provided.unwrap(),
device_software_recognised: x.device_software_recognised.unwrap(),
name: x.name.unwrap(),
device_user_provided: x.device_user_provided,
device_software_recognised: x.device_software_recognised,
name: x.name,
})
});
res
@ -413,7 +428,7 @@ pub struct SurveyResponse {
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SurveyUser {
pub created_at: i64, // OffsetDateTime,
pub id: Uuid,
pub id: uuid::Uuid,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
@ -477,12 +492,13 @@ impl ResultsPage {
pub async fn get_campaign_resutls(
id: Identity,
query: web::Query<ResultsPage>,
path: web::Path<Uuid>,
path: web::Path<uuid::Uuid>,
data: AppData,
) -> ServiceResult<impl Responder> {
let username = id.identity().unwrap();
let query = query.into_inner();
let page = query.page();
let path = Uuid::parse_str(&path.to_string()).unwrap();
let results =
runners::get_results(&username, &path, &data, page, 50, query.bench_type)
@ -558,13 +574,13 @@ mod tests {
const DEVICE_SOFTWARE_RECOGNISED: &str = "Foobar.v2";
const THREADS: i32 = 4;
let data = get_test_data().await;
{
let data = get_test_data().await;
delete_user(NAME, &data).await;
}
let (data, _creds, signin_resp) =
register_and_signin(NAME, EMAIL, PASSWORD).await;
let (_creds, signin_resp) =
register_and_signin(&data, NAME, EMAIL, PASSWORD).await;
let cookies = get_cookie!(signin_resp);
let survey = get_survey_user(data.clone()).await;
let survey_cookie = get_cookie!(survey);
@ -592,7 +608,7 @@ mod tests {
let responses = super::runners::get_results(
NAME,
&uuid::Uuid::parse_str(&campaign.campaign_id).unwrap(),
&sqlx::types::Uuid::parse_str(&campaign.campaign_id).unwrap(),
&AppData::new(data.clone()),
0,
50,
@ -610,7 +626,7 @@ mod tests {
assert_eq!(
super::runners::get_results(
NAME,
&uuid::Uuid::parse_str(&campaign.campaign_id).unwrap(),
&sqlx::types::Uuid::parse_str(&campaign.campaign_id).unwrap(),
&AppData::new(data.clone()),
0,
50,
@ -624,7 +640,7 @@ mod tests {
assert_eq!(
super::runners::get_results(
NAME,
&uuid::Uuid::parse_str(&campaign.campaign_id).unwrap(),
&sqlx::types::Uuid::parse_str(&campaign.campaign_id).unwrap(),
&AppData::new(data.clone()),
0,
50,
@ -655,6 +671,7 @@ mod tests {
assert_eq!(responses, res);
bad_post_req_test_witout_payload(
&data,
NAME,
PASSWORD,
&V1_API_ROUTES.admin.campaign.delete.replace("{uuid}", NAME),

View file

@ -1,19 +1,8 @@
/*
* Copyright (C) 2021 Aravinth Manivannan <realaravinth@batsense.net>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
// Copyright (C) 2021 Aravinth Manivannan <realaravinth@batsense.net>
// SPDX-FileCopyrightText: 2023 Aravinth Manivannan <realaravinth@batsense.net>
//
// SPDX-License-Identifier: AGPL-3.0-or-later
use actix_auth_middleware::*;
use actix_web::web::ServiceConfig;

View file

@ -1,19 +1,7 @@
/*
* Copyright (C) 2021 Aravinth Manivannan <realaravinth@batsense.net>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
// Copyright (C) 2021 Aravinth Manivannan <realaravinth@batsense.net>
// SPDX-FileCopyrightText: 2023 Aravinth Manivannan <realaravinth@batsense.net>
//
// SPDX-License-Identifier: AGPL-3.0-or-later
use actix_web::http::{header, StatusCode};
use actix_web::test;
@ -53,11 +41,11 @@ async fn auth_works() {
delete_user(NAME, &data).await;
// 1. Register and signin
let (_, _, signin_resp) = register_and_signin(NAME, EMAIL, PASSWORD).await;
let (_, signin_resp) = register_and_signin(&data, NAME, EMAIL, PASSWORD).await;
let cookies = get_cookie!(signin_resp);
// Sign in with email
signin(EMAIL, PASSWORD).await;
signin(&data, EMAIL, PASSWORD).await;
// 2. check if duplicate username is allowed
let mut msg = Register {
@ -67,6 +55,7 @@ async fn auth_works() {
email: Some(EMAIL.into()),
};
bad_post_req_test(
&data,
NAME,
PASSWORD,
ROUTES.admin.auth.register,
@ -78,6 +67,7 @@ async fn auth_works() {
let name = format!("{}dupemail", NAME);
msg.username = name;
bad_post_req_test(
&data,
NAME,
PASSWORD,
ROUTES.admin.auth.register,
@ -92,6 +82,7 @@ async fn auth_works() {
password: msg.password.clone(),
};
bad_post_req_test(
&data,
NAME,
PASSWORD,
ROUTES.admin.auth.login,
@ -102,6 +93,7 @@ async fn auth_works() {
creds.login = "nonexistantuser@example.com".into();
bad_post_req_test(
&data,
NAME,
PASSWORD,
ROUTES.admin.auth.login,
@ -115,6 +107,7 @@ async fn auth_works() {
creds.password = NAME.into();
bad_post_req_test(
&data,
NAME,
PASSWORD,
ROUTES.admin.auth.login,

View file

@ -1,18 +1,7 @@
/*
* Copyright (C) 2021 Aravinth Manivannan <realaravinth@batsense.net>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
// Copyright (C) 2021 Aravinth Manivannan <realaravinth@batsense.net>
// SPDX-FileCopyrightText: 2023 Aravinth Manivannan <realaravinth@batsense.net>
//
// SPDX-License-Identifier: AGPL-3.0-or-later
mod auth;
mod protected;

View file

@ -1,19 +1,7 @@
/*
* Copyright (C) 2021 Aravinth Manivannan <realaravinth@batsense.net>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
// Copyright (C) 2021 Aravinth Manivannan <realaravinth@batsense.net>
// SPDX-FileCopyrightText: 2023 Aravinth Manivannan <realaravinth@batsense.net>
//
// SPDX-License-Identifier: AGPL-3.0-or-later
use actix_web::http::StatusCode;
use actix_web::test;
@ -29,13 +17,13 @@ async fn protected_routes_work() {
const EMAIL: &str = "testuser119@a.com2";
let get_protected_urls = [V1_API_ROUTES.admin.auth.logout];
let data = get_test_data().await;
{
let data = get_test_data().await;
delete_user(NAME, &data).await;
}
let (data, _, signin_resp) = register_and_signin(NAME, EMAIL, PASSWORD).await;
let (_, signin_resp) = register_and_signin(&data, NAME, EMAIL, PASSWORD).await;
let cookies = get_cookie!(signin_resp);
let app = get_app!(data).await;

View file

@ -1,19 +1,8 @@
/*
* Copyright (C) 2021 Aravinth Manivannan <realaravinth@batsense.net>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
// Copyright (C) 2021 Aravinth Manivannan <realaravinth@batsense.net>
// SPDX-FileCopyrightText: 2023 Aravinth Manivannan <realaravinth@batsense.net>
//
// SPDX-License-Identifier: AGPL-3.0-or-later
use std::borrow::Cow;
use std::str::FromStr;
@ -24,7 +13,7 @@ use actix_web::{http, web, HttpResponse, Responder};
use futures::future::try_join_all;
use serde::{Deserialize, Serialize};
use sqlx::types::time::OffsetDateTime;
use uuid::Uuid;
use sqlx::types::Uuid;
use super::{get_uuid, RedirectQuery};
use crate::errors::*;
@ -95,7 +84,7 @@ pub fn services(cfg: &mut web::ServiceConfig) {
pub mod runners {
use super::*;
pub async fn register_runner(data: &AppData) -> ServiceResult<uuid::Uuid> {
pub async fn register_runner(data: &AppData) -> ServiceResult<sqlx::types::Uuid> {
let mut uuid;
let now = OffsetDateTime::now_utc();

819
src/api/v1/mcaptcha/db.rs Normal file
View file

@ -0,0 +1,819 @@
// Copyright (C) 2023 Aravinth Manivannan <realaravinth@batsense.net>
// SPDX-FileCopyrightText: 2023 Aravinth Manivannan <realaravinth@batsense.net>
//
// SPDX-License-Identifier: AGPL-3.0-or-later
use url::Url;
use uuid::Uuid;
use crate::api::v1::get_random;
use crate::db::{
JobState, JOB_STATES, JOB_STATE_CREATE, JOB_STATE_FINISH, JOB_STATE_RUNNING,
};
use crate::errors::*;
use crate::mcaptcha::PerformanceAnalytics;
use crate::Data;
use sqlx::types::time::OffsetDateTime;
fn now_unix_time_stamp() -> OffsetDateTime {
OffsetDateTime::now_utc()
}
impl Data {
/// Check if an mCaptcha instance is registered on the database
pub async fn mcaptcha_url_exists(&self, url: &str) -> ServiceResult<bool> {
let res = sqlx::query!(
"SELECT EXISTS (SELECT 1 from survey_mcaptcha_hostname WHERE url = $1)",
url
)
.fetch_one(&self.db)
.await?;
let mut resp = false;
if let Some(x) = res.exists {
if x {
resp = true;
}
}
Ok(resp)
}
/// Register an mCaptcha instance
pub async fn mcaptcha_register_instance(&self, url: &str) -> ServiceResult<String> {
let secret = get_random(32);
sqlx::query!(
"INSERT INTO survey_mcaptcha_hostname (url, secret) VALUES ($1, $2)",
url,
&secret,
)
.execute(&self.db)
.await?;
Ok(secret)
}
/// Update the secret of an mCaptcha instance
pub async fn mcaptcha_update_secret(&self, url: &str) -> ServiceResult<String> {
let secret = get_random(32);
sqlx::query!(
"UPDATE survey_mcaptcha_hostname set secret = $1 WHERE url = $2",
&secret,
url
)
.execute(&self.db)
.await?;
Ok(secret)
}
/// Authenticate an mCaptcha instance and return its URL
pub async fn mcaptcha_authenticate(&self, secret: &str) -> ServiceResult<()> {
let res = sqlx::query!(
"SELECT EXISTS (
SELECT
url
FROM
survey_mcaptcha_hostname
WHERE secret = $1
)",
secret
)
.fetch_one(&self.db)
.await?;
if !matches!(res.exists, Some(true)) {
return Err(ServiceError::WrongPassword);
}
Ok(())
}
/// Delete mCaptcha instance from database
pub async fn mcaptcha_delete_mcaptcha_instance(
&self,
url: &str,
secret: &str,
) -> ServiceResult<()> {
sqlx::query!(
"DELETE FROM survey_mcaptcha_hostname WHERE secret = $1 AND url =$2",
secret,
url
)
.execute(&self.db)
.await?;
Ok(())
}
/// Delete mCaptcha campaign from database
pub async fn mcaptcha_delete_mcaptcha_campaign(
&self,
campaign_id: &Uuid,
secret: &str,
) -> ServiceResult<()> {
let campaign_str = campaign_id.to_string();
sqlx::query!(
"DELETE FROM
survey_mcaptcha_campaign
WHERE
campaign_id = $1
AND
url_id = (
SELECT
ID
FROM
survey_mcaptcha_hostname
WHERE
secret = $2
)",
&campaign_str,
secret
)
.execute(&self.db)
.await?;
Ok(())
}
/// Check if an mCaptcha instance campaign is registered on DB
pub async fn mcaptcha_campaign_is_registered(
&self,
campaign_id: &Uuid,
secret: &str,
) -> ServiceResult<bool> {
let campaign_str = campaign_id.to_string();
let res = sqlx::query!(
"SELECT EXISTS (
SELECT
ID
FROM
survey_mcaptcha_campaign
WHERE
campaign_id = $1
AND
url_id = (
SELECT
ID
FROM
survey_mcaptcha_hostname
WHERE
secret = $2
)
)",
&campaign_str,
secret
)
.fetch_one(&self.db)
.await?;
let mut resp = false;
if let Some(x) = res.exists {
if x {
resp = true;
}
}
Ok(resp)
}
/// Register an mCaptcha instance campaign on DB
pub async fn mcaptcha_register_campaign(
&self,
campaign_id: &Uuid,
secret: &str,
) -> ServiceResult<()> {
let campaign_str = campaign_id.to_string();
let public_id = Uuid::new_v4();
sqlx::query!(
"INSERT INTO
survey_mcaptcha_campaign (campaign_id, public_id, url_id)
VALUES ($1, $2, (SELECT ID FROM survey_mcaptcha_hostname WHERE secret = $3));",
&campaign_str,
&public_id.to_string(),
secret,
)
.execute(&self.db)
.await?;
Ok(())
}
/// Register an mCaptcha instance campaign on DB
pub async fn mcaptcha_get_campaign_public_id(
&self,
campaign_id: &Uuid,
secret: &str,
) -> ServiceResult<Uuid> {
let campaign_str = campaign_id.to_string();
struct S {
public_id: String,
}
let res = sqlx::query_as!(
S,
"SELECT
public_id
FROM
survey_mcaptcha_campaign
WHERE
campaign_id = $1
AND
url_id = (SELECT ID FROM survey_mcaptcha_hostname WHERE secret = $2);",
&campaign_str,
secret,
)
.fetch_one(&self.db)
.await?;
Ok(Uuid::parse_str(&res.public_id).unwrap())
}
/// Get an mCaptcha instance campaign checkpoint
pub async fn mcaptcha_get_checkpoint(
&self,
campaign_id: &Uuid,
) -> ServiceResult<usize> {
let campaign_str = campaign_id.to_string();
struct CheckPoint {
synced_till: i32,
}
let checkpoint = sqlx::query_as!(
CheckPoint,
"SELECT
synced_till
FROM
survey_mcaptcha_campaign
WHERE
campaign_id = $1;",
&campaign_str,
)
.fetch_one(&self.db)
.await?;
let checkpoint = checkpoint.synced_till as usize;
Ok(checkpoint)
}
/// Set an mCaptcha instance campaign checkpoint
pub async fn mcaptcha_set_checkpoint(
&self,
campaign_id: &Uuid,
checkpoint: usize,
) -> ServiceResult<()> {
let campaign_str = campaign_id.to_string();
sqlx::query!(
"UPDATE
survey_mcaptcha_campaign
SET
synced_till = $1
WHERE
campaign_id = $2; ",
checkpoint as i32,
&campaign_str,
)
.execute(&self.db)
.await?;
Ok(())
}
/// Store mCaptcha instance campaign analytics
pub async fn mcaptcha_insert_analytics(
&self,
campaign_id: &Uuid,
r: &PerformanceAnalytics,
) -> ServiceResult<()> {
let campaign_str = campaign_id.to_string();
sqlx::query!(
"INSERT INTO
survey_mcaptcha_analytics (
campaign_id, time, difficulty_factor, worker_type
)
VALUES ((
SELECT
ID
FROM
survey_mcaptcha_campaign
WHERE
campaign_id = $1
), $2, $3, $4
);",
&campaign_str,
r.time as i32,
r.difficulty_factor as i32,
&r.worker_type,
)
.execute(&self.db)
.await?;
Ok(())
}
/// fetch PoW analytics
pub async fn mcaptcha_analytics_fetch(
&self,
public_id: &Uuid,
limit: usize,
offset: usize,
) -> ServiceResult<Vec<PerformanceAnalytics>> {
let public_id_str = public_id.to_string();
struct P {
id: i32,
time: i32,
difficulty_factor: i32,
worker_type: String,
}
impl From<P> for PerformanceAnalytics {
fn from(v: P) -> Self {
Self {
time: v.time as u32,
difficulty_factor: v.difficulty_factor as u32,
worker_type: v.worker_type,
id: v.id as usize,
}
}
}
let mut c = sqlx::query_as!(
P,
"SELECT id, time, difficulty_factor, worker_type FROM survey_mcaptcha_analytics
WHERE
campaign_id = (
SELECT
ID FROM survey_mcaptcha_campaign
WHERE
public_id = $1
)
ORDER BY ID
OFFSET $2 LIMIT $3
",
&public_id_str,
offset as i32,
limit as i32
)
.fetch_all(&self.db)
.await?;
let mut res = Vec::with_capacity(c.len());
for i in c.drain(0..) {
res.push(i.into())
}
Ok(res)
}
pub async fn get_next_job_to_run(&self) -> ServiceResult<Option<SchedulerJob>> {
let res = match sqlx::query_as!(
InnerSchedulerJob,
"SELECT
survey_mcaptcha_campaign.campaign_id,
survey_mcaptcha_upload_jobs.public_id,
survey_mcaptcha_hostname.url
FROM
survey_mcaptcha_campaign
INNER JOIN
survey_mcaptcha_upload_jobs
ON
survey_mcaptcha_upload_jobs.campaign_id = survey_mcaptcha_campaign.ID
INNER JOIN
survey_mcaptcha_hostname
ON
survey_mcaptcha_hostname.ID = survey_mcaptcha_campaign.url_id
WHERE
survey_mcaptcha_upload_jobs.job_state = (
SELECT ID FROM survey_mcaptcha_upload_job_states WHERE name = $1
)
AND
survey_mcaptcha_upload_jobs.finished_at is NULL
AND
survey_mcaptcha_upload_jobs.scheduled_at is NULL
ORDER BY created_at ASC;",
&JOB_STATE_CREATE.name
)
.fetch_one(&self.db)
.await
{
Ok(res) => Ok(Some(res.into())),
Err(sqlx::Error::RowNotFound) => Ok(None),
Err(e) => Err(e),
}?;
Ok(res)
}
pub async fn add_job(&self, campaign_id: &Uuid) -> ServiceResult<Uuid> {
let now = now_unix_time_stamp();
if let Some(unfinished_job) =
self.get_unfinished_job_for_campaign(campaign_id).await?
{
return Ok(unfinished_job.public_job_id);
}
let public_id = Uuid::new_v4();
let public_id_str = public_id.to_string();
let campaign_str = campaign_id.to_string();
sqlx::query!(
"INSERT INTO survey_mcaptcha_upload_jobs
(campaign_id, job_state, created_at, public_id)
VALUES (
(SELECT ID FROM survey_mcaptcha_campaign WHERE campaign_id = $1),
(SELECT ID FROM survey_mcaptcha_upload_job_states WHERE name = $2),
$3, $4)",
&campaign_str,
&JOB_STATE_CREATE.name,
now,
public_id_str
)
.execute(&self.db)
.await?;
Ok(public_id)
}
pub async fn get_unfinished_job_for_campaign(
&self,
campaign_id: &Uuid,
) -> ServiceResult<Option<Job>> {
let res = match sqlx::query_as!(
InnerJob,
"
SELECT
survey_mcaptcha_upload_jobs.ID,
survey_mcaptcha_upload_jobs.public_id,
survey_mcaptcha_campaign.campaign_id,
survey_mcaptcha_campaign.public_id as campaign_public_id,
survey_mcaptcha_upload_job_states.name,
survey_mcaptcha_upload_jobs.created_at,
survey_mcaptcha_upload_jobs.scheduled_at,
survey_mcaptcha_upload_jobs.finished_at
FROM survey_mcaptcha_upload_jobs
INNER JOIN
survey_mcaptcha_upload_job_states
ON
survey_mcaptcha_upload_job_states.ID = survey_mcaptcha_upload_jobs.job_state
INNER JOIN
survey_mcaptcha_campaign
ON
survey_mcaptcha_campaign.ID = survey_mcaptcha_upload_jobs.campaign_id
WHERE
survey_mcaptcha_campaign.campaign_id = $1
AND
survey_mcaptcha_upload_job_states.name = $2;",
&campaign_id.to_string(),
&JOB_STATE_CREATE.name
)
.fetch_one(&self.db)
.await {
Ok(res) => Ok(Some(res.into())),
Err(sqlx::Error::RowNotFound) => Ok(None),
Err(e) => Err(e),
}?;
Ok(res)
}
pub async fn get_job(&self, public_id: &uuid::Uuid) -> ServiceResult<Option<Job>> {
let res = match sqlx::query_as!(
InnerJob,
"
SELECT
survey_mcaptcha_upload_jobs.ID,
survey_mcaptcha_upload_jobs.public_id,
survey_mcaptcha_campaign.campaign_id,
survey_mcaptcha_campaign.public_id as campaign_public_id,
survey_mcaptcha_upload_job_states.name,
survey_mcaptcha_upload_jobs.created_at,
survey_mcaptcha_upload_jobs.scheduled_at,
survey_mcaptcha_upload_jobs.finished_at
FROM survey_mcaptcha_upload_jobs
INNER JOIN
survey_mcaptcha_upload_job_states
ON
survey_mcaptcha_upload_job_states.ID = survey_mcaptcha_upload_jobs.job_state
INNER JOIN
survey_mcaptcha_campaign
ON
survey_mcaptcha_campaign.ID = survey_mcaptcha_upload_jobs.campaign_id
WHERE
survey_mcaptcha_upload_jobs.public_id = $1",
&public_id.to_string()
)
.fetch_one(&self.db)
.await {
Ok(res) => Ok(Some(res.into())),
Err(sqlx::Error::RowNotFound) => Ok(None),
Err(e) => Err(e),
}?;
Ok(res)
}
pub async fn get_all_jobs_of_state(
&self,
state: &JobState,
) -> ServiceResult<Vec<Job>> {
let mut res = sqlx::query_as!(
InnerJob,
"
SELECT
survey_mcaptcha_upload_jobs.ID,
survey_mcaptcha_upload_jobs.public_id,
survey_mcaptcha_campaign.campaign_id,
survey_mcaptcha_campaign.public_id as campaign_public_id,
survey_mcaptcha_upload_job_states.name,
survey_mcaptcha_upload_jobs.created_at,
survey_mcaptcha_upload_jobs.scheduled_at,
survey_mcaptcha_upload_jobs.finished_at
FROM survey_mcaptcha_upload_jobs
INNER JOIN
survey_mcaptcha_upload_job_states
ON
survey_mcaptcha_upload_job_states.ID = survey_mcaptcha_upload_jobs.job_state
INNER JOIN
survey_mcaptcha_campaign
ON
survey_mcaptcha_campaign.ID = survey_mcaptcha_upload_jobs.campaign_id
WHERE
survey_mcaptcha_upload_job_states.name = $1;",
&state.name
)
.fetch_all(&self.db)
.await?;
let res = res.drain(0..).map(|r| r.into()).collect();
Ok(res)
}
pub async fn mark_job_scheduled(&self, job: &SchedulerJob) -> ServiceResult<()> {
let now = now_unix_time_stamp();
sqlx::query!(
"
UPDATE
survey_mcaptcha_upload_jobs
SET
job_state = (SELECT ID FROM survey_mcaptcha_upload_job_states WHERE name = $1),
scheduled_at = $2
WHERE public_id = $3;",
&JOB_STATE_RUNNING.name,
now,
&job.public_job_id.to_string(),
)
.execute(&self.db)
.await
?;
Ok(())
}
pub async fn mark_job_finished(&self, job: &SchedulerJob) -> ServiceResult<()> {
let now = now_unix_time_stamp();
sqlx::query!(
"
UPDATE
survey_mcaptcha_upload_jobs
SET
job_state = (SELECT ID FROM survey_mcaptcha_upload_job_states WHERE name = $1),
finished_at = $2
WHERE public_id = $3;",
&JOB_STATE_FINISH.name,
now,
&job.public_job_id.to_string(),
)
.execute(&self.db)
.await
?;
Ok(())
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct SchedulerJob {
pub campaign_id: Uuid,
pub public_job_id: Uuid,
pub url: Url,
}
#[derive(Clone, Debug, PartialEq, Eq)]
struct InnerSchedulerJob {
campaign_id: String,
public_id: String,
url: String,
}
impl From<InnerSchedulerJob> for SchedulerJob {
fn from(j: InnerSchedulerJob) -> Self {
SchedulerJob {
campaign_id: Uuid::parse_str(&j.campaign_id).unwrap(),
public_job_id: Uuid::parse_str(&j.public_id).unwrap(),
url: Url::parse(&j.url).unwrap(),
}
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Job {
pub state: JobState,
pub campaign_id: Uuid,
pub campaign_public_id: Uuid,
pub public_job_id: Uuid,
pub id: u32,
pub created_at: OffsetDateTime,
pub scheduled_at: Option<OffsetDateTime>,
pub finished_at: Option<OffsetDateTime>,
}
struct InnerJob {
name: String,
campaign_id: String,
public_id: String,
campaign_public_id: String,
id: i32,
created_at: OffsetDateTime,
scheduled_at: Option<OffsetDateTime>,
finished_at: Option<OffsetDateTime>,
}
impl From<InnerJob> for Job {
fn from(j: InnerJob) -> Self {
Job {
state: (JOB_STATES)
.iter()
.find(|d| d.name == j.name)
.unwrap()
.to_owned()
.to_owned(),
id: j.id as u32,
created_at: j.created_at,
scheduled_at: j.scheduled_at,
finished_at: j.finished_at,
campaign_id: Uuid::parse_str(&j.campaign_id).unwrap(),
campaign_public_id: Uuid::parse_str(&j.campaign_public_id).unwrap(),
public_job_id: Uuid::parse_str(&j.public_id).unwrap(),
}
}
}
#[cfg(test)]
mod tests {
use crate::{mcaptcha::PerformanceAnalytics, tests::*};
use super::*;
use url::Url;
#[actix_rt::test]
async fn test_db_mcaptcha_works() {
let url = Url::parse("http://test_add_campaign.example").unwrap();
let data = get_test_data().await;
let url_str = url.to_string();
if data.mcaptcha_url_exists(&url_str).await.unwrap() {
let secret = data.mcaptcha_update_secret(&url_str).await.unwrap();
data.mcaptcha_delete_mcaptcha_instance(&url_str, &secret)
.await
.unwrap();
}
assert!(!data.mcaptcha_url_exists(&url_str).await.unwrap());
let secret = data.mcaptcha_register_instance(&url_str).await.unwrap();
assert!(data.mcaptcha_url_exists(&url_str).await.unwrap());
let secret2 = data.mcaptcha_update_secret(&url_str).await.unwrap();
assert_ne!(secret2, secret);
let secret = secret2;
assert!(data.mcaptcha_authenticate(&secret).await.is_ok());
assert_eq!(
data.mcaptcha_authenticate("foo").await.err(),
Some(ServiceError::WrongPassword)
);
let uuid = Uuid::new_v4();
if data
.mcaptcha_campaign_is_registered(&uuid, &secret)
.await
.unwrap()
{
data.mcaptcha_delete_mcaptcha_campaign(&uuid, &secret)
.await
.unwrap();
}
assert!(!data
.mcaptcha_campaign_is_registered(&uuid, &secret)
.await
.unwrap());
data.mcaptcha_register_campaign(&uuid, &secret)
.await
.unwrap();
assert!(data
.mcaptcha_campaign_is_registered(&uuid, &secret)
.await
.unwrap());
assert_eq!(data.mcaptcha_get_checkpoint(&uuid).await.unwrap(), 0);
data.mcaptcha_set_checkpoint(&uuid, 1).await.unwrap();
assert_eq!(data.mcaptcha_get_checkpoint(&uuid).await.unwrap(), 1);
let analytics = PerformanceAnalytics {
id: 1,
time: 1,
difficulty_factor: 1,
worker_type: "foo".to_string(),
};
data.mcaptcha_insert_analytics(&uuid, &analytics)
.await
.unwrap();
let public_id = data
.mcaptcha_get_campaign_public_id(&uuid, &secret)
.await
.unwrap();
let db_analytics = data
.mcaptcha_analytics_fetch(&public_id, 50, 0)
.await
.unwrap();
assert_eq!(db_analytics.len(), 1);
assert_eq!(db_analytics[0].time, analytics.time);
assert_eq!(
db_analytics[0].difficulty_factor,
analytics.difficulty_factor
);
assert_eq!(db_analytics[0].worker_type, analytics.worker_type);
assert_eq!(
data.mcaptcha_analytics_fetch(&public_id, 50, 1)
.await
.unwrap(),
vec![]
);
// job related stuff
let job1_public_id = data.add_job(&uuid).await.unwrap();
let job = data.get_job(&job1_public_id).await.unwrap().unwrap();
assert_eq!(public_id, job.campaign_public_id);
assert_eq!(
data.get_unfinished_job_for_campaign(&uuid)
.await
.unwrap()
.unwrap(),
job
);
let job2_public_id = data.add_job(&uuid).await.unwrap();
let job2 = data.get_job(&job2_public_id).await.unwrap().unwrap();
assert_eq!(job2, job);
let scheduler_job = data.get_next_job_to_run().await.unwrap().unwrap();
assert_eq!(scheduler_job.url, url);
assert_eq!(
data.get_next_job_to_run()
.await
.unwrap()
.unwrap()
.public_job_id,
job.public_job_id
);
assert!(job.created_at < now_unix_time_stamp());
assert!(job.scheduled_at.is_none());
assert!(job.finished_at.is_none());
assert_eq!(
data.get_all_jobs_of_state(&JOB_STATE_CREATE).await.unwrap(),
vec![job.clone()]
);
data.mark_job_scheduled(&scheduler_job).await.unwrap();
assert!(data.get_next_job_to_run().await.unwrap().is_none(),);
let job = data.get_job(&job.public_job_id).await.unwrap().unwrap();
assert!(job.scheduled_at.is_some());
assert_eq!(
data.get_all_jobs_of_state(&JOB_STATE_RUNNING)
.await
.unwrap(),
vec![job.clone()]
);
data.mark_job_finished(&scheduler_job).await.unwrap();
let job = data.get_job(&job.public_job_id).await.unwrap().unwrap();
assert!(job.finished_at.is_some());
assert_eq!(
data.get_all_jobs_of_state(&JOB_STATE_FINISH).await.unwrap(),
vec![job.clone()]
);
let job2_public_id = data.add_job(&uuid).await.unwrap();
let job2 = data.get_job(&job2_public_id).await.unwrap().unwrap();
assert_ne!(job2.public_job_id, job.public_job_id);
assert_eq!(
data.get_next_job_to_run()
.await
.unwrap()
.unwrap()
.public_job_id,
job2.public_job_id
);
assert_eq!(public_id, job2.campaign_public_id);
}
}

View file

@ -0,0 +1,260 @@
// Copyright (C) 2023 Aravinth Manivannan <realaravinth@batsense.net>
// SPDX-FileCopyrightText: 2023 Aravinth Manivannan <realaravinth@batsense.net>
//
// SPDX-License-Identifier: AGPL-3.0-or-later
use actix_web::web::ServiceConfig;
use actix_web::{web, HttpResponse, Responder};
use serde::{Deserialize, Serialize};
use url::Url;
use uuid::Uuid;
use crate::api::v1::ROUTES;
use crate::errors::*;
use crate::AppData;
pub fn services(cfg: &mut ServiceConfig) {
cfg.service(register);
cfg.service(upload);
cfg.service(download);
}
#[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq)]
pub struct MCaptchaInstance {
pub url: Url,
pub auth_token: String,
}
#[actix_web_codegen_const_routes::post(path = "ROUTES.mcaptcha.register")]
async fn register(
data: AppData,
payload: web::Json<MCaptchaInstance>,
) -> ServiceResult<impl Responder> {
/* Summary
* 1. Check if secret exists
* 2. If not, add hostname and create secret
* 3. Post to mCaptcha
*/
let url_str = payload.url.to_string();
let secret = if data.mcaptcha_url_exists(&url_str).await? {
data.mcaptcha_update_secret(&url_str).await?
} else {
data.mcaptcha_register_instance(&url_str).await?
};
let payload = payload.into_inner();
data.mcaptcha
.share_secret(payload.url, secret, payload.auth_token)
.await?;
Ok(HttpResponse::Ok())
}
#[derive(Deserialize, Serialize, Debug, Eq, PartialEq, Clone)]
pub struct UploadJobCreated {
id: Uuid,
}
#[derive(Debug, Clone, Default, Deserialize, Serialize, PartialEq)]
pub struct Secret {
pub secret: String,
}
#[actix_web_codegen_const_routes::post(path = "ROUTES.mcaptcha.upload")]
async fn upload(
data: AppData,
campaign: web::Path<uuid::Uuid>,
payload: web::Json<Secret>,
) -> ServiceResult<impl Responder> {
/* TODO
* 1. Authenticate: Get URL from secret
* 2. Check if campaign exists
* 3. If not: create campaign
* 4. Get last known sync point
* 5. Download results
* 6. Update sync point
*/
data.mcaptcha_authenticate(&payload.secret).await?;
// let campaign_str = campaign.to_string();
if !data
.mcaptcha_campaign_is_registered(&campaign, &payload.secret)
.await?
{
data.mcaptcha_register_campaign(&campaign, &payload.secret)
.await?;
}
let res = UploadJobCreated {
id: data.add_job(&campaign).await?,
};
Ok(HttpResponse::Created().json(res))
}
#[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq)]
pub struct Page {
pub page: usize,
}
#[actix_web_codegen_const_routes::get(path = "ROUTES.mcaptcha.download")]
async fn download(
data: AppData,
page: web::Query<Page>,
public_id: web::Path<uuid::Uuid>,
) -> ServiceResult<impl Responder> {
const LIMIT: usize = 50;
let offset = LIMIT as isize * ((page.page as isize) - 1);
let offset = if offset < 0 { 0 } else { offset };
let public_id = public_id.into_inner();
let resp = data
.mcaptcha_analytics_fetch(&public_id, LIMIT, offset as usize)
.await?;
Ok(HttpResponse::Ok().json(resp))
}
#[cfg(test)]
mod tests {
use super::Secret;
use crate::api::v1::get_random;
use crate::mcaptcha::PerformanceAnalytics;
use crate::tests::*;
use crate::*;
use actix_web::test;
#[actix_rt::test]
async fn mcaptcha_hooks_work() {
let mcaptcha_instance =
url::Url::parse("http://mcaptcha_hooks_work.example.org").unwrap();
let mcaptcha_instance_str = mcaptcha_instance.to_string();
let campaign_id = uuid::Uuid::new_v4();
let (data, client) = get_test_data_with_mcaptcha_client().await;
let app = get_app!(data).await;
let mcaptcha_downloader =
crate::mcaptcha::MCaptchaDownloader::new(AppData::new(data.clone()));
let (mcaptcha_downloader_killer, mcaptcha_downloader_job) =
mcaptcha_downloader.start_job().await.unwrap();
if data
.mcaptcha_url_exists(&mcaptcha_instance_str)
.await
.unwrap()
{
let secret = data
.mcaptcha_update_secret(&mcaptcha_instance_str)
.await
.unwrap();
data.mcaptcha_delete_mcaptcha_instance(&mcaptcha_instance_str, &secret)
.await
.unwrap();
}
let payload = super::MCaptchaInstance {
url: mcaptcha_instance.clone(),
auth_token: get_random(23),
};
let resp = test::call_service(
&app,
post_request!(&payload, V1_API_ROUTES.mcaptcha.register).to_request(),
)
.await;
assert_eq!(resp.status(), StatusCode::OK);
let secret = {
let mut mcaptcha = payload.url.clone();
mcaptcha.set_path("/api/v1/survey/secret");
let mut x = client.client.write().unwrap();
x.remove(&mcaptcha.to_string()).unwrap()
};
let resp2 = test::call_service(
&app,
post_request!(&payload, V1_API_ROUTES.mcaptcha.register).to_request(),
)
.await;
assert_eq!(resp2.status(), StatusCode::OK);
let secret2 = {
let mut mcaptcha = payload.url.clone();
mcaptcha.set_path("/api/v1/survey/secret");
let mut x = client.client.write().unwrap();
x.remove(&mcaptcha.to_string()).unwrap()
};
assert_ne!(secret, secret2);
let secret = secret2;
let payload = Secret {
secret: secret.clone(),
};
if data
.mcaptcha_campaign_is_registered(&campaign_id, &secret)
.await
.unwrap()
{
data.mcaptcha_delete_mcaptcha_campaign(&campaign_id, &secret)
.await
.unwrap();
}
let resp = test::call_service(
&app,
post_request!(
&payload,
&V1_API_ROUTES
.mcaptcha
.get_upload_route(&campaign_id.to_string())
)
.to_request(),
)
.await;
assert_eq!(resp.status(), StatusCode::CREATED);
let job: super::UploadJobCreated = test::read_body_json(resp).await;
loop {
if let Some(job) = data.get_job(&job.id).await.unwrap() {
if job.state == *crate::db::JOB_STATE_FINISH {
break;
}
}
tokio::time::sleep(std::time::Duration::new(1, 0)).await;
}
let public_id = data
.mcaptcha_get_campaign_public_id(&campaign_id, &secret)
.await
.unwrap();
let expected = crate::mcaptcha::tests::BENCHMARK.clone();
let got = data
.mcaptcha_analytics_fetch(&public_id, 50, 0)
.await
.unwrap();
for i in 0..2 {
assert_eq!(got[i].time, expected[i].time);
assert_eq!(got[i].difficulty_factor, expected[i].difficulty_factor);
assert_eq!(got[i].worker_type, expected[i].worker_type);
}
let resp = get_request!(
&app,
&V1_API_ROUTES
.mcaptcha
.get_download_route(&public_id.to_string(), 0)
);
assert_eq!(resp.status(), StatusCode::OK);
let resp: Vec<PerformanceAnalytics> = test::read_body_json(resp).await;
assert_eq!(resp.len(), 2);
assert_eq!(resp, got);
mcaptcha_downloader_killer.send(()).unwrap();
mcaptcha_downloader_job.await.unwrap();
}
}

View file

@ -0,0 +1,46 @@
// Copyright (C) 2023 Aravinth Manivannan <realaravinth@batsense.net>
// SPDX-FileCopyrightText: 2023 Aravinth Manivannan <realaravinth@batsense.net>
//
// SPDX-License-Identifier: AGPL-3.0-or-later
use actix_web::web::ServiceConfig;
pub mod db;
pub mod hooks;
pub fn services(cfg: &mut ServiceConfig) {
hooks::services(cfg);
}
pub mod routes {
use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
pub struct Mcaptcha {
pub upload: &'static str,
pub download: &'static str,
pub register: &'static str,
}
impl Mcaptcha {
pub const fn new() -> Self {
Self {
register: "/mcaptcha/api/v1/register",
upload: "/mcaptcha/api/v1/{campaign_id}/upload",
download: "/mcapthca/api/v1/{campaign_id}/download",
}
}
pub fn get_download_route(&self, campaign_id: &str, page: usize) -> String {
format!(
"{}?page={}",
self.download.replace("{campaign_id}", campaign_id),
page
)
}
pub fn get_upload_route(&self, campaign_id: &str) -> String {
self.upload.replace("{campaign_id}", campaign_id)
}
}
}

View file

@ -1,19 +1,7 @@
/*
* Copyright (C) 2021 Aravinth Manivannan <realaravinth@batsense.net>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
// Copyright (C) 2021 Aravinth Manivannan <realaravinth@batsense.net>
// SPDX-FileCopyrightText: 2023 Aravinth Manivannan <realaravinth@batsense.net>
//
// SPDX-License-Identifier: AGPL-3.0-or-later
use actix_web::{web, HttpResponse, Responder};
use derive_builder::Builder;

View file

@ -1,33 +1,26 @@
/*
* Copyright (C) 2021 Aravinth Manivannan <realaravinth@batsense.net>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
// Copyright (C) 2021 Aravinth Manivannan <realaravinth@batsense.net>
// SPDX-FileCopyrightText: 2023 Aravinth Manivannan <realaravinth@batsense.net>
//
// SPDX-License-Identifier: AGPL-3.0-or-later
use actix_web::web::ServiceConfig;
use serde::Deserialize;
use uuid::Uuid;
use sqlx::types::Uuid;
pub mod admin;
pub mod bench;
pub mod mcaptcha;
mod meta;
pub mod routes;
pub mod stats;
pub use routes::ROUTES;
pub fn services(cfg: &mut ServiceConfig) {
meta::services(cfg);
bench::services(cfg);
admin::services(cfg);
mcaptcha::services(cfg);
stats::services(cfg);
}
pub fn get_random(len: usize) -> String {
@ -44,7 +37,7 @@ pub fn get_random(len: usize) -> String {
}
pub fn get_uuid() -> Uuid {
Uuid::new_v4()
Uuid::parse_str(&uuid::Uuid::new_v4().to_string()).unwrap()
}
#[derive(Deserialize)]

View file

@ -1,24 +1,15 @@
/*
* Copyright (C) 2021 Aravinth Manivannan <realaravinth@batsense.net>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
// Copyright (C) 2021 Aravinth Manivannan <realaravinth@batsense.net>
// SPDX-FileCopyrightText: 2023 Aravinth Manivannan <realaravinth@batsense.net>
//
// SPDX-License-Identifier: AGPL-3.0-or-later
use serde::Serialize;
use super::admin::routes::Admin;
use super::bench::routes::Benches;
use super::mcaptcha::routes::Mcaptcha;
use super::meta::routes::Meta;
use super::stats::routes::Stats;
pub const ROUTES: Routes = Routes::new();
@ -27,6 +18,8 @@ pub struct Routes {
pub admin: Admin,
pub meta: Meta,
pub benches: Benches,
pub mcaptcha: Mcaptcha,
pub stats: Stats,
}
impl Routes {
@ -35,6 +28,8 @@ impl Routes {
admin: Admin::new(),
meta: Meta::new(),
benches: Benches::new(),
mcaptcha: Mcaptcha::new(),
stats: Stats::new(),
}
}
}

256
src/api/v1/stats.rs Normal file
View file

@ -0,0 +1,256 @@
// Copyright (C) 2021 Aravinth Manivannan <realaravinth@batsense.net>
// SPDX-FileCopyrightText: 2023 Aravinth Manivannan <realaravinth@batsense.net>
//
// SPDX-License-Identifier: AGPL-3.0-or-later
use actix_web::{web, HttpResponse, Responder};
use derive_builder::Builder;
use serde::{Deserialize, Serialize};
use crate::errors::*;
use crate::AppData;
#[derive(Clone, Debug, Deserialize, Builder, Serialize)]
pub struct BuildDetails {
pub version: &'static str,
pub git_commit_hash: &'static str,
}
pub mod routes {
use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
pub struct Stats {
pub percentile_benches: &'static str,
}
impl Stats {
pub const fn new() -> Self {
Self {
percentile_benches: "/api/v1/stats/benches/percentile",
}
}
}
}
/// Get difficulty factor with max time limit for percentile of stats
#[actix_web_codegen_const_routes::post(
path = "crate::V1_API_ROUTES.stats.percentile_benches"
)]
async fn percentile_benches(
data: AppData,
payload: web::Json<PercentileReq>,
) -> ServiceResult<impl Responder> {
struct Count {
count: Option<i64>,
}
let count = sqlx::query_as!(
Count,
"SELECT COUNT(difficulty) FROM survey_benches WHERE duration <= $1;",
payload.time as f32
)
.fetch_one(&data.db)
.await?;
if count.count.is_none() {
return Ok(HttpResponse::Ok().json(PercentileResp {
difficulty_factor: None,
}));
}
let count = count.count.unwrap();
if count < 2 {
return Ok(HttpResponse::Ok().json(PercentileResp {
difficulty_factor: None,
}));
}
let location = ((count - 1) as f64 * (payload.percentile / 100.00)) + 1.00;
let fraction = location - location.floor();
async fn get_data_at_location(
data: &crate::Data,
time: u32,
location: i64,
) -> ServiceResult<Option<u32>> {
struct Difficulty {
difficulty: Option<i32>,
}
match sqlx::query_as!(
Difficulty,
"SELECT
difficulty
FROM
survey_benches
WHERE
duration <= $1
ORDER BY difficulty ASC LIMIT 1 OFFSET $2;",
time as f32,
location as i64 - 1,
)
.fetch_one(&data.db)
.await
{
Ok(res) => Ok(Some(res.difficulty.unwrap() as u32)),
Err(sqlx::Error::RowNotFound) => Ok(None),
Err(e) => Err(e.into()),
}
}
if fraction > 0.00 {
if let (Some(base), Some(ceiling)) = (
get_data_at_location(&data, payload.time, location.floor() as i64).await?,
get_data_at_location(&data, payload.time, location.floor() as i64 + 1)
.await?,
) {
let res = base as u32 + ((ceiling - base) as f64 * fraction).floor() as u32;
return Ok(HttpResponse::Ok().json(PercentileResp {
difficulty_factor: Some(res),
}));
}
} else {
if let Some(base) =
get_data_at_location(&data, payload.time, location.floor() as i64).await?
{
let res = base as u32;
return Ok(HttpResponse::Ok().json(PercentileResp {
difficulty_factor: Some(res),
}));
}
};
Ok(HttpResponse::Ok().json(PercentileResp {
difficulty_factor: None,
}))
}
#[derive(Clone, Debug, Deserialize, Builder, Serialize)]
/// Health check return datatype
pub struct PercentileReq {
time: u32,
percentile: f64,
}
#[derive(Clone, Debug, Deserialize, Builder, Serialize)]
/// Health check return datatype
pub struct PercentileResp {
difficulty_factor: Option<u32>,
}
pub fn services(cfg: &mut web::ServiceConfig) {
cfg.service(percentile_benches);
}
#[cfg(test)]
mod tests {
use actix_web::{http::StatusCode, test, App};
use super::*;
use crate::api::v1::services;
use crate::tests::get_test_data;
use crate::*;
#[actix_rt::test]
async fn stats_bench_work() {
use crate::tests::*;
const NAME: &str = "benchstatsuesr";
const EMAIL: &str = "benchstatsuesr@testadminuser.com";
const PASSWORD: &str = "longpassword2";
const DEVICE_USER_PROVIDED: &str = "foo";
const DEVICE_SOFTWARE_RECOGNISED: &str = "Foobar.v2";
const THREADS: i32 = 4;
let data = get_test_data().await;
{
delete_user(NAME, &data).await;
}
let (creds, signin_resp) =
register_and_signin(&data, NAME, EMAIL, PASSWORD).await;
let cookies = get_cookie!(signin_resp);
let app = get_app!(data).await;
let survey = get_survey_user(data.clone()).await;
let survey_cookie = get_cookie!(survey);
let campaign = create_new_campaign(NAME, data.clone(), cookies.clone()).await;
let campaign_config =
get_campaign_config(&campaign, data.clone(), survey_cookie.clone()).await;
assert_eq!(DIFFICULTIES.to_vec(), campaign_config.difficulties);
let submit_payload = crate::api::v1::bench::Submission {
device_user_provided: DEVICE_USER_PROVIDED.into(),
device_software_recognised: DEVICE_SOFTWARE_RECOGNISED.into(),
threads: THREADS,
benches: BENCHES.clone(),
submission_type: crate::api::v1::bench::SubmissionType::Wasm,
};
submit_bench(&submit_payload, &campaign, survey_cookie, data.clone()).await;
let msg = PercentileReq {
time: 1,
percentile: 99.00,
};
let resp = test::call_service(
&app,
post_request!(&msg, V1_API_ROUTES.stats.percentile_benches).to_request(),
)
.await;
assert_eq!(resp.status(), StatusCode::OK);
let resp: PercentileResp = test::read_body_json(resp).await;
assert!(resp.difficulty_factor.is_none());
let msg = PercentileReq {
time: 1,
percentile: 100.00,
};
let resp = test::call_service(
&app,
post_request!(&msg, V1_API_ROUTES.stats.percentile_benches).to_request(),
)
.await;
assert_eq!(resp.status(), StatusCode::OK);
let resp: PercentileResp = test::read_body_json(resp).await;
assert!(resp.difficulty_factor.is_none());
let msg = PercentileReq {
time: 2,
percentile: 100.00,
};
let resp = test::call_service(
&app,
post_request!(&msg, V1_API_ROUTES.stats.percentile_benches).to_request(),
)
.await;
assert_eq!(resp.status(), StatusCode::OK);
let resp: PercentileResp = test::read_body_json(resp).await;
assert_eq!(resp.difficulty_factor.unwrap(), 2);
let msg = PercentileReq {
time: 5,
percentile: 90.00,
};
let resp = test::call_service(
&app,
post_request!(&msg, V1_API_ROUTES.stats.percentile_benches).to_request(),
)
.await;
assert_eq!(resp.status(), StatusCode::OK);
let resp: PercentileResp = test::read_body_json(resp).await;
assert_eq!(resp.difficulty_factor.unwrap(), 4);
delete_user(NAME, &data).await;
}
}

423
src/archive.rs Normal file
View file

@ -0,0 +1,423 @@
// Copyright (C) 2023 Aravinth Manivannan <realaravinth@batsense.net>
// SPDX-FileCopyrightText: 2023 Aravinth Manivannan <realaravinth@batsense.net>
//
// SPDX-License-Identifier: AGPL-3.0-or-later
use std::path::{Path, PathBuf};
use serde::{Deserialize, Serialize};
use sqlx::types::time::OffsetDateTime;
use sqlx::types::Uuid;
use tokio::fs;
use tokio::io::AsyncWriteExt;
use tokio::sync::oneshot::{self, error::TryRecvError, Sender};
use tokio::task::JoinHandle;
use crate::api::v1::admin::campaigns::runners::get_results;
use crate::api::v1::admin::campaigns::SurveyResponse;
use crate::{errors::ServiceResult, AppData, Settings};
const CAMPAIGN_INFO_FILE: &str = "campaign.json";
const BENCHMARK_FILE: &str = "benchmark.csv";
pub struct Archiver {
base_path: String,
}
pub struct Archive {
now: i64,
base_path: String,
campaign: Uuid,
}
impl Archive {
pub fn new(campaign: Uuid, base_path: String) -> Self {
let now = OffsetDateTime::now_utc().unix_timestamp();
Self {
now,
campaign,
base_path,
}
}
fn campaign_path(&self) -> PathBuf {
Path::new(&self.base_path).join(&self.campaign.to_string())
}
fn archive_path_now(&self) -> PathBuf {
self.campaign_path().join(self.now.to_string())
}
fn campaign_file_path(&self) -> PathBuf {
self.archive_path_now().join(CAMPAIGN_INFO_FILE)
}
fn benchmark_file_path(&self) -> PathBuf {
self.archive_path_now().join(BENCHMARK_FILE)
}
}
impl Archiver {
pub fn new(s: &Settings) -> Self {
Archiver {
base_path: s.publish.dir.clone(),
}
}
async fn create_dir_util(p: &PathBuf) -> ServiceResult<()> {
if p.exists() {
if !p.is_dir() {
fs::remove_file(&p).await.unwrap();
fs::create_dir_all(&p).await.unwrap();
}
} else {
fs::create_dir_all(&p).await.unwrap();
}
Ok(())
}
async fn write_campaign_file(&self, c: &Campaign, a: &Archive) -> ServiceResult<()> {
let archive_path = a.archive_path_now();
Self::create_dir_util(&archive_path).await?;
let campaign_file_path = a.campaign_file_path();
let contents = serde_json::to_string(c).unwrap();
// fs::write(campaign_file_path, contents).await.unwrap();
let mut file = fs::File::create(&campaign_file_path).await.unwrap();
file.write_all(contents.as_bytes()).await.unwrap();
file.flush().await.unwrap();
Ok(())
}
fn get_headers(c: &Campaign) -> Vec<String> {
let mut keys = vec![
"ID".to_string(),
"user".to_string(),
"device_user_provided".to_string(),
"device_software_recognised".to_string(),
"threads".to_string(),
"submitted_at".to_string(),
"submission_type".to_string(),
];
let mut diff_order = Vec::with_capacity(c.difficulties.len());
for d in c.difficulties.iter() {
diff_order.push(d);
keys.push(format!("Difficulty {}", d));
}
keys
}
fn extract_record(c: &Campaign, r: SurveyResponse) -> Vec<String> {
let mut rec = vec![
r.id.to_string(),
r.user.id.to_string(),
r.device_user_provided,
r.device_software_recognised,
r.threads.map_or_else(|| "-".into(), |v| v.to_string()),
r.submitted_at.to_string(),
r.submission_type.to_string(),
];
for d in c.difficulties.iter() {
let bench = r
.benches
.iter()
.find(|b| b.difficulty == *d as i32)
.map_or_else(|| "-".into(), |v| v.duration.to_string());
rec.push(bench);
}
rec
}
async fn write_benchmark_file(
&self,
c: &Campaign,
archive: &Archive,
data: &AppData,
) -> ServiceResult<()> {
let archive_path = archive.archive_path_now();
Self::create_dir_util(&archive_path).await?;
let benchmark_file_path = archive.benchmark_file_path();
struct Username {
name: String,
}
let owner = sqlx::query_as!(
Username,
"SELECT
survey_admins.name
FROM
survey_admins
INNER JOIN survey_campaigns ON
survey_admins.ID = survey_campaigns.user_id
WHERE
survey_campaigns.ID = $1
",
&Uuid::parse_str(&c.id.to_string()).unwrap()
)
.fetch_one(&data.db)
.await?;
let mut page = 0;
let limit = 50;
let file = fs::OpenOptions::new()
.read(true)
.append(true)
.create(true)
.open(&benchmark_file_path)
.await
.unwrap();
let mut wri = csv_async::AsyncWriter::from_writer(file);
let keys = Self::get_headers(c);
wri.write_record(&keys).await.unwrap();
loop {
let mut resp = get_results(
&owner.name,
&Uuid::parse_str(&c.id.to_string()).unwrap(),
data,
page,
limit,
None,
)
.await?;
for r in resp.drain(0..) {
let rec = Self::extract_record(c, r);
wri.write_record(&rec).await.unwrap();
wri.flush().await.unwrap();
}
if resp.len() < limit {
break;
} else {
page += 1
}
}
Ok(())
}
pub async fn init_archive_job(
self,
data: AppData,
) -> ServiceResult<(Sender<bool>, JoinHandle<()>)> {
let (tx, mut rx) = oneshot::channel();
fn can_run(rx: &mut oneshot::Receiver<bool>) -> bool {
match rx.try_recv() {
Err(TryRecvError::Empty) => true,
_ => false,
}
}
let job = async move {
loop {
if !can_run(&mut rx) {
log::info!("Killing archive loop: received signal");
break;
}
for _ in 0..data.settings.publish.duration {
if !can_run(&mut rx) {
log::info!("Killing archive loop: received signal");
break;
}
tokio::time::sleep(std::time::Duration::new(1, 0)).await;
}
let _ = self.archive(&data).await;
}
};
let job_fut = tokio::spawn(job);
Ok((tx, job_fut))
}
pub async fn archive(&self, data: &AppData) -> ServiceResult<()> {
let mut db_campaigns = sqlx::query_as!(
InnerCampaign,
"SELECT ID, name, difficulties, created_at FROM survey_campaigns"
)
.fetch_all(&data.db)
.await?;
for c in db_campaigns.drain(0..) {
let archive = Archive::new(c.id.clone(), self.base_path.clone());
let campaign: Campaign = c.into();
self.write_campaign_file(&campaign, &archive).await?;
self.write_benchmark_file(&campaign, &archive, data).await?;
}
Ok(())
}
}
#[derive(Clone, Debug, Eq, PartialEq)]
struct InnerCampaign {
id: Uuid,
name: String,
difficulties: Vec<i32>,
created_at: OffsetDateTime,
}
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
pub struct Campaign {
pub id: uuid::Uuid,
pub name: String,
pub difficulties: Vec<u32>,
pub created_at: i64,
}
impl From<InnerCampaign> for Campaign {
fn from(i: InnerCampaign) -> Self {
Self {
id: uuid::Uuid::parse_str(&i.id.to_string()).unwrap(),
name: i.name,
difficulties: i.difficulties.iter().map(|d| *d as u32).collect(),
created_at: i.created_at.unix_timestamp(),
}
}
}
#[cfg(test)]
mod tests {
use std::str::FromStr;
use csv_async::StringRecord;
use futures::stream::StreamExt;
use crate::api::v1::bench::Submission;
use crate::api::v1::bench::SubmissionType;
use crate::*;
use super::*;
use mktemp::Temp;
#[test]
fn archive_path_works() {
let mut settings = Settings::new().unwrap();
let tmp_dir = Temp::new_dir().unwrap();
settings.publish.dir = tmp_dir.join("base_path").to_str().unwrap().into();
let uuid = Uuid::new_v4();
let archive = Archive::new(uuid.clone(), settings.publish.dir.clone());
let archive_path = archive.archive_path_now();
assert_eq!(
archive_path,
Path::new(&settings.publish.dir)
.join(&uuid.to_string())
.join(&archive.now.to_string())
);
let campaign_file_path = archive.campaign_file_path();
assert_eq!(
campaign_file_path,
Path::new(&settings.publish.dir)
.join(&uuid.to_string())
.join(&archive.now.to_string())
.join(CAMPAIGN_INFO_FILE)
);
let benchmark_file_path = archive.benchmark_file_path();
assert_eq!(
benchmark_file_path,
Path::new(&settings.publish.dir)
.join(&uuid.to_string())
.join(&archive.now.to_string())
.join(BENCHMARK_FILE)
);
}
#[actix_rt::test]
async fn archive_is_correct_test() {
use crate::tests::*;
const NAME: &str = "arciscorrecttesuser";
const EMAIL: &str = "archive_is_correct_testuser@testadminuser.com";
const PASSWORD: &str = "longpassword2";
const DEVICE_USER_PROVIDED: &str = "foo";
const DEVICE_SOFTWARE_RECOGNISED: &str = "Foobar.v2";
const THREADS: i32 = 4;
let data = get_test_data().await;
{
delete_user(NAME, &data).await;
}
//let campaign: Campaign = c.into();
//let archive = Archive::new(campaign.id.clone(), self.base_path.clone());
//self.write_campaign_file(&campaign, &archive).await?;
//self.write_benchmark_file(&campaign, &archive, data).await?;
let (creds, signin_resp) =
register_and_signin(&data, NAME, EMAIL, PASSWORD).await;
let cookies = get_cookie!(signin_resp);
let survey = get_survey_user(data.clone()).await;
let survey_cookie = get_cookie!(survey);
let campaign = create_new_campaign(NAME, data.clone(), cookies.clone()).await;
let campaign_config =
get_campaign_config(&campaign, data.clone(), survey_cookie.clone()).await;
assert_eq!(DIFFICULTIES.to_vec(), campaign_config.difficulties);
let submit_payload = Submission {
device_user_provided: DEVICE_USER_PROVIDED.into(),
device_software_recognised: DEVICE_SOFTWARE_RECOGNISED.into(),
threads: THREADS,
benches: BENCHES.clone(),
submission_type: SubmissionType::Wasm,
};
let _proof =
submit_bench(&submit_payload, &campaign, survey_cookie, data.clone()).await;
let campaign_id = Uuid::from_str(&campaign.campaign_id).unwrap();
let db_campaign = sqlx::query_as!(
InnerCampaign,
"SELECT ID, name, difficulties, created_at FROM survey_campaigns WHERE ID = $1",
campaign_id,
)
.fetch_one(&data.db)
.await.unwrap();
let campaign: Campaign = db_campaign.into();
let archive = Archive::new(
Uuid::parse_str(&campaign.id.to_string()).unwrap(),
data.settings.publish.dir.clone(),
);
let archiver = Archiver::new(&data.settings);
archiver.archive(&AppData::new(data.clone())).await.unwrap();
let contents: Campaign = serde_json::from_str(
&fs::read_to_string(&archive.campaign_file_path())
.await
.unwrap(),
)
.unwrap();
assert_eq!(contents, campaign);
let page = 0;
let limit = 10;
let mut responses = get_results(
NAME,
&campaign_id,
&AppData::new(data.clone()),
page,
limit,
None,
)
.await
.unwrap();
assert_eq!(responses.len(), 1);
let r = responses.pop().unwrap();
let rec = Archiver::extract_record(&campaign, r);
let mut rdr = csv_async::AsyncReader::from_reader(
fs::File::open(archive.benchmark_file_path()).await.unwrap(),
);
let mut records = rdr.records();
assert_eq!(
records.next().await.unwrap().unwrap(),
StringRecord::from(rec)
);
}
}

View file

@ -0,0 +1,3 @@
SPDX-FileCopyrightText: 2023 Aravinth Manivannan <realaravinth@batsense.net>
SPDX-License-Identifier: AGPL-3.0-or-later

View file

@ -1,19 +1,8 @@
/*
* Copyright (C) 2021 Aravinth Manivannan <realaravinth@batsense.net>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
// Copyright (C) 2021 Aravinth Manivannan <realaravinth@batsense.net>
// SPDX-FileCopyrightText: 2023 Aravinth Manivannan <realaravinth@batsense.net>
//
// SPDX-License-Identifier: AGPL-3.0-or-later
//! App data: database connections, etc.
use std::sync::Arc;
use std::thread;
@ -22,6 +11,7 @@ use argon2_creds::{Config, ConfigBuilder, PasswordPolicy};
use sqlx::postgres::PgPoolOptions;
use sqlx::PgPool;
use crate::mcaptcha::*;
use crate::settings::Settings;
/// App data
@ -30,6 +20,8 @@ pub struct Data {
pub db: PgPool,
pub creds: Config,
pub settings: Settings,
pub mcaptcha: Box<dyn MCaptchaClient>,
}
impl Data {
@ -45,7 +37,10 @@ impl Data {
#[cfg(not(tarpaulin_include))]
/// create new instance of app data
pub async fn new(settings: Settings) -> Arc<Self> {
pub async fn new(
settings: Settings,
mcaptcha: Box<dyn MCaptchaClient>,
) -> Arc<Self> {
let creds = Self::get_creds();
let c = creds.clone();
#[allow(unused_variables)]
@ -67,6 +62,7 @@ impl Data {
db,
creds,
settings,
mcaptcha,
};
Arc::new(data)

91
src/db.rs Normal file
View file

@ -0,0 +1,91 @@
// SPDX-FileCopyrightText: 2023 Aravinth Manivannan <realaravinth@batsense.net>
//
// SPDX-License-Identifier: AGPL-3.0-or-later
use lazy_static::lazy_static;
use serde::{Deserialize, Serialize};
use sqlx::PgPool;
#[derive(Deserialize, Serialize, Clone, Debug, Eq, PartialEq)]
pub struct JobState {
pub name: String,
}
impl JobState {
pub fn new(name: String) -> Self {
Self { name }
}
}
lazy_static! {
pub static ref JOB_STATE_CREATE: JobState = JobState::new("job.state.create".into());
pub static ref JOB_STATE_FINISH: JobState = JobState::new("job.state.finish".into());
pub static ref JOB_STATE_RUNNING: JobState =
JobState::new("job.state.running".into());
pub static ref JOB_STATES: [&'static JobState; 3] =
[&*JOB_STATE_CREATE, &*JOB_STATE_FINISH, &*JOB_STATE_RUNNING];
}
async fn job_state_exists(
db: &PgPool,
job_state: &JobState,
) -> sqlx::error::Result<bool> {
let res = sqlx::query!(
"SELECT EXISTS (SELECT 1 from survey_mcaptcha_upload_job_states WHERE name = $1)",
job_state.name,
)
.fetch_one(db)
.await?;
let mut resp = false;
if let Some(x) = res.exists {
resp = x;
}
Ok(resp)
}
async fn create_job_states(db: &PgPool) -> sqlx::error::Result<()> {
for j in &*JOB_STATES {
if !job_state_exists(db, j).await? {
sqlx::query!(
"INSERT INTO survey_mcaptcha_upload_job_states
(name) VALUES ($1) ON CONFLICT (name) DO NOTHING;",
j.name
)
.execute(db)
.await?;
}
}
Ok(())
}
pub async fn migrate_db(db: &PgPool) -> sqlx::error::Result<()> {
sqlx::migrate!("./migrations/").run(db).await?;
create_job_states(db).await?;
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
#[actix_rt::test]
async fn test_mcaptcha_job_states_exist() {
// can't use crate::tests::get_test_data because this module is used by
// ./src/tests-migrate.rs too, which doesn't load tests module
let settings = crate::settings::Settings::new().unwrap();
let db = sqlx::postgres::PgPoolOptions::new()
.max_connections(2)
.connect(&settings.database.url)
.await
.expect("Unable to form database pool");
migrate_db(&db).await.unwrap();
for e in (*JOB_STATES).iter() {
println!("checking job state {}", e.name);
assert!(job_state_exists(&db, e).await.unwrap());
}
}
}

View file

@ -1,19 +1,8 @@
/*
* Copyright (C) 2021 Aravinth Manivannan <realaravinth@batsense.net>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
// Copyright (C) 2021 Aravinth Manivannan <realaravinth@batsense.net>
// SPDX-FileCopyrightText: 2023 Aravinth Manivannan <realaravinth@batsense.net>
//
// SPDX-License-Identifier: AGPL-3.0-or-later
use std::convert::From;
use argon2_creds::errors::CredsError;

View file

@ -1,22 +1,12 @@
/*
* Copyright (C) 2021 Aravinth Manivannan <realaravinth@batsense.net>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
// Copyright (C) 2021 Aravinth Manivannan <realaravinth@batsense.net>
// SPDX-FileCopyrightText: 2023 Aravinth Manivannan <realaravinth@batsense.net>
//
// SPDX-License-Identifier: AGPL-3.0-or-later
use std::env;
use std::sync::Arc;
use actix_files::Files;
use actix_identity::{CookieIdentityPolicy, IdentityService};
use actix_session::{storage::CookieSessionStore, SessionMiddleware};
use actix_web::{
@ -27,8 +17,11 @@ use lazy_static::lazy_static;
use log::info;
mod api;
mod archive;
mod data;
mod db;
mod errors;
mod mcaptcha;
mod pages;
mod settings;
mod static_assets;
@ -56,6 +49,8 @@ lazy_static! {
FILES.get("./static/cache/bundle/glue.js").unwrap();
}
pub const DOWNLOAD_SCOPE: &str = "/download";
pub const CACHE_AGE: u32 = 604800;
pub const COMPILED_DATE: &str = env!("COMPILED_DATE");
@ -70,7 +65,9 @@ pub type AppData = actix_web::web::Data<Arc<crate::data::Data>>;
#[cfg(not(tarpaulin_include))]
#[actix_web::main]
async fn main() -> std::io::Result<()> {
env::set_var("RUST_LOG", "info");
if env::var("RUST_LOG").is_err() {
env::set_var("RUST_LOG", "info");
}
pretty_env_logger::init();
@ -80,10 +77,21 @@ async fn main() -> std::io::Result<()> {
);
let settings = Settings::new().unwrap();
let data = Data::new(settings.clone()).await;
sqlx::migrate!("./migrations/").run(&data.db).await.unwrap();
let mcaptcha: Box<dyn mcaptcha::MCaptchaClient> =
Box::new(mcaptcha::MCaptchaClientReqwest::default());
let data = Data::new(settings.clone(), mcaptcha).await;
db::migrate_db(&data.db).await.unwrap();
let data = actix_web::web::Data::new(data);
let arch = archive::Archiver::new(&data.settings);
let (archive_kiler, archive_job) =
arch.init_archive_job(data.clone()).await.unwrap();
let mcaptcha_downloader = mcaptcha::MCaptchaDownloader::new(data.clone());
let (mcaptcha_downloader_killer, mcaptcha_downloader_job) =
mcaptcha_downloader.start_job().await.unwrap();
let ip = settings.server.get_ip();
println!("Starting server on: http://{}", ip);
@ -101,6 +109,9 @@ async fn main() -> std::io::Result<()> {
.wrap(actix_middleware::NormalizePath::new(
actix_middleware::TrailingSlash::Trim,
))
.service(
Files::new(DOWNLOAD_SCOPE, &settings.publish.dir).show_files_listing(),
)
.configure(services)
.app_data(data.clone())
})
@ -108,6 +119,12 @@ async fn main() -> std::io::Result<()> {
.unwrap()
.run()
.await
.unwrap();
let _ = mcaptcha_downloader_killer.send(());
let _ = archive_kiler.send(true);
let _ = tokio::join!(archive_job, mcaptcha_downloader_job);
Ok(())
}
#[cfg(not(tarpaulin_include))]

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