Compare commits

...

291 Commits

Author SHA1 Message Date
Kainoa Kanter 832ccc3e88
Update README.md 2023-09-05 14:49:43 -07:00
Kainoa Kanter 1677032f4e
Merge pull request #72 from idanoo/main 2023-05-01 13:07:15 -07:00
Daniel Mason 9c245cf827 Remove paste.m2.nz from instance list 2023-05-01 08:59:57 +00:00
Kainoa Kanter ac1f4cf33a
Merge pull request #69 from hatkidchan/fix-68-layout
Switched from e.key to e.code, fixes #68
2023-01-16 08:58:27 -08:00
hkc 90d1966779
Switched from e.key to e.code, fixes #68 2023-01-16 14:26:04 +03:00
Kainoa Kanter f0a3670913
Update README.md 2022-09-23 11:19:45 -07:00
Kainoa Kanter 81e5a3f7a8
Merge pull request #65 from pupbrained/patch-2
Update Domain in README
2022-09-22 21:41:02 -07:00
Mars e7c96047cf
Update Domain in README 2022-09-23 03:10:26 +00:00
Kainoa Kanter e2037f7522
Merge pull request #64 from idanoo/update_domain
Update domain/config in README.md
2022-09-11 20:35:52 -07:00
idanoo 7eb63190f0 Update link in README.md 2022-09-12 13:56:04 +12:00
Kainoa Kanter 82d2087281
Update README.md 2022-07-19 21:28:56 -07:00
Kainoa Kanter 5e77dcf43b
Update README.md 2022-07-19 21:27:52 -07:00
mellowmarshe db0d09bad7
Merge pull request #61 from auguwu/env-var-subsitution 2022-05-15 21:55:52 -04:00
Noel 0c78b83b30
remove full path from vite config 2022-05-15 18:51:32 -07:00
Noel 6e8e2b119a
Merge branch 'env-var-subsitution' of https://github.com/auguwu/zer0bin into env-var-subsitution 2022-05-15 18:49:22 -07:00
Noel 479354fe2c
remove .env 2022-05-15 18:49:18 -07:00
Noel 75de8c53e3
Merge branch 'zer0bin-dev:main' into env-var-subsitution 2022-05-15 18:48:20 -07:00
Noel e9e18e3501
add environment variable subsitution with `.env` files and system env 2022-05-15 18:47:07 -07:00
domterion de58aa84c2 Remove single_view from schema.sql, migrator will create this 2022-05-16 00:30:14 +00:00
ThatOneCalculator fd6b91977b refactor: ♻️ Comments to pug 2022-04-08 08:47:18 -07:00
ThatOneCalculator 0050ea2fb9 Merge branch 'main' of https://github.com/zer0bin-dev/zer0bin 2022-04-08 08:11:28 -07:00
ThatOneCalculator 5bb8c3441b refactor: ♻️ Config to TS 2022-04-08 08:11:16 -07:00
Kainoa Kanter 3ee8b85213
docs: 🤓 Free font option 2022-04-07 22:27:37 -07:00
ThatOneCalculator 535530c34f feat: Add free font option 2022-04-07 22:23:04 -07:00
ThatOneCalculator 21ec4c1ef0 perf: Add vite-plugin-compression for gzip 2022-04-07 19:35:47 -07:00
ThatOneCalculator d683701360 perf: Remove all fonts except woff2 2022-04-07 19:32:31 -07:00
ThatOneCalculator 0e1bb82944 fix: 🐛 Add lang to html 2022-04-07 19:30:39 -07:00
ThatOneCalculator f1ccf6a836 fix: 🐛 Metadata 2022-04-07 19:28:25 -07:00
ThatOneCalculator fa07222803 fix: 🐛 Favicon 2022-04-07 19:20:48 -07:00
ThatOneCalculator 3cfda99765 fix: 🐛 Favicon 2022-04-07 19:15:31 -07:00
ThatOneCalculator d96287c206 fix: Lighthouse accesibility 2022-04-07 19:15:11 -07:00
mellowmarshe 1146f4b7da
Merge pull request #60 from zer0bin-dev/vite 2022-04-07 21:08:04 -04:00
Kainoa Kanter 7be6aa6cf2
deps: 🔥 remove parcel 2022-04-07 17:54:51 -07:00
ThatOneCalculator 6f55b59d7b build: 🏗️ Switch to Vite for build system 2022-04-07 17:49:34 -07:00
ThatOneCalculator 9ff53c1345 Merge branch 'main' of https://github.com/zer0bin-dev/zer0bin 2022-04-04 12:14:40 -07:00
ThatOneCalculator f001286f5b refactor: 💄 Share button to top bar 2022-04-04 12:14:25 -07:00
Kainoa Kanter b03ca2c8f7
docs: 📝 Fix broken links on button illusts 2022-04-04 12:04:22 -07:00
ThatOneCalculator 648b6aac4e feat: Share button = copy to clipboard if no sharenav 2022-04-04 11:59:26 -07:00
ThatOneCalculator fff67c1a43 feat: Share button 2022-04-04 11:49:03 -07:00
ThatOneCalculator 4f62e7f4ee feat: 🚧 Share button 2022-04-04 11:34:08 -07:00
Kainoa Kanter 8ad0b5790d
🔖 v1.1.1 2022-04-04 11:05:51 -07:00
ThatOneCalculator 6ee88465fa feat: 🔖 v1.1.1
Upgrade deps
2022-04-04 10:42:04 -07:00
Dominic Harris 36e81a6c4f
🐛 fix: Fix migrator 2022-04-04 13:37:35 -04:00
Kainoa Kanter 794403ae97
docs: 📝 Make keybinds bullet points 2022-04-04 09:50:04 -07:00
ThatOneCalculator ead9d9108e refactor: 🚧 Use built in migrator (WIP) 2022-04-04 09:35:50 -07:00
ThatOneCalculator be7617476f refactor: ♻️ Still use extraSVGAttrs with new method 2022-04-04 00:40:19 -07:00
ThatOneCalculator bbccfc4314 refactor: ♻️ Render icon method 2022-04-04 00:35:27 -07:00
ThatOneCalculator a2b6392b03 refactor: 🎨 Pug formatting 2022-04-04 00:22:17 -07:00
ThatOneCalculator 407a4997f6 fix: 🥚 Add `.htmlnanorc` for comments 2022-04-04 00:18:27 -07:00
ThatOneCalculator 0081ddeafa feat: 🥚 Inspect element suprise 2022-04-04 00:13:07 -07:00
ThatOneCalculator ee5e9a1ca3 feat: Markdown mode keybind (Ctrl + M) 2022-04-03 23:56:38 -07:00
ThatOneCalculator 667e00b894 fix: 🐛 Disable markdown button when viewing paste 2022-04-03 23:44:57 -07:00
ThatOneCalculator 8d6e3b6378 feat: 💄 Fade for hiding and colors 2022-04-03 23:43:06 -07:00
ThatOneCalculator bd718fadde refactor: ♻️ use `toggle()` for changing classes 2022-04-03 23:33:28 -07:00
Kainoa Kanter 44e996c60d docs: 📝 Improve features section 2022-04-03 23:24:22 -07:00
ThatOneCalculator 18e2ba0200 fix: 🗃️ Seperate schema and migrations 2022-04-03 23:06:11 -07:00
ThatOneCalculator 70c84ebaba fix: ✏️ Func capitalization 2022-04-03 22:44:59 -07:00
ThatOneCalculator abeebd045f fix: ✏️ Typo in migration 2022-04-03 22:41:53 -07:00
ThatOneCalculator a2b3104c08 refactor: 🗃️ Migrations to lc 2022-04-03 22:39:26 -07:00
ThatOneCalculator 3eb141ec72 refactor: 🎨 Make editor.value var 2022-04-03 22:28:38 -07:00
ThatOneCalculator cbd21b6bb2 feat: Markdown button 2022-04-03 22:26:32 -07:00
ThatOneCalculator 5fe090c302 fix: 🥅 Catch migration error 2022-04-03 22:11:56 -07:00
ThatOneCalculator 35004d8f0f feat: ⚗️ migrations 2022-04-03 21:55:29 -07:00
ThatOneCalculator fa78dd4246 fix: 🔥 Remove fire animation until parcel is fixed 2022-04-03 20:03:15 -07:00
ThatOneCalculator 1bd6d3721a fix: ⚗️ Try secondary calc 2022-04-03 19:37:13 -07:00
ThatOneCalculator d260e338f5 style: ⚗️ Try `math.div()` 2022-04-03 19:36:19 -07:00
ThatOneCalculator 658538fd61 build: ⬆️ Upgrade parcel 2022-04-03 19:34:20 -07:00
ThatOneCalculator 67f753c0d6 fix: ⚗️ Test CSS fix 2022-04-03 19:33:37 -07:00
ThatOneCalculator 4a921a947e fix: 💄 Particle animation 2022-04-03 19:11:39 -07:00
ThatOneCalculator d543cfc154 feat: 🔊 Alert user if single view 2022-04-03 19:09:05 -07:00
ThatOneCalculator 5021a3df8d fix: 🚨 Remove `/` for division outside of `calc()` 2022-04-03 19:04:04 -07:00
Kainoa Kanter 4fad42ff6a
Merge pull request #49 from zer0bin-dev/single-view-pastes 2022-04-03 19:00:08 -07:00
ThatOneCalculator 95d45b09d6 feat: 🔖 v1.1.0 2022-04-03 18:56:09 -07:00
ThatOneCalculator 9a2ccf73c3 feat: Single view paste icon 2022-04-03 18:54:18 -07:00
Dominic Harris a78713c24a
🐛 fix: Add lang to html 2022-03-28 15:19:03 -04:00
Dominic Harris f3e135df46
feature: A little less padding on button wrapper 2022-03-28 13:48:11 -04:00
Dominic Harris f2eb61fa0e
feature: Rounded corners 2022-03-28 09:30:00 -04:00
Dominic Harris 0e0e6daf8f
feature: Single view pastes works on the frontend 2022-03-27 15:21:54 -04:00
mellowmarshe 51f3293279
Merge pull request #47 from zer0bin-dev/main
Merge upstream single-view-pastes
2022-03-26 09:08:25 -04:00
Dominic Harris 871dcc5c38
feature: Single view pastes work on the backend 2022-03-26 08:37:07 -04:00
Dominic Harris c179f8bf90
feature: svp 2022-03-26 08:19:15 -04:00
Dominic Harris dc5c178152
♻️ refactor: Remove useless API call 2022-03-25 21:25:03 -04:00
Kainoa Kanter 1b4da8955d
deps: 📦 Move parcel to dev deps 2022-03-25 16:07:44 -07:00
Kainoa Kanter e11a496e8c
refactor: Further minify highlight.js 2022-03-25 15:27:01 -07:00
ThatOneCalculator fb81db3add feat: Custom highlight.js 2022-03-25 15:19:17 -07:00
Kainoa Kanter 113287e5dc
Merge pull request #45 from zer0bin-dev/hide-button 2022-03-25 14:41:37 -07:00
ThatOneCalculator 202cb98c39 refactor: Cut bundle size by almost 600kb 2022-03-25 14:39:43 -07:00
Dominic Harris 161662c4de
♻️ refactor: Add display: none defaults where sensible 2022-03-25 08:38:28 -04:00
Dominic Harris 77340f763c
♻️ refactor: Change tooltip text size 2022-03-24 19:46:29 -04:00
Dominic Harris c8a46307b8
♻️ refactor: Some css tings 2022-03-24 19:34:35 -04:00
Dominic Harris b983bc352f
feature: Okay should be good now 2022-03-24 18:10:15 -04:00
Dominic Harris 788235d411
feature: Add hide button 2022-03-24 17:58:08 -04:00
ThatOneCalculator 297042ab0e release: 🔖 v1.0.2 2022-03-24 07:11:17 -07:00
Dominic Harris 6bc1e8c421
feature: Raw endpoint is back! 2022-03-24 09:19:52 -04:00
ThatOneCalculator fb4b814e0a fix: 💄 Fix spacing on viewing markdown pastes 2022-03-23 23:27:27 -07:00
ThatOneCalculator f57312e308 release: 🔖 v1.0.1 2022-03-23 18:38:49 -07:00
Kainoa Kanter fd3334ea7c
config: ⚙ Change caching rules 2022-03-23 18:36:56 -07:00
Kainoa Kanter 024feb777a
community: 🫂 Improve contributing guidelines 2022-03-23 18:34:17 -07:00
Kainoa Kanter 92cbc3f49e
docs: 📝 Add self hosting 2022-03-23 18:29:29 -07:00
Dominic Harris 9b8fcbd757 release: 🔖 v1.0.0 2022-03-23 17:48:28 -07:00
Kainoa Kanter bc59fc6359
docs: 📝 Add CLI client link 2022-03-23 17:11:19 -07:00
Kainoa Kanter e863421fae
fix: 🐛 Fix `md` with newline 2022-03-23 15:53:06 -07:00
Kainoa Kanter 807aa1f516
config: ⚙ gzip_static if no brotli 2022-03-23 15:44:16 -07:00
ThatOneCalculator 40f2d7a578 chore: 📦 Update package.json 2022-03-23 15:34:35 -07:00
ThatOneCalculator 02f91b3f8d fix: ✏️ Typo 2022-03-23 13:27:15 -07:00
Kainoa Kanter 30cc4c3890
docs: 📝 Markdown feature spec 2022-03-23 12:44:27 -07:00
Kainoa Kanter 525a254531
feat: Also check for `md ` to start markdown 2022-03-23 12:42:29 -07:00
Kainoa Kanter 4e25416f80
docs: 📝 Emojis for features 2022-03-23 12:29:06 -07:00
Kainoa Kanter e9db6c2c7b
docs: 📝 Mention mobile UI 2022-03-23 12:23:20 -07:00
ThatOneCalculator a5a9620efd Merge branch 'main' of https://github.com/zer0bin-dev/zer0bin 2022-03-23 12:14:24 -07:00
ThatOneCalculator 2f1dd15048 fix: 🐛 Fixes #41 2022-03-23 12:14:15 -07:00
Kainoa Kanter f844f5f4ae
docs: 📝 Add more features to list 2022-03-23 12:00:25 -07:00
Kainoa Kanter 062f0c8b22
feat: Markdown rendering 2022-03-23 11:56:39 -07:00
Kainoa Kanter f468e12125
docs: 📝 Marked icon 2022-03-23 11:49:43 -07:00
ThatOneCalculator bfc3825d15 Merge branch 'main' of https://github.com/zer0bin-dev/zer0bin 2022-03-23 11:45:38 -07:00
ThatOneCalculator 397479b13c fix: 🐛 Don't render initial `---` for markdown 2022-03-23 11:45:28 -07:00
Kainoa Kanter 921fc40916
docs: 📝 Features section 2022-03-23 11:42:58 -07:00
ThatOneCalculator dbfed7a7dc fix: 💄 Hide line numbers when viewing markdown 2022-03-23 11:36:50 -07:00
ThatOneCalculator 4ed5065bef fix: 🐛 Fix marked import 2022-03-23 11:34:44 -07:00
ThatOneCalculator 1ffb3abdfd test: ⚗️ Debug test of Markdown 2022-03-23 11:29:19 -07:00
ThatOneCalculator f35b619619 fix: 🐛 Fonts to local 2022-03-23 11:27:25 -07:00
ThatOneCalculator cc65f2fe78 Merge branch 'main' of https://github.com/zer0bin-dev/zer0bin 2022-03-23 11:16:19 -07:00
ThatOneCalculator 7505d619ea feat: ⚗️ Markdown 2022-03-23 11:16:11 -07:00
Kainoa Kanter fa05a899db
docs: 📝 Cartograph CF Icon 2022-03-23 10:55:51 -07:00
Kainoa Kanter aab7682760
docs: 📝 Improve rust badge maker icon 2022-03-23 10:36:33 -07:00
Kainoa Kanter 0408c5f023
docs: 📝 Badge maker badge 2022-03-23 10:33:30 -07:00
ThatOneCalculator a90250dcec Merge branch 'main' of https://github.com/zer0bin-dev/zer0bin 2022-03-23 10:21:56 -07:00
ThatOneCalculator 46cb4de1ef docs: 📝 Instance badges 2022-03-23 10:21:48 -07:00
Kainoa Kanter 36d648b8b5
Merge pull request #39 from zer0bin-dev/badges 2022-03-23 10:16:04 -07:00
ThatOneCalculator 94e282b039 Merge conflict 2022-03-23 10:15:32 -07:00
ThatOneCalculator 6235dfa6ab style: Total pastes label is rose 2022-03-23 10:10:16 -07:00
ThatOneCalculator fd84b62cbd feat: Total pastes badge 2022-03-23 10:08:18 -07:00
ThatOneCalculator 619b327ec2 Merge branch 'badges' of https://github.com/zer0bin-dev/zer0bin into badges 2022-03-23 09:54:25 -07:00
ThatOneCalculator f77fdbf850 feat: Fix label color 2022-03-23 09:54:14 -07:00
Dominic Harris 15e376c3d9
♻️ refactor: Remove useless statements 2022-03-23 12:53:08 -04:00
Dominic Harris 50581c022b
feature: Work on badges 2022-03-23 12:47:00 -04:00
ThatOneCalculator 63c20b56bc docs: 📝 Change technology used icons 2022-03-23 09:34:50 -07:00
Kainoa Kanter 083a2a8de9
docs: 📝 Update icon badges 2022-03-23 09:27:59 -07:00
Kainoa Kanter ab0c21fd9f
docs: 📝 Fix Wiki badge 2022-03-22 18:12:12 -07:00
ThatOneCalculator 9b4eed484a docs: 📝 Wiki badge 2022-03-22 18:11:08 -07:00
ThatOneCalculator 5ff0cef35e dep: 📦 Rebase parcel 2022-03-22 17:21:58 -07:00
ThatOneCalculator dbd5ce3eeb fix: 🔥 Remove yarn.lock 2022-03-22 16:42:31 -07:00
ThatOneCalculator 2bc96946f5 fix: 🐛 Fix Parcel build and imports 2022-03-22 16:30:30 -07:00
ThatOneCalculator 2b69f8a615 fix: 🚑 Fix parcel 2022-03-22 16:27:35 -07:00
ThatOneCalculator 02ca472369 fix: ⬇️ Force parcel to 2.3.2 2022-03-22 16:20:13 -07:00
ThatOneCalculator fa29569ba1 fix: 🚑 Fix style import for icons 2022-03-22 16:05:33 -07:00
ThatOneCalculator 8013d12a21 fix: 🐛 Properly parse confetti chance 2022-03-22 15:59:14 -07:00
ThatOneCalculator 50ecb91151 feat: Add back frontend config 2022-03-22 15:40:01 -07:00
Kainoa Kanter 294b50150f
docs: 📝 Update Wiki link 2022-03-22 15:32:50 -07:00
Kainoa Kanter 22639a244d
docs: 📝 Wiki 2022-03-22 15:32:25 -07:00
Kainoa Kanter 597fd3663b
tyop: ✏ Typo in readme 2022-03-22 15:30:41 -07:00
Kainoa Kanter 41e290102c
docs: 📝 Wiki 2022-03-22 15:29:56 -07:00
ThatOneCalculator 973e7a91f6 fix: No more frontend config 2022-03-22 15:19:12 -07:00
ThatOneCalculator e9c4842719 feat: 🚧 Badges 2022-03-22 14:37:53 -07:00
ThatOneCalculator 5948dcfda5 feat: Customizable confetti chance 2022-03-22 13:55:18 -07:00
Kainoa Kanter e6a4341976 docs: 📝 Update benchmarks 💪 2022-03-22 13:39:55 -07:00
Kainoa Kanter 5056a83225
deps: 📦 Update parcel to 2.4.0 2022-03-22 13:31:15 -07:00
ThatOneCalculator 01cffc24d5 style: 🎨 Clean up tooltip code 2022-03-22 13:27:41 -07:00
ThatOneCalculator 21c25dce94 fix: 🐛 Closes #37 2022-03-22 13:23:47 -07:00
ThatOneCalculator b1e792472b fix: Foreach 2022-03-22 13:22:51 -07:00
ThatOneCalculator e4183c9070 test: 🧪 Modify querySelectorAll 2022-03-22 13:21:08 -07:00
ThatOneCalculator 331abc7c8d debug: 🐛 Log each button 2022-03-22 13:19:59 -07:00
ThatOneCalculator 0610f5bba2 test: 🧪 Check for attributes 2022-03-22 13:18:23 -07:00
ThatOneCalculator 6ec8b47cfb test: 🧪 MutationObserver 2022-03-22 13:16:59 -07:00
ThatOneCalculator db834b108f test: 🧪 Popstate 2022-03-22 13:12:57 -07:00
ThatOneCalculator 08352498c8 debug: 🧪 Log theme 2022-03-22 13:07:25 -07:00
ThatOneCalculator 82cb6ff2e5 fix: 🐛 Close #37 2022-03-22 13:05:21 -07:00
ThatOneCalculator 8621c29c9d fix: Tooltip style applies on new paste 2022-03-22 12:20:25 -07:00
ThatOneCalculator 918068f0be fix: 🐛 Tooltips respect popstatea 2022-03-22 12:18:52 -07:00
ThatOneCalculator 4184901345 fix: 💄 Dynamic tooltip positions 2022-03-22 12:15:12 -07:00
ThatOneCalculator 2a8a4c3ac5 fix: 💄 Dynamic tooltip positions 2022-03-22 12:12:27 -07:00
ThatOneCalculator 7f33ae0327 fix: 💄 Fix tooltip positioning 2022-03-22 11:49:43 -07:00
ThatOneCalculator 2155c90bc4 build: 📦 Update packages 2022-03-22 11:41:21 -07:00
Kainoa Kanter 1867dde1f2
config: ⚙ Update default nginx config 2022-03-22 11:36:18 -07:00
Kainoa Kanter 77eebaa42f
docs: 📝 Update Conventional Commits icon 2022-03-22 11:32:47 -07:00
Kainoa Kanter 49aaa073ab
config: ⚙ Change default config 2022-03-22 09:55:09 -07:00
ThatOneCalculator a7b149f26e feat: Block DarkReader 2022-03-22 09:46:25 -07:00
Dominic Harris 30a843c390
📝 doc: Add official zer0bin instance 2022-03-22 11:59:00 -04:00
Kainoa Kanter 4c618f9486
community: 🫂 Update public instance template 2022-03-21 23:45:27 -07:00
Kainoa Kanter b6476606f8
docs: 📝 Add tinker.nz as instance
Closes #35
2022-03-21 23:43:05 -07:00
Daniel Mason ed45574c84 fix: ✏️ Typo in issue template 3 2022-03-21 21:13:21 -07:00
Kainoa Kanter b99e63b018
docs: 📝 (Somewhat) uniform logo colors 2022-03-21 19:40:01 -07:00
Dominic Harris 7333afcbd6 fix: 📦 Cargo lock 2022-03-21 19:18:50 -07:00
ThatOneCalculator bbf6cfeada fix: 💄 Tooltip padding 2022-03-21 19:15:36 -07:00
ThatOneCalculator 2844749225 fix: 💄 Use variable instead of hardcoded 2022-03-21 18:31:15 -07:00
ThatOneCalculator f70de0e290 style: 🎨 SCSS variable 2022-03-21 18:22:36 -07:00
ThatOneCalculator b8e4c56c10 style: 💄 Move tooltip down 2022-03-21 18:18:50 -07:00
ThatOneCalculator 7c5db6ab7c fix: ✏️ Typo in tooltip 2022-03-21 18:14:57 -07:00
ThatOneCalculator eaddc25def feat: 🔖 v0.7.1 2022-03-21 18:12:17 -07:00
ThatOneCalculator fc9ad79149 style: 💄 Icons for GitHub tooltip 2022-03-21 18:09:28 -07:00
ThatOneCalculator b63251206b feat: Keybind to duplicate paste 2022-03-21 17:58:58 -07:00
ThatOneCalculator 868b9c45be feat: Add keybinds to tooltips 2022-03-21 17:56:28 -07:00
ThatOneCalculator 44700e686e build: 🔖 Upgrade package.json version 2022-03-21 17:50:40 -07:00
ThatOneCalculator be2e0ad5c2 style: 💄 Clean up SCSS 2022-03-21 17:49:57 -07:00
ThatOneCalculator a66540ca5a refactor: 💄 CSS -> SCSS 2022-03-21 17:45:44 -07:00
Kainoa Kanter fcbfc52347
docs: 📝 Prepare for zer0b.in launch 2022-03-21 17:42:57 -07:00
Kainoa Kanter af28ceae14
docs: 📝 Add tippy icon 2022-03-21 17:34:30 -07:00
ThatOneCalculator e9041ff13d feat: Close #27: Tooltips 2022-03-21 17:23:33 -07:00
ThatOneCalculator ac440256c4 style: 💄 Change mobile block opacity 2022-03-21 16:49:30 -07:00
ThatOneCalculator a1a83f4665 style: 💄 Logo opacity on mobile 2022-03-21 16:48:10 -07:00
ThatOneCalculator 7394cd4ba7 fix: 💄 Typo 2022-03-21 16:46:02 -07:00
ThatOneCalculator a51a23d772 style: 💄 Make logo on mobile have greater opacity 2022-03-21 16:45:06 -07:00
ThatOneCalculator edd1e98a86 fix: 💄 Make editor have mono font 2022-03-21 16:42:35 -07:00
ThatOneCalculator 67fb649b02 Fix #29 2022-03-21 16:41:02 -07:00
ThatOneCalculator 38b58bf08c Merge branch 'main' of https://github.com/Domterion/zer0bin 2022-03-21 16:37:03 -07:00
ThatOneCalculator 173b42ebe7 Fix #28 2022-03-21 16:36:56 -07:00
Kainoa Kanter c9f38fbde1
docs: 📝 Update JSConfetti icon 🎉 2022-03-21 16:30:42 -07:00
ThatOneCalculator bae89b7899 fix: 🐛 Fix copy button 2022-03-21 16:18:37 -07:00
Dominic Harris ec20eb89e3 dep: 📦 Update Serde 2022-03-20 20:28:12 -07:00
Kainoa Kanter 1c92c9104d
formatting: 🔥 2022-03-20 16:40:41 -07:00
Kainoa Kanter 131616e9be
docs: 📝 Update badge label color 2022-03-19 20:20:12 -07:00
Kainoa Kanter 8d39df0ec2
docs: 📝 Add release badge 2022-03-19 20:19:14 -07:00
Kainoa Kanter 32842c0053
refactor: ♻ Clean up Prettier config 2022-03-19 20:14:59 -07:00
Kainoa Kanter 07a8d8cbdb
docs: 📝 Fix oversized icon 2022-03-19 19:41:24 -07:00
Kainoa Kanter e538e85d96 community: 🫂 Improve issue template 3 2022-03-19 19:39:23 -07:00
ThatOneCalculator be183807cc docs: 📝 Improve phrasing in Code of Conduct 2022-03-19 19:36:07 -07:00
ThatOneCalculator dfe25ee031 Merge branch 'main' of https://github.com/Domterion/zer0bin 2022-03-19 19:35:08 -07:00
ThatOneCalculator 3c6db18596 docs: 📝 Add Conventional Commits to README 2022-03-19 19:34:24 -07:00
ThatOneCalculator 10027ff5e3 docs: 📄 Add Conventional Commits to Code of Conduct 2022-03-19 19:32:04 -07:00
Kainoa Kanter 2d1c14f15b
docs: 📝 Typo 2022-03-19 19:29:05 -07:00
ThatOneCalculator 2c37d6a83f docs: 📄 Update code of conduct 2022-03-19 19:28:24 -07:00
ThatOneCalculator c20e6a879c refactor: ♻️ Logic change on keybind for new paste 2022-03-19 19:26:35 -07:00
ThatOneCalculator d043839fc9 feat: Ctrl + N makes new paste 2022-03-19 18:51:37 -07:00
ThatOneCalculator fb51056fa0 feat: 🔖 v0.7.0 release candidate! 2022-03-19 18:48:23 -07:00
Kainoa Kanter 59f73bbd57
revert: 🔙 Rust edition 2022-03-19 18:36:19 -07:00
Kainoa Kanter 42c992c5a7
dep: 🚀 bump version in Cargo.toml
"we dont mention this ." - Dom, 2022
2022-03-19 18:34:45 -07:00
Kainoa Kanter f37c12db59
doc: 📝 Update benchmarks 2022-03-19 17:48:52 -07:00
Kainoa Kanter e115434a0e
doc: 📝 Yarn 2022-03-19 17:39:56 -07:00
ThatOneCalculator a5eb9f17cc fix: 🚑 Fix NGINX ReGeX 2022-03-19 17:36:33 -07:00
ThatOneCalculator 3378fa0aa3 feat: No longer need `/~/` 2022-03-19 17:25:29 -07:00
ThatOneCalculator f4b827d1c6 Merge branch 'main' of https://github.com/Domterion/zer0bin 2022-03-19 17:17:32 -07:00
ThatOneCalculator 749c928306 fix: 🔧 Yarn cache ignored 2022-03-19 17:17:18 -07:00
Kainoa Kanter b40820ef9c
doc: 📝 Update README icons 2022-03-19 17:01:49 -07:00
Kainoa Kanter b56cfc7c5f
doc: 📝 Put steps into details 2022-03-19 16:58:12 -07:00
Kainoa Kanter 465cc0169a
doc: 📝 Update details tags 2022-03-19 16:56:59 -07:00
Kainoa Kanter bc9611e027
doc: 📝 Move prettier to frontend 2022-03-19 16:48:40 -07:00
Kainoa Kanter a5d55afba2
docs: 📝 `username` -> `postgres` 2022-03-19 14:40:45 -07:00
Kainoa Kanter de9ac516e1
docs: 📝 Add back comment 2022-03-19 14:39:08 -07:00
Kainoa Kanter 5a649e25bb
docs: 📝 😈 for FreeBSD 2022-03-19 14:38:15 -07:00
Kainoa Kanter a5236a16af
Merge pull request #25 from zer0bin-dev/yarn 2022-03-19 14:35:28 -07:00
Kainoa Kanter ed9416467c
egg: 🥚 Change node egg to yarn egg 2022-03-19 12:57:10 -07:00
Kainoa Kanter 2274efa958
docs: 📝 Change Brotli emoji 🌾 2022-03-19 12:42:41 -07:00
Kainoa Kanter a625235635
docs: 📝 Omit cargo from deps
Cargo comes with rust
https://doc.rust-lang.org/cargo/getting-started/installation.html
2022-03-19 12:40:46 -07:00
ThatOneCalculator 882287280c feat: Yarn 2022-03-19 12:38:18 -07:00
Kainoa Kanter 345d461574
docs: 📝 Add comment to psql line 2022-03-19 11:48:53 -07:00
Kainoa Kanter 57253f0c73
docs: 📝 Move Prettier 2022-03-19 11:34:23 -07:00
Kainoa Kanter a20a2dfb14
docs: 📝 Add SVG 2022-03-19 11:33:29 -07:00
ThatOneCalculator 18fb4616f9 Merge branch 'main' of https://github.com/Domterion/zer0bin 2022-03-19 11:20:42 -07:00
ThatOneCalculator 3e135919f4 refactor: 🎨 Formatting, remove global.content 2022-03-19 11:19:53 -07:00
Kainoa Kanter bd238e3e19
docs: 📝 Configuration and benchmarks now details 2022-03-19 11:11:28 -07:00
Kainoa Kanter 8f8b234b1f
docs: 📝 Remove "Docker coming soon" 😔🐋 2022-03-19 10:48:50 -07:00
ThatOneCalculator 456a92e3b9 style: 🎨 Formatting 2022-03-19 10:47:05 -07:00
ThatOneCalculator 58a15dafda Merge branch 'main' of https://github.com/Domterion/zer0bin 2022-03-19 10:41:56 -07:00
ThatOneCalculator 783dabbe9f Close 🐢 Split TS files #21 2022-03-19 10:41:48 -07:00
Kainoa Kanter bd844c6adb
Update README.md 2022-03-18 18:49:40 -07:00
Dominic Harris 557e4f1fbf
sorry testing :( 2022-03-18 15:17:45 -04:00
Dominic Harris 84cb21325f
🐛 fix: Remove my testing nginx config 2022-03-18 15:07:49 -04:00
Dominic Harris 83f9f880bf
♻️ refactor: Move Docker to its own branch 2022-03-18 15:05:19 -04:00
Dominic Harris 245b4376a9
feature: Work on Docker (WIP) 2022-03-18 14:58:12 -04:00
Kainoa Kanter 1729bfc51b
docs: 📝 Comment out Docker 🐋 until ready 2022-03-18 11:57:35 -07:00
Kainoa Kanter b22e351d57
docs: 📝 Add transfonter 2022-03-18 11:56:18 -07:00
ThatOneCalculator 6551e0b315 Merge branch 'main' of https://github.com/Domterion/zer0bin 2022-03-18 11:51:11 -07:00
ThatOneCalculator 1370d8d1fc Add italic font 2022-03-18 11:51:04 -07:00
Kainoa Kanter e622facfb8
refactor: ♻ fix build statement 2022-03-18 11:44:33 -07:00
ThatOneCalculator bb90482cd4 fix: ✏️ Typo 2022-03-18 11:33:04 -07:00
ThatOneCalculator b5ab095195 refactor: ♻️ Change random code 2022-03-17 12:29:33 -07:00
ThatOneCalculator d65d74b325 A 2022-03-17 12:28:34 -07:00
ThatOneCalculator c7b200080e feat: Ctrl + S saves paste
Refactors saving to be its own method, and uses that method for the save button and the ctrl + s event
2022-03-17 12:23:18 -07:00
ThatOneCalculator 3899b674f3 Merge branch 'main' of https://github.com/Domterion/zer0bin 2022-03-17 12:21:46 -07:00
ThatOneCalculator bca2ee264b Ctrl + S saves 2022-03-17 12:21:29 -07:00
Kainoa Kanter 046f2f192f
📝 doc: Update repo link 2022-03-17 12:16:32 -07:00
Kainoa Kanter 0888e8f3dc
📝 doc: Credit Skill Icons 2022-03-17 12:14:34 -07:00
Dominic Harris aa305a3637
📝 doc: Add my email to enforcement in CODE_OF_CONDUCT.md 2022-03-17 09:38:31 -04:00
Dominic Harris 2f72e2b182
♻️ refactor: Redo contributing guidelines 2022-03-17 09:33:47 -04:00
Dominic Harris ada569cdaf
📝 doc: Add contributing to readme 2022-03-17 09:28:16 -04:00
Dominic Harris 59196333ac
♻️ refactor: More padding on line numbers and none on textarea 2022-03-17 09:17:42 -04:00
Dominic Harris cef72bb8ac
feature: Work on Dockerfile for frontend 2022-03-17 08:44:53 -04:00
Dominic Harris 324f5b381a
🎁 heres your emoji 2022-03-16 19:53:57 -04:00
Dominic Harris 9744446a46
a 2022-03-16 19:40:44 -04:00
Dominic Harris 99d4986f2b
yay! 2022-03-16 19:38:43 -04:00
Kainoa Kanter 4393106cd0 The 2022-03-16 16:05:19 -07:00
Kainoa Kanter c745d99fd4 Merge branch 'main' of https://github.com/Domterion/zer0bin 2022-03-16 16:03:26 -07:00
Kainoa Kanter 3b1db4d068 Try smth 2022-03-16 16:03:18 -07:00
Kainoa Kanter f2f1c834ab
Update README.md 2022-03-16 13:18:23 -07:00
Kainoa Kanter 834003fcc9 Merge branch 'main' of https://github.com/Domterion/zer0bin 2022-03-16 13:03:29 -07:00
Kainoa Kanter bb063dcb33 import roles 2022-03-16 13:03:24 -07:00
Dominic Harris dd97a5d4ee
ficks 2022-03-16 16:00:02 -04:00
Dominic Harris 0576a2ea4c
ficks 2022-03-16 16:00:02 -04:00
Kainoa Kanter db9b5c1226
Update README.md 2022-03-16 12:47:52 -07:00
Kainoa Kanter 690329d4c3
🥳 v0.6.1 2022-03-16 11:17:06 -07:00
Kainoa Kanter d0aebcea08
🥳 v0.6.1 2022-03-16 11:16:55 -07:00
41 changed files with 3225 additions and 544 deletions

View File

@ -12,19 +12,13 @@ Thanks for offering us your public instance!
## Details
What country is the server in:
What server hardware/provider is the server on:
Are you using CloudFlare:
What version of zer0bin is it running:
Have you made any modifications to zer0bin? If so, what?:
What are the ratelimits:
What is the expiration time of pastes:
What is the max paste size:
- Domain name:
- What country is the server in:
- What server hardware/provider is the server on:
- Are you using CloudFlare or any Google services (domain, DNS, etc):
- What version of zer0bin is it running:
- Have you made any modifications to zer0bin? If so, what?:
- What are the ratelimits:
- What is the expiration time of pastes:
- What is the max paste size:

2
.gitignore vendored
View File

@ -1,6 +1,6 @@
**/target/
**/.yarn
**/node_modules/
**/dist/
**/.parcel-cache/
**/config.json
**/package-lock.json

View File

@ -1,7 +0,0 @@
{
"useTabs": true,
"trailingComma": "es5",
"tabWidth": 4,
"semi": false,
"singleQuote": false
}

View File

@ -17,24 +17,24 @@ diverse, inclusive, and healthy community.
Examples of behavior that contributes to a positive environment for our
community include:
* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
* Focusing on what is best not just for us as individuals, but for the
overall community
- Demonstrating empathy and kindness toward other people
- Being respectful of differing opinions, viewpoints, and experiences
- Giving and gracefully accepting constructive feedback
- Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
- Focusing on what is best not just for us as individuals, but for the
overall community
Examples of unacceptable behavior include:
* The use of sexualized language or imagery, and sexual attention or
advances of any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email
address, without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
- The use of sexualized language or imagery, and sexual attention or
advances of any kind
- Trolling, insulting or derogatory comments, and personal or political attacks
- Public or private harassment
- Publishing others' private information, such as a physical or email
address, without their explicit permission
- Other conduct which could reasonably be considered inappropriate in a
professional setting
## Enforcement Responsibilities
@ -60,7 +60,7 @@ representative at an online or offline event.
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at
kainoa@t1c.dev.
dominic@domm.me.
All complaints will be reviewed and investigated promptly and fairly.
All community leaders are obligated to respect the privacy and security of the
@ -106,7 +106,7 @@ Violating these terms may lead to a permanent ban.
### 4. Permanent Ban
**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior, harassment of an
standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of individuals.
**Consequence**: A permanent ban from any sort of public interaction within

View File

@ -1,6 +1,10 @@
# Contributing Guidelines
- Follow repo structure
- Use prettier formatter with our settings
- Be respectful
- Don't add packages that have a lot of bloat
- Remember to use `npm` if you're working on the frontend
- Follow the repository structure
- Commit messages must be descriptive and concise
- Your code must be formatted with the formatters we use
- The frontend must use our `prettier` config
- The backend must use `rustfmt`
- The frontend must be installed with `yarn` and compiled with `parcel`
- Additional frontend packages must not be considered bloated
- All commits must follow [Conventional Commits](https://marketplace.visualstudio.com/items?itemName=vivaxy.vscode-conventional-commits)

View File

@ -1,3 +1,10 @@
"Wait, but isn't Cartograph CF a paid font you need a license for?"
![You](https://c.tenor.com/Mxgk7rxrzq8AAAAC/lithiumare-kiracord.gif)
# Ok but fr
People have been pirating Cartograph CF for a looong time, but if you would like to use Fira Code (a free font) instead:
1. `cd frontend`
2. `mv style/font-fira.scss style/font.scss`
3. Rebuild frontend

134
README.md
View File

@ -1,131 +1,77 @@
<div align="center">
<a href="https://zer0b.in">
<img src="https://raw.githubusercontent.com/zer0bin-dev/.github/main/zer0bin.svg" height="150px"/>
<br>
<img src="https://raw.githubusercontent.com/zer0bin-dev/.github/main/zer0bin-rainbow.svg" height="100"/>
<br>
</a>
Just a place to paste
<br>
<br>
<p align="center">
<a href="https://github.com/zer0bin-dev/zer0bin/stargazers">
<img alt="Stargazers" src="https://custom-icon-badges.herokuapp.com/github/stars/zer0bin-dev/zer0bin?style=for-the-badge&logo=star&color=f6c177&logoColor=31748f&labelColor=12101F"></a>
<!-- <a href="https://github.com/zer0bin-dev/zer0bin/releases/latest">
<img alt="Releases" src="https://img.shields.io/github/release/zer0bin-dev/zer0bin?style=for-the-badge&logo=github&color=31748f&logoColor=ebbcba&labelColor=12101F"/></a> -->
<a href="https://github.com/zer0bin-dev/zer0bin/issues">
<img alt="Issues" src="https://custom-icon-badges.herokuapp.com/github/issues/zer0bin-dev/zer0bin?style=for-the-badge&logo=issue-opened&color=9ccfd8&logoColor=eb6f92&labelColor=12101F"></a>
<img alt="Stargazers" src="https://custom-icon-badges.herokuapp.com/github/stars/zer0bin-dev/zer0bin?style=for-the-badge&logo=star&color=f6c177&logoColor=eb6f92&labelColor=191724"></a>
<a href="https://github.com/zer0bin-dev/zer0bin/wiki">
<img alt="Wiki" src="https://custom-icon-badges.herokuapp.com/badge/read_the-wiki-ebbcba?style=for-the-badge&logo=repo&logoColor=eb6f92&labelColor=191724"></a>
<a href="https://github.com/zer0bin-dev/zer0bin/releases/latest">
<img alt="Releases" src="https://img.shields.io/github/release/zer0bin-dev/zer0bin?style=for-the-badge&logo=github&color=31748f&logoColor=eb6f92&labelColor=191724"/></a>
<a href="https://github.com/zer0bin-dev/zer0bin/blob/main/LICENSE">
<img alt="License" src="https://custom-icon-badges.herokuapp.com/github/license/zer0bin-dev/zer0bin?style=for-the-badge&logo=law&color=c4a7e7&logoColor=ebbcba&labelColor=12101F"></a>
<img alt="License" src="https://custom-icon-badges.herokuapp.com/github/license/zer0bin-dev/zer0bin?style=for-the-badge&logo=law&color=c4a7e7&logoColor=eb6f92&labelColor=191724"></a>
<a href="https://github.com/zer0bin-dev/zer0bin/issues">
<img alt="Issues" src="https://custom-icon-badges.herokuapp.com/github/issues/zer0bin-dev/zer0bin?style=for-the-badge&logo=issue-opened&color=9ccfd8&logoColor=eb6f92&labelColor=191724"></a>
</p>
<br>
</div>
# Features
- ✨ Code highlighting and line numbers (default)
- 📖 Markdown rendering (click the <a href="https://github.com/zer0bin-dev/zer0bin"><img alt="Markdown" src="https://user-images.githubusercontent.com/44733677/161484749-fdf60750-36ae-4d0a-aaa5-cdcae54fc805.svg" height=18></a> button)
- 🔥 Single-view pastes (click the <a href="https://github.com/zer0bin-dev/zer0bin"><img alt="Fire" src="https://user-images.githubusercontent.com/44733677/161485115-c5fccb81-fa21-4e67-88fd-9a6f9dff728e.svg" height=18></a> button)
- ‍🧑‍💻 [CLI Client](https://github.com/zer0bin-dev/zer0)
- 🚀 Easily selfhostable
- 👀 View counter
- ⌨️ Keybinds
- <kbd>Ctrl</kbd> + <kbd>S</kbd>: save paste
- <kbd>Ctrl</kbd> + <kbd>N</kbd>: new paste
- <kbd>Ctrl</kbd> + <kbd>D</kbd>: duplicate paste
- <kbd>Ctrl</kbd> + <kbd>M</kbd>: toggle markdown mode
- 📱 Mobile-friendly UI
- 🧈 Super smooth scrolling
- 🖼️ Badge generation for stats (seen below)
# Public instances
Submit your public instance [here](https://github.com/Domterion/zer0bin/issues/new?assignees=&labels=&template=03_public_instance.md&title=%F0%9F%9A%80+)!
| Website | Expiration | Max paste size | Version | Country |
| ---------------------------------------------- | ---------- | -------------- | ------- | ------- |
| zer0b.in (not up yet) | 7 days | 40,000 chars | vx.x.x | ? |
| [stepbro.voring.me](https://stepbro.voring.me) | 365 days | 69,000 chars | v0.6.0 | 🇺🇸 US |
| URL | Expiration | Max paste size | Total Pastes | Version | Country |
| ---------------------------------------------- | ---------- | -------------- | -------------------------------------------- | --------------------------------------------- | ------- |
| [paste.mint.lgbt](https://paste.mint.lgbt) | 30 days | 50,000 chars | ![pastes](https://paste.mint.lgbt/api/b/t) | ![version](https://paste.mint.lgbt/api/b/v) | 🇨🇱 Chile |
# Technologies used
### Frontend:
<a href="https://www.typescriptlang.org/"><img src="https://github.com/tandpfun/skill-icons/raw/main/icons/TypeScript.svg" height=40/></a> <a href="https://sass-lang.com/"><img src="https://github.com/tandpfun/skill-icons/raw/main/icons/Sass.svg" height=40/></a> <a href="https://pugjs.org/"><img src="https://github.com/tandpfun/skill-icons/raw/main/icons/Pug-Dark.svg" height=40/></a> <a href="https://rosepinetheme.com/"><img src="https://cdn.discordapp.com/attachments/810799100940255260/953176309444542464/RosePine.svg" height=40/></a> <a href="https://highlightjs.org/"><img src="https://cdn.discordapp.com/attachments/810799100940255260/953177926688464936/HLJS.svg" height=40/></a> <a href="https://github.com/ant-design/ant-design-icons"><img src="https://cdn.discordapp.com/attachments/810799100940255260/953181625259266059/AntIcons-Dark.svg" height=40/></a> <a href="https://github.com/idiotWu/smooth-scrollbar"><img src="https://cdn.discordapp.com/attachments/810799100940255260/953564432628322364/SmoothScrollJS.svg" height=40/></a> <a href="https://github.com/loonywizard/js-confetti"><img src="https://cdn.discordapp.com/attachments/810799100940255260/953564432896782416/JSConfetti.svg" height=40/></a> <a href="https://definitelytyped.org/"><img src="https://cdn.discordapp.com/attachments/810799100940255260/953567495321710602/DefinitelyTyped.svg" height=40/></a> <a href="https://parceljs.org/"><img src="https://cdn.discordapp.com/attachments/810799100940255260/953176310195322920/Parcel-Dark.svg" height=40/></a> <a href="https://npmjs.org"><img src="https://cdn.discordapp.com/attachments/810799100940255260/953176309259972638/NPM.svg" height=40/></a>
<a href="https://www.typescriptlang.org/"><img src="https://github.com/tandpfun/skill-icons/raw/main/icons/TypeScript.svg" height=40/></a> <a href="https://sass-lang.com/"><img src="https://github.com/tandpfun/skill-icons/raw/main/icons/Sass.svg" height=40/></a> <a href="https://pugjs.org/"><img src="https://github.com/tandpfun/skill-icons/raw/main/icons/Pug-Dark.svg" height=40/></a> <a href="https://rosepinetheme.com/"><img src="https://cdn.discordapp.com/attachments/810799100940255260/953176309444542464/RosePine.svg" height=40/></a> <a href="https://highlightjs.org/"><img src="https://cdn.discordapp.com/attachments/810799100940255260/956227499229061140/hljs.svg" height=40/></a> <a href="https://marked.js.org/"><img src="https://cdn.discordapp.com/attachments/810799100940255260/956263178961047612/MarkedJS.svg" height=40/></a> <a href="https://github.com/ant-design/ant-design-icons"><img src="https://cdn.discordapp.com/attachments/810799100940255260/956227498985799690/anticons.svg" height=40/></a><br><a href="https://github.com/idiotWu/smooth-scrollbar"><img src="https://cdn.discordapp.com/attachments/810799100940255260/953564432628322364/SmoothScrollJS.svg" height=40/></a> <a href="https://atomiks.github.io/tippyjs/"><img src="https://cdn.discordapp.com/attachments/872332549777666078/955624715521769522/Tippy.svg" height=40/></a> <a href="https://github.com/loonywizard/js-confetti"><img src="https://cdn.discordapp.com/attachments/810799100940255260/955609316042362930/JSConfetti.svg" height=40/></a> <a href="https://github.com/hadialqattan/no-darkreader"><img src="https://cdn.discordapp.com/attachments/810799100940255260/955869669535907870/NoDarkReader.svg" height=40/></a> <a href="https://vitejs.dev/"><img src="https://cdn.discordapp.com/attachments/810799100940255260/961789632834600960/Vite-Dark.svg" height=40/></a> <a href="https://prettier.io/"><img src="https://cdn.discordapp.com/attachments/810799100940255260/953339670538887318/Prettier.svg" height=40/></a> <a href="https://yarnpkg.org"><img src="https://cdn.discordapp.com/attachments/810799100940255260/954823377493852170/Yarn.svg" height=40/></a>
### Backend:
<a href="https://www.rust-lang.org/"><img src="https://github.com/tandpfun/skill-icons/raw/main/icons/Rust.svg" height=40/></a> <a href="https://actix.rs/"><img src="https://user-images.githubusercontent.com/44733677/158648238-0586f185-4e0c-43bc-b6a9-effd18b3b1ac.svg" height=40/></a> <a href="https://github.com/serde-rs/serde"><img src="https://cdn.discordapp.com/attachments/810799100940255260/953176309964627978/Serde-Dark.svg" height=40/></a> <a href="https://github.com/launchbadge/sqlx"><img src="https://cdn.discordapp.com/attachments/810799100940255260/953176310354673704/SQLX-Dark.svg" height=40/></a> <a href="https://github.com/chronotope/chrono"><img src="https://cdn.discordapp.com/attachments/810799100940255260/953178919169835018/NPM-svg.png" height=40/></a> <a href="https://www.postgresql.org/"><img src="https://github.com/tandpfun/skill-icons/raw/main/icons/PostgreSQL-Dark.svg" height=40/></a> <a href="https://github.com/nikolay-govorov/nanoid"><img src="https://cdn.discordapp.com/attachments/810799100940255260/953176309629067354/NanoID-Dark.svg" height=40/></a>
<a href="https://www.rust-lang.org/"><img src="https://github.com/tandpfun/skill-icons/raw/main/icons/Rust.svg" height=40/></a> <a href="https://actix.rs/"><img src="https://user-images.githubusercontent.com/44733677/158648238-0586f185-4e0c-43bc-b6a9-effd18b3b1ac.svg" height=40/></a> <a href="https://github.com/serde-rs/serde"><img src="https://cdn.discordapp.com/attachments/810799100940255260/956227498792849418/serde.svg" height=40/></a> <a href="https://github.com/launchbadge/sqlx"><img src="https://cdn.discordapp.com/attachments/810799100940255260/956227498608320562/sqlx.svg" height=40/></a> <a href="https://github.com/chronotope/chrono"><img src="https://cdn.discordapp.com/attachments/810799100940255260/953178919169835018/NPM-svg.png" height=40/></a> <a href="https://www.postgresql.org/"><img src="https://github.com/tandpfun/skill-icons/raw/main/icons/PostgreSQL-Dark.svg" height=40/></a> <a href="https://github.com/nikolay-govorov/nanoid"><img src="https://cdn.discordapp.com/attachments/810799100940255260/953176309629067354/NanoID-Dark.svg" height=40/></a> <a href="https://github.com/cgburgess/badge-maker"><img src="https://cdn.discordapp.com/attachments/810799100940255260/956244924930617385/RustBadgeMaker.svg" height=40/></a>
### Misc:
<a href="https://nginx.com/"><img src="https://github.com/tandpfun/skill-icons/raw/main/icons/Nginx.svg" height=40/></a> <a href="https://github.com/google/ngx_brotli"><img src="https://cdn.discordapp.com/attachments/810799100940255260/953552981691883520/Brotli.svg" height=40/></a> <a href="https://docker.com/"><img src="https://github.com/tandpfun/skill-icons/raw/main/icons/Docker.svg" height=40/></a> <a href="https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax"><img src="https://github.com/tandpfun/skill-icons/raw/main/icons/Markdown-Dark.svg" height=40/></a> <a href="https://prettier.io/"><img src="https://cdn.discordapp.com/attachments/810799100940255260/953339670538887318/Prettier.svg" height=40/></a> <a href="https://git-scm.com/"><img src="https://github.com/tandpfun/skill-icons/raw/main/icons/Git.svg" height=40/></a>
<a href="https://nginx.com/"><img src="https://github.com/tandpfun/skill-icons/raw/main/icons/Nginx.svg" height=40/></a> <!-- <a href="https://docker.com/"><img src="https://github.com/tandpfun/skill-icons/raw/main/icons/Docker.svg" height=40/></a> --> <a href="https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax"><img src="https://github.com/tandpfun/skill-icons/raw/main/icons/Markdown-Dark.svg" height=40/></a> <a href="https://git-scm.com/"><img src="https://github.com/tandpfun/skill-icons/raw/main/icons/Git.svg" height=40/></a> <a href="https://www.conventionalcommits.org/"><img src="https://cdn.discordapp.com/attachments/810799100940255260/955896756095320074/ConventionalCommits.svg" height=40/></a>
# API
###### (Sorta) made with [Skill Icons](https://skillicons.dev/)
- **GET** `/api/p/:id` - Get a paste by ID
- **POST** `/api/p/n` - Post a new paste
- **GET** `/api/s` - Get stats about the instance
# More info
# Self-host instructions
### Looking for API reference, self-hosting instructions, and/or benchmarks?
### Requirements
<a href="https://github.com/zer0bin-dev/zer0bin/wiki">
<img alt="Stargazers" src="https://custom-icon-badges.herokuapp.com/badge/read_the-wiki-ebbcba?style=for-the-badge&logo=repo&logoColor=eb6f92&labelColor=191724" height=50></a>
- 🦀 Rust ≥ 1.58.0
- 🚢 Cargo ≥ 1.58.0
- 🐢 NodeJS ≥ 16.0
- 🚀 NPM ≥ 8.0.0
- 🐘 PostgreSQL ≥ 9.6
- 🦝 Nginx ≥ 1.18.0
- 🥖 [Brotli](https://github.com/google/ngx_brotli) plugin reccomended
- 📍 Domain linked to your server
- 🌄 Must have [SSL certs](https://letsencrypt.org/)
- 🐧 \*nix OS (Linux, \*BSD, etc)
# Contributing
### Steps
<!--
1. `git clone https://github.com/Domterion/zer0bin && cd zer0bin`
2. Edit `example.nginx` as appropriate, then `mv example.nginx yourdomain.tld && for i in /etc/nginx/sites-available/ /etc/nginx/sites-enabled/; do cp ./yourdomain.tld $i; done && systemctl nginx restart`
3. `psql -f schema.sql -U postgres zer0bin`
4. `cd frontend`
5. `cp config.example.json config.json` and edit as appropriate
6. `npm i && npm run build`
7. `cd ../backend`
8. `cp config.example.json config.json` and edit as appropriate
9. `cargo build --release`
10. `./target/release/backend` (preferably in a tmux session or as a service)
-->
🐋 Docker is coming soon:tm:
Please run each command one at a time!
```bash
# export EDITOR=nano
git clone https://github.com/Domterion/zer0bin && cd zer0bin
$EDITOR example.nginx # Edit as appropriate
mv example.nginx yourdomain.tld
sudo cp ./yourdomain.tld /etc/nginx/sites-available
sudo cp ./yourdomain.tld /etc/nginx/sites-enabled
systemctl nginx restart # Or whichever process manager you use
cd frontend
cp config.example.json config.json
$EDITOR config.json # Edit as appropriate
npm i && npm run build
cd ../backend
psql -f schema.sql -U postgres zer0bin
cp config.example.json config.json
$EDITOR config.json # Edit as appropriate
cargo build --release
./target/release/zer0bin-bin # Preferably in a tmux session or as a service
```
### Configuration
| Key | Values | Description |
| ------------------------------------------ | ------------------------ | ------------------------------------------------------------------------------ |
| server.backend_host | 127.0.0.1 or 0.0.0.0 | The host to run the backend on |
| server.backend_port | Any open port | The port to run the backend on |
| pastes.character_limit | Number up to 2^64 - 1 | The amount of characters allowed in a single paste |
| pastes.days_til_expiration | Number up to 2^63 or -1 | The days till a paste is to expire. If set to -1 then pastes will never expire |
| pastes.id_length | Number up to 2^64 - 1 | The length of the ID for each paste |
| databases.postgres_uri | PostreSQL Connection URI | The URI to use when connecting to a PostgreSQL database |
| ratelimits.seconds_in_between_pastes | Number up to 2^64 - 1 | The seconds between paste uploads |
| ratelimits.allowed_pastes_before_ratelimit | Number up to 2^32 - 1 | Amount of requests that can be made before they are blocked and have to wait |
# Benchmarks
###### Measured with Lighthouse and Firefox Network Performance Analysis
### Homepage
![image](https://user-images.githubusercontent.com/44733677/158523056-2d1b4a38-76f8-413f-b4df-5fd3d920dc66.png)
![image](https://user-images.githubusercontent.com/44733677/158523711-19f34696-b88f-4a6c-9a66-a77cf2f3e74e.png)
### 20 line paste
![image](https://user-images.githubusercontent.com/44733677/158522958-a226612f-3848-43be-876e-8822a4cc9907.png)
![image](https://user-images.githubusercontent.com/44733677/158523846-d79a94a5-64a5-475a-b481-e72141b47cf6.png)
See [CONTRIBUTING.md](./CONTRIBUTING.md)

289
backend/Cargo.lock generated Executable file → Normal file
View File

@ -16,16 +16,15 @@ dependencies = [
"memchr",
"pin-project-lite",
"tokio",
"tokio-util 0.7.0",
"tokio-util",
]
[[package]]
name = "actix-cors"
version = "0.6.0"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "30dbd116ef7532f56e2f6d7c511736ea0b124d914ee8820a5271247bf89f06aa"
checksum = "414360eed71ba2d5435b185ba43ecbe281dfab5df3898286d6b7be8074372c92"
dependencies = [
"actix-service",
"actix-utils",
"actix-web",
"derive_more",
@ -49,9 +48,9 @@ dependencies = [
[[package]]
name = "actix-http"
version = "3.0.0"
version = "3.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0f3fdd63b9cfeaf92eeeece719dabbddddb420a57d3fd171ce1490ecfb7086b1"
checksum = "a5885cb81a0d4d0d322864bea1bb6c2a8144626b4fdc625d4c51eba197e7797a"
dependencies = [
"actix-codec",
"actix-rt",
@ -71,7 +70,7 @@ dependencies = [
"http",
"httparse",
"httpdate",
"itoa",
"itoa 1.0.1",
"language-tags",
"local-channel",
"log",
@ -110,9 +109,9 @@ dependencies = [
[[package]]
name = "actix-rt"
version = "2.6.0"
version = "2.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cdf3f2183be1241ed4dd22611850b85d38de0b08a09f1f7bcccbd0809084b359"
checksum = "7ea16c295198e958ef31930a6ef37d0fb64e9ca3b6116e6b93a8bdae96ee1000"
dependencies = [
"actix-macros",
"futures-core",
@ -121,20 +120,20 @@ dependencies = [
[[package]]
name = "actix-server"
version = "2.0.0"
version = "2.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9e7472ac180abb0a8e592b653744345983a7a14f44691c8394a799d0df4dbbf"
checksum = "0da34f8e659ea1b077bb4637948b815cd3768ad5a188fdcd74ff4d84240cd824"
dependencies = [
"actix-rt",
"actix-service",
"actix-utils",
"futures-core",
"futures-util",
"log",
"mio",
"num_cpus",
"socket2",
"tokio",
"tracing",
]
[[package]]
@ -182,7 +181,7 @@ dependencies = [
"encoding_rs",
"futures-core",
"futures-util",
"itoa",
"itoa 1.0.1",
"language-tags",
"log",
"mime",
@ -194,7 +193,7 @@ dependencies = [
"serde_urlencoded",
"smallvec",
"socket2",
"time 0.3.7",
"time 0.3.9",
"url",
]
@ -268,12 +267,13 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
[[package]]
name = "backend"
version = "0.1.0"
version = "1.1.1"
dependencies = [
"actix-cors",
"actix-governor",
"actix-rt",
"actix-web",
"badge-maker",
"chrono",
"nanoid",
"serde",
@ -281,12 +281,37 @@ dependencies = [
"sqlx",
]
[[package]]
name = "badge-maker"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "383647c1ae7388c2801ef995f6de2f9551a361ad637f2a0e4fea41c51dd37b81"
dependencies = [
"aho-corasick",
"bincode",
"itoa 0.4.8",
"lazy_static",
"regex",
"seahash",
"serde",
"thiserror",
]
[[package]]
name = "base64"
version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd"
[[package]]
name = "bincode"
version = "1.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad"
dependencies = [
"serde",
]
[[package]]
name = "bitflags"
version = "1.3.2"
@ -313,9 +338,9 @@ dependencies = [
[[package]]
name = "brotli"
version = "3.3.3"
version = "3.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f838e47a451d5a8fa552371f80024dd6ace9b7acdf25c4c3d0f9bc6816fb1c39"
checksum = "a1a0b1dbcc8ae29329621f8d4f0d835787c1c38bb1401979b49d13b0b305ff68"
dependencies = [
"alloc-no-stdlib",
"alloc-stdlib",
@ -384,7 +409,7 @@ dependencies = [
"num-integer",
"num-traits",
"serde",
"time 0.1.43",
"time 0.1.44",
"winapi",
]
@ -401,15 +426,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94d4706de1b0fa5b132270cddffa8585166037822e260a944fe161acd137ca05"
dependencies = [
"percent-encoding",
"time 0.3.7",
"time 0.3.9",
"version_check",
]
[[package]]
name = "cpufeatures"
version = "0.2.1"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95059428f66df56b63431fdb4e1947ed2190586af5c5a8a8b71122bdf5a7f469"
checksum = "59a6001667ab124aebae2a495118e11d30984c3a653e99d86d58971708cf5e4b"
dependencies = [
"libc",
]
@ -440,9 +465,9 @@ dependencies = [
[[package]]
name = "crossbeam-queue"
version = "0.3.4"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4dd435b205a4842da59efd07628f921c096bc1cc0a156835b4fa0bcb9a19bcce"
checksum = "1f25d8400f4a7a5778f0e4e52384a48cbd9b5c495d110786187fc750075277a2"
dependencies = [
"cfg-if",
"crossbeam-utils",
@ -450,9 +475,9 @@ dependencies = [
[[package]]
name = "crossbeam-utils"
version = "0.8.7"
version = "0.8.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5e5bed1f1c269533fa816a0a5492b3545209a205ca1a54842be180eb63a16a6"
checksum = "0bf124c720b7686e3c2663cf54062ab0f68a88af2fb6a030e87e30bf721fcb38"
dependencies = [
"cfg-if",
"lazy_static",
@ -480,9 +505,9 @@ dependencies = [
[[package]]
name = "dashmap"
version = "5.1.0"
version = "5.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0834a35a3fce649144119e18da2a4d8ed12ef3862f47183fd46f625d072d96c"
checksum = "4c8858831f7781322e539ea39e72449c46b059638250c14344fec8d0aa6e539c"
dependencies = [
"cfg-if",
"num_cpus",
@ -532,9 +557,9 @@ dependencies = [
[[package]]
name = "dirs-sys"
version = "0.3.6"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03d86534ed367a67548dc68113a0f5db55432fdfbb6e6f9d77704397d95d5780"
checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6"
dependencies = [
"libc",
"redox_users",
@ -714,13 +739,13 @@ dependencies = [
[[package]]
name = "getrandom"
version = "0.2.5"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d39cd93900197114fa1fcb7ae84ca742095eed9442088988ae74fa744e930e77"
checksum = "9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad"
dependencies = [
"cfg-if",
"libc",
"wasi",
"wasi 0.10.0+wasi-snapshot-preview1",
]
[[package]]
@ -742,9 +767,9 @@ dependencies = [
[[package]]
name = "h2"
version = "0.3.11"
version = "0.3.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9f1f717ddc7b2ba36df7e871fd88db79326551d3d6f1fc406fbfd28b582ff8e"
checksum = "37a82c6d637fc9515a4694bbf1cb2457b79d81ce52b3108bdeea58b07dd34a57"
dependencies = [
"bytes",
"fnv",
@ -755,7 +780,7 @@ dependencies = [
"indexmap",
"slab",
"tokio",
"tokio-util 0.6.9",
"tokio-util",
"tracing",
]
@ -819,7 +844,7 @@ checksum = "31f4c6746584866f0feabcc69893c5b51beef3831656a968ed7ae254cdc4fd03"
dependencies = [
"bytes",
"fnv",
"itoa",
"itoa 1.0.1",
]
[[package]]
@ -847,9 +872,9 @@ dependencies = [
[[package]]
name = "indexmap"
version = "1.8.0"
version = "1.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "282a6247722caba404c065016bbfa522806e51714c34f5dfc3e4a3a46fcb4223"
checksum = "0f647032dfaa1f8b6dc29bd3edb7bbef4861b8b8007ebb118d6db284fd59f6ee"
dependencies = [
"autocfg",
"hashbrown",
@ -873,6 +898,12 @@ dependencies = [
"either",
]
[[package]]
name = "itoa"
version = "0.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4"
[[package]]
name = "itoa"
version = "1.0.1"
@ -911,9 +942,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.2.119"
version = "0.2.121"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1bf2e165bb3457c8e098ea76f3e3bc9db55f87aa90d52d0e6be741470916aaa4"
checksum = "efaa7b300f3b5fe8eb6bf21ce3895e1751d9665086af2d64b42f19701015ff4f"
[[package]]
name = "local-channel"
@ -935,18 +966,19 @@ checksum = "902eb695eb0591864543cbfbf6d742510642a605a61fc5e97fe6ceb5a30ac4fb"
[[package]]
name = "lock_api"
version = "0.4.6"
version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "88943dd7ef4a2e5a4bfa2753aaab3013e34ce2533d1996fb18ef591e315e2b3b"
checksum = "327fa5b6a6940e4699ec49a9beae1ea4845c6bab9314e4f84ac68742139d8c53"
dependencies = [
"autocfg",
"scopeguard",
]
[[package]]
name = "log"
version = "0.4.14"
version = "0.4.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
checksum = "6389c490849ff5bc16be905ae24bc913a9c8892e19b2341dbc175e14c341c2b8"
dependencies = [
"cfg-if",
]
@ -1007,14 +1039,15 @@ dependencies = [
[[package]]
name = "mio"
version = "0.8.0"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba272f85fa0b41fc91872be579b3bbe0f56b792aa361a380eb669469f68dafb2"
checksum = "52da4364ffb0e4fe33a9841a98a3f3014fb964045ce4f7a45a398243c8d6b0c9"
dependencies = [
"libc",
"log",
"miow",
"ntapi",
"wasi 0.11.0+wasi-snapshot-preview1",
"winapi",
]
@ -1044,13 +1077,12 @@ checksum = "b93853da6d84c2e3c7d730d6473e8817692dd89be387eb01b94d7f108ecb5b8c"
[[package]]
name = "nom"
version = "7.1.0"
version = "7.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b1d11e1ef389c76fe5b81bcaf2ea32cf88b62bc494e19f493d0b30e7a930109"
checksum = "a8903e5a29a317527874d0402f867152a3d21c908bb0b933e416c65e301d4c36"
dependencies = [
"memchr",
"minimal-lexical",
"version_check",
]
[[package]]
@ -1099,18 +1131,18 @@ dependencies = [
[[package]]
name = "num_threads"
version = "0.1.3"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97ba99ba6393e2c3734791401b66902d981cb03bf190af674ca69949b6d5fb15"
checksum = "aba1801fb138d8e85e11d0fc70baf4fe1cdfffda7c6cd34a854905df588e5ed0"
dependencies = [
"libc",
]
[[package]]
name = "once_cell"
version = "1.9.0"
version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da32515d9f6e6e489d7bc9d84c71b060db7247dc035bbe44eac88cf87486d8d5"
checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9"
[[package]]
name = "opaque-debug"
@ -1136,7 +1168,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87f5ec2493a61ac0506c0f4199f99070cbe83857b0337006a30f3e6719b8ef58"
dependencies = [
"lock_api",
"parking_lot_core 0.9.1",
"parking_lot_core 0.9.2",
]
[[package]]
@ -1155,9 +1187,9 @@ dependencies = [
[[package]]
name = "parking_lot_core"
version = "0.9.1"
version = "0.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28141e0cc4143da2443301914478dc976a61ffdb3f043058310c70df2fed8954"
checksum = "995f667a6c822200b0433ac218e05582f0e2efa1b922a3fd2fbaadc5f87bab37"
dependencies = [
"cfg-if",
"libc",
@ -1168,9 +1200,9 @@ dependencies = [
[[package]]
name = "paste"
version = "1.0.6"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0744126afe1a6dd7f394cb50a716dbe086cb06e255e53d8d0185d82828358fb5"
checksum = "0c520e05135d6e763148b6426a837e239041653ba7becd2e538c076c738025fc"
[[package]]
name = "percent-encoding"
@ -1216,16 +1248,16 @@ dependencies = [
"mach",
"once_cell",
"raw-cpuid",
"wasi",
"wasi 0.10.0+wasi-snapshot-preview1",
"web-sys",
"winapi",
]
[[package]]
name = "quote"
version = "1.0.15"
version = "1.0.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "864d3e96a899863136fc6e99f3d7cae289dafe43bf2c5ac19b70df7210c0a145"
checksum = "632d02bff7f874a36f33ea8bb416cd484b90cc66c1194b1a1110d067a7013f58"
dependencies = [
"proc-macro2",
]
@ -1262,37 +1294,38 @@ dependencies = [
[[package]]
name = "raw-cpuid"
version = "10.2.0"
version = "10.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "929f54e29691d4e6a9cc558479de70db7aa3d98cd6fe7ab86d7507aa2886b9d2"
checksum = "738bc47119e3eeccc7e94c4a506901aea5e7b4944ecd0829cbebf4af04ceda12"
dependencies = [
"bitflags",
]
[[package]]
name = "redox_syscall"
version = "0.2.10"
version = "0.2.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff"
checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42"
dependencies = [
"bitflags",
]
[[package]]
name = "redox_users"
version = "0.4.0"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "528532f3d801c87aec9def2add9ca802fe569e44a544afe633765267840abe64"
checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b"
dependencies = [
"getrandom",
"redox_syscall",
"thiserror",
]
[[package]]
name = "regex"
version = "1.5.4"
version = "1.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461"
checksum = "1a11647b6b25ff05a515cb92c365cec08801e83423a235b51e231e1808747286"
dependencies = [
"aho-corasick",
"memchr",
@ -1365,10 +1398,16 @@ dependencies = [
]
[[package]]
name = "semver"
version = "1.0.6"
name = "seahash"
version = "4.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4a3381e03edd24287172047536f20cabde766e2cd3e65e6b00fb3af51c4f38d"
checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b"
[[package]]
name = "semver"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d65bd28f48be7196d222d95b9243287f48d27aca604e08497513019ff0502cc4"
[[package]]
name = "serde"
@ -1396,7 +1435,7 @@ version = "1.0.79"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e8d9fa5c3b304765ce1fd9c4c8a3de2c8db365a5b91be52f186efc675681d95"
dependencies = [
"itoa",
"itoa 1.0.1",
"ryu",
"serde",
]
@ -1408,7 +1447,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd"
dependencies = [
"form_urlencoded",
"itoa",
"itoa 1.0.1",
"ryu",
"serde",
]
@ -1461,9 +1500,9 @@ dependencies = [
[[package]]
name = "slab"
version = "0.4.5"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9def91fd1e018fe007022791f865d0ccc9b3a0d5001e01aabb8b40e46000afb5"
checksum = "eb703cfe953bccee95685111adeedb76fabe4e97549a58d16f03ea7b9367bb32"
[[package]]
name = "smallvec"
@ -1533,7 +1572,7 @@ dependencies = [
"hex",
"hmac",
"indexmap",
"itoa",
"itoa 1.0.1",
"libc",
"log",
"md-5",
@ -1607,9 +1646,9 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601"
[[package]]
name = "syn"
version = "1.0.86"
version = "1.0.90"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a65b3f4ffa0092e9887669db0eae07941f023991ab58ea44da8fe8e2d511c6b"
checksum = "704df27628939572cd88d33f171cd6f896f4eaca85252c6e0a72d8d8287ee86f"
dependencies = [
"proc-macro2",
"quote",
@ -1638,21 +1677,22 @@ dependencies = [
[[package]]
name = "time"
version = "0.1.43"
version = "0.1.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438"
checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255"
dependencies = [
"libc",
"wasi 0.10.0+wasi-snapshot-preview1",
"winapi",
]
[[package]]
name = "time"
version = "0.3.7"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "004cbc98f30fa233c61a38bc77e96a9106e65c88f2d3bef182ae952027e5753d"
checksum = "c2702e08a7a860f005826c6815dcac101b19b5eb330c27fe4a5928fec1d20ddd"
dependencies = [
"itoa",
"itoa 1.0.1",
"libc",
"num_threads",
"time-macros",
@ -1660,9 +1700,9 @@ dependencies = [
[[package]]
name = "time-macros"
version = "0.2.3"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "25eb0ca3468fc0acc11828786797f6ef9aa1555e4a211a60d64cc8e4d1be47d6"
checksum = "42657b1a6f4d817cda8e7a0ace261fe0cc946cf3a80314390b22cc61ae080792"
[[package]]
name = "tinyvec"
@ -1722,48 +1762,47 @@ dependencies = [
[[package]]
name = "tokio-util"
version = "0.6.9"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9e99e1983e5d376cd8eb4b66604d2e99e79f5bd988c3055891dcd8c9e2604cc0"
checksum = "0edfdeb067411dba2044da6d1cb2df793dd35add7888d73c16e3381ded401764"
dependencies = [
"bytes",
"futures-core",
"futures-sink",
"log",
"pin-project-lite",
"tokio",
]
[[package]]
name = "tokio-util"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "64910e1b9c1901aaf5375561e35b9c057d95ff41a44ede043a03e09279eabaf1"
dependencies = [
"bytes",
"futures-core",
"futures-sink",
"log",
"pin-project-lite",
"tokio",
"tracing",
]
[[package]]
name = "tracing"
version = "0.1.31"
version = "0.1.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f6c650a8ef0cd2dd93736f033d21cbd1224c5a967aa0c258d00fcf7dafef9b9f"
checksum = "4a1bdf54a7c28a2bbf701e1d2233f6c77f473486b94bee4f9678da5a148dca7f"
dependencies = [
"cfg-if",
"log",
"pin-project-lite",
"tracing-attributes",
"tracing-core",
]
[[package]]
name = "tracing-core"
version = "0.1.22"
name = "tracing-attributes"
version = "0.1.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03cfcb51380632a72d3111cb8d3447a8d908e577d31beeac006f836383d29a23"
checksum = "2e65ce065b4b5c53e73bb28912318cb8c9e9ad3921f1d669eb0e68b4c8143a2b"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "tracing-core"
version = "0.1.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90442985ee2f57c9e1b548ee72ae842f4a9a20e3f417cc38dbc5dc684d9bb4ee"
dependencies = [
"lazy_static",
]
@ -1833,9 +1872,15 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
[[package]]
name = "wasi"
version = "0.10.2+wasi-snapshot-preview1"
version = "0.10.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
[[package]]
name = "wasi"
version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "wasm-bindgen"
@ -1954,9 +1999,9 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "windows-sys"
version = "0.32.0"
version = "0.34.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3df6e476185f92a12c072be4a189a0210dcdcf512a1891d6dff9edb874deadc6"
checksum = "5acdd78cb4ba54c0045ac14f62d8f94a03d10047904ae2a40afa1e99d8f70825"
dependencies = [
"windows_aarch64_msvc",
"windows_i686_gnu",
@ -1967,33 +2012,33 @@ dependencies = [
[[package]]
name = "windows_aarch64_msvc"
version = "0.32.0"
version = "0.34.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d8e92753b1c443191654ec532f14c199742964a061be25d77d7a96f09db20bf5"
checksum = "17cffbe740121affb56fad0fc0e421804adf0ae00891205213b5cecd30db881d"
[[package]]
name = "windows_i686_gnu"
version = "0.32.0"
version = "0.34.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a711c68811799e017b6038e0922cb27a5e2f43a2ddb609fe0b6f3eeda9de615"
checksum = "2564fde759adb79129d9b4f54be42b32c89970c18ebf93124ca8870a498688ed"
[[package]]
name = "windows_i686_msvc"
version = "0.32.0"
version = "0.34.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "146c11bb1a02615db74680b32a68e2d61f553cc24c4eb5b4ca10311740e44172"
checksum = "9cd9d32ba70453522332c14d38814bceeb747d80b3958676007acadd7e166956"
[[package]]
name = "windows_x86_64_gnu"
version = "0.32.0"
version = "0.34.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c912b12f7454c6620635bbff3450962753834be2a594819bd5e945af18ec64bc"
checksum = "cfce6deae227ee8d356d19effc141a509cc503dfd1f850622ec4b0f84428e1f4"
[[package]]
name = "windows_x86_64_msvc"
version = "0.32.0"
version = "0.34.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "504a2476202769977a040c6364301a3f65d0cc9e3fb08600b2bda150a0488316"
checksum = "d19538ccc21819d01deaf88d6a17eae6596a12e9aafdbb97916fb49896d89de9"
[[package]]
name = "zstd"

View File

@ -1,12 +1,12 @@
[package]
name = "backend"
version = "0.1.0"
version = "1.1.1"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
serde = "1.0"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
actix-rt = "2.6.0"
@ -14,7 +14,9 @@ actix-web = "4.0.0-rc.1"
actix-cors = "0.6.0"
actix-governor = "0.3.0"
sqlx = { version = "0.5", features = ["runtime-tokio-rustls", "postgres", "chrono"] }
badge-maker = "0.2.1"
sqlx = { version = "0.5.11", features = ["runtime-tokio-rustls", "postgres", "chrono"] }
chrono = { version = "0.4.19", features = ["serde"] }
@ -31,4 +33,4 @@ debug-assertions = false
[[bin]]
name = "zer0bin-bin"
path = "src/main.rs"
path = "src/main.rs"

View File

@ -1,21 +0,0 @@
FROM rustlang/rust:nightly-alpine3.15 AS builder
RUN apk update && apk add --no-cache build-base openssl-dev gcompat libc6-compat bash
WORKDIR /build/zer0bin
COPY Cargo.toml .
RUN echo "fn main() {}" >> dummy.rs
RUN sed -i 's#src/main.rs#dummy.rs#' Cargo.toml
ENV RUSTFLAGS=-Ctarget-feature=-crt-static
RUN if [[ $(uname -m) =~ ^arm ]]; then CARGO_INCREMENTAL=1 cargo build --release --target aarch64-unknown-linux-musl; else CARGO_INCREMENTAL=1 cargo build --release; fi
RUN rm dummy.rs && sed -i 's#dummy.rs#src/main.rs#' Cargo.toml
COPY . .
RUN CARGO_INCREMENTAL=1 cargo build --release
FROM alpine:3.15
WORKDIR /app
RUN apk update && apk add --no-cache build-base openssl
COPY --from=builder /build/zer0bin/target/release/zer0bin-bin .
CMD ["/app/zer0bin-bin"]

View File

@ -1,18 +1,22 @@
{
"server": {
"backend_host": "127.0.0.1",
"backend_port": 8000
},
"pastes": {
"character_limit": 40000,
"days_til_expiration": 7,
"id_length": 10
},
"ratelimits": {
"seconds_in_between_pastes": 2,
"allowed_pastes_before_ratelimit": 5
},
"databases": {
"postgres_uri": "postgres://postgres:postgres@localhost:5432/zer0bin"
}
"server": {
"backend_host": "127.0.0.1",
"backend_port": 8000
},
"pastes": {
"character_limit": 50000,
"days_til_expiration": 30,
"id_length": 6
},
"ratelimits": {
"seconds_in_between_pastes": 2,
"allowed_pastes_before_ratelimit": 5
},
"databases": {
"postgres_uri": "postgres://postgres:postgres@localhost:5432/zer0bin"
},
"logging": {
"on_post_paste": true,
"on_get_paste": true
}
}

View File

@ -0,0 +1 @@
ALTER TABLE pastes ADD column single_view BOOLEAN DEFAULT false;

4
backend/schema.sql Executable file → Normal file
View File

@ -5,6 +5,7 @@ CREATE TABLE IF NOT EXISTS pastes (
"expires_at" TIMESTAMP WITHOUT TIME ZONE,
"created_at" TIMESTAMP WITHOUT TIME ZONE DEFAULT(NOW() AT TIME ZONE 'utc')
);
CREATE OR REPLACE FUNCTION deleteExpiredPastes() RETURNS trigger AS $pastes_expire$ BEGIN
DELETE FROM pastes
WHERE "expires_at" IS NOT NULL
@ -12,7 +13,8 @@ WHERE "expires_at" IS NOT NULL
RETURN NEW;
END;
$pastes_expire$ LANGUAGE plpgsql;
CREATE TRIGGER checkPastes BEFORE
INSERT
OR
UPDATE ON pastes FOR STATEMENT EXECUTE PROCEDURE deleteExpiredPastes();
UPDATE ON pastes FOR STATEMENT EXECUTE PROCEDURE deleteExpiredPastes();

View File

@ -8,6 +8,7 @@ pub struct Config {
pub pastes: PastesConfig,
pub ratelimits: RatelimitsConifg,
pub databases: DatabasesConfig,
pub logging: LoggingConfig
}
#[derive(Serialize, Deserialize, Clone)]
@ -34,6 +35,12 @@ pub struct DatabasesConfig {
pub postgres_uri: String,
}
#[derive(Serialize, Deserialize, Clone)]
pub struct LoggingConfig {
pub on_post_paste: bool,
pub on_get_paste: bool
}
pub fn load(path: PathBuf) -> Config {
let file = File::open(path).expect("Failed to load config");
serde_json::from_reader(file).unwrap()

View File

@ -2,7 +2,7 @@ mod config;
mod models;
mod routes;
use std::{io, path::PathBuf};
use std::{io, path::Path, path::PathBuf};
use actix_cors::Cors;
use actix_governor::{Governor, GovernorConfigBuilder};
@ -12,9 +12,11 @@ use actix_web::{
};
use config::Config;
use sqlx::{postgres::PgPoolOptions, PgPool};
use sqlx::{migrate::Migrator, postgres::PgPoolOptions, PgPool};
use crate::routes::{get_paste, get_stats, new_paste};
use crate::routes::{
get_paste, get_raw_paste, get_stats, get_total_pastes_badge, get_version_badge, new_paste,
};
#[derive(Clone)]
pub struct AppState {
@ -22,15 +24,29 @@ pub struct AppState {
pub pool: PgPool,
}
pub async fn migrations(pool: &PgPool) -> Result<(), sqlx::Error> {
Migrator::new(Path::new("./migrations"))
.await?
.run(pool)
.await?;
Ok(())
}
#[actix_rt::main]
async fn main() -> io::Result<()> {
let config = config::load(PathBuf::from("config.json"));
let db_uri = &config.databases.postgres_uri.to_string();
let pool = PgPoolOptions::new()
.max_connections(100)
.connect(&config.databases.postgres_uri)
.connect(db_uri)
.await
.expect("Failed to connect to database");
migrations(&pool).await.expect("Failed to run migrations");
let address = format!(
"{}:{}",
config.server.backend_host, config.server.backend_port
@ -63,7 +79,12 @@ async fn main() -> io::Result<()> {
.wrap(Governor::new(&paste_governor))
.service(get_paste)
.service(new_paste)
// .service(get_raw_paste),
.service(get_raw_paste),
)
.service(
web::scope("/b")
.service(get_version_badge)
.service(get_total_pastes_badge),
)
})
.bind(address)?

View File

@ -7,12 +7,14 @@ pub struct Paste {
pub id: String,
pub content: String,
pub views: i64,
pub single_view: bool,
pub expires_at: Option<NaiveDateTime>,
}
#[derive(Deserialize)]
pub struct PartialPaste {
pub content: String,
pub single_view: bool
}
#[derive(Serialize)]
@ -25,6 +27,7 @@ pub struct ApiResponse<T> {
pub struct NewPasteResponse {
pub id: String,
pub content: String,
pub single_view: bool,
}
#[derive(Serialize)]
@ -32,12 +35,14 @@ pub struct GetPasteResponse {
pub id: String,
pub content: String,
pub views: i64,
pub single_view: bool,
pub expires_at: Option<NaiveDateTime>,
}
#[derive(Serialize)]
pub struct GetStatsResponse {
pub count: i64,
pub version: String,
}
#[derive(Serialize)]

View File

@ -4,8 +4,9 @@ use actix_web::{
HttpResponse, Responder,
};
use chrono::Duration;
use badge_maker::{BadgeBuilder, Style};
use chrono::Duration;
use nanoid::nanoid;
use sqlx::{postgres::PgRow, types::chrono::Utc, Row};
@ -17,33 +18,7 @@ use crate::{
AppState,
};
#[get("/s")]
pub async fn get_stats(state: web::Data<AppState>) -> impl Responder {
// TODO: Maybe there's a less hacky way to do this..?
let count: Result<i64, sqlx::Error> = sqlx::query(r#"SELECT COUNT(*) FROM pastes"#)
.try_map(|row: PgRow| row.try_get::<i64, _>("count"))
.fetch_one(&state.pool)
.await;
if let Err(e) = count {
eprintln!("Error occurred while retrieving paste count: {:?}", e);
return HttpResponse::InternalServerError().json(ApiResponse {
success: false,
data: ApiError {
message: "Error occurred while retrieving paste count, please try again."
.to_string(),
},
});
}
HttpResponse::Ok().json(ApiResponse {
success: true,
data: GetStatsResponse {
count: count.unwrap(),
},
})
}
// Pastes
#[get("/{id}")]
pub async fn get_paste(state: web::Data<AppState>, id: web::Path<String>) -> impl Responder {
@ -57,11 +32,22 @@ pub async fn get_paste(state: web::Data<AppState>, id: web::Path<String>) -> imp
match res {
Ok(p) => {
// this may be worth handling at some point..
let _ = sqlx::query(r#"UPDATE pastes SET "views" = "views" + 1 WHERE "id" = $1"#)
.bind(id.clone())
.execute(&state.pool)
.await;
// Only increment views if its not a single view paste
if p.single_view {
let _ = sqlx::query(r#"DELETE FROM pastes WHERE "id" = $1"#)
.bind(id.clone())
.execute(&state.pool)
.await;
} else {
let _ = sqlx::query(r#"UPDATE pastes SET "views" = "views" + 1 WHERE "id" = $1"#)
.bind(id.clone())
.execute(&state.pool)
.await;
}
if state.config.logging.on_get_paste {
println!("[GET] id={} views={} single_view={}", id, p.views + 1, p.single_view);
}
HttpResponse::Ok().json(ApiResponse {
success: true,
@ -69,6 +55,7 @@ pub async fn get_paste(state: web::Data<AppState>, id: web::Path<String>) -> imp
id: p.id,
content: p.content,
views: p.views + 1,
single_view: p.single_view,
expires_at: p.expires_at,
},
})
@ -96,7 +83,6 @@ pub async fn get_paste(state: web::Data<AppState>, id: web::Path<String>) -> imp
}
}
// TODO: Fix major vuln
#[get("/r/{id}")]
pub async fn get_raw_paste(state: web::Data<AppState>, id: web::Path<String>) -> impl Responder {
let id = id.into_inner();
@ -109,13 +95,25 @@ pub async fn get_raw_paste(state: web::Data<AppState>, id: web::Path<String>) ->
match res {
Ok(p) => {
// this may be worth handling at some point..
let _ = sqlx::query(r#"UPDATE pastes SET "views" = "views" + 1 WHERE "id" = $1"#)
.bind(id.clone())
.execute(&state.pool)
.await;
if p.single_view {
let _ = sqlx::query(r#"DELETE FROM pastes WHERE "id" = $1"#)
.bind(id.clone())
.execute(&state.pool)
.await;
} else {
let _ = sqlx::query(r#"UPDATE pastes SET "views" = "views" + 1 WHERE "id" = $1"#)
.bind(id.clone())
.execute(&state.pool)
.await;
}
HttpResponse::Ok().body(p.content)
if state.config.logging.on_get_paste {
println!("[GET] raw id={} views={} single_view={}", id, p.views + 1, p.single_view);
}
HttpResponse::Ok()
.content_type("text/plain")
.body(p.content)
}
Err(e) => match e {
sqlx::Error::RowNotFound => {
@ -165,41 +163,32 @@ pub async fn new_paste(
Some(Utc::now() + Duration::days(state.config.pastes.days_til_expiration))
};
/*
.replace(/&/g, '&amp;')
.replace(/>/g, '&gt;')
.replace(/</g, '&lt;')
.replace(/"/g, '&quot;');
*/
// let cleaned = data
// .content
// .clone()
// .replace("&", "&amp;")
// .replace("<", "&lt;")
// .replace(">", "&gt;")
// .replace(r#"""#, "&quot;");
let cleaned = data
.content
.clone();
let content = data.content.clone();
let single_view = data.single_view;
let res =
sqlx::query(r#"INSERT INTO pastes("id", "content", "expires_at") VALUES ($1, $2, $3)"#)
sqlx::query(r#"INSERT INTO pastes("id", "content", "single_view", "expires_at") VALUES ($1, $2, $3, $4)"#)
.bind(id.clone())
.bind(cleaned.clone())
.bind(content.clone())
.bind(single_view)
.bind(expires_at)
.execute(&state.pool)
.await;
match res {
Ok(_) => HttpResponse::Ok().json(ApiResponse {
success: true,
data: NewPasteResponse {
id,
content: cleaned,
},
}),
Ok(_) => {
if state.config.logging.on_post_paste {
println!("[POST] id={} length={} single_view={}", id, content.len(), single_view);
}
HttpResponse::Ok().json(ApiResponse {
success: true,
data: NewPasteResponse {
id,
content,
single_view,
},
})
}
Err(e) => {
eprintln!("Error occurred while creating paste: {:?}", e);
@ -212,3 +201,86 @@ pub async fn new_paste(
}
}
}
// Stats
#[get("/s")]
pub async fn get_stats(state: web::Data<AppState>) -> impl Responder {
let version = env!("CARGO_PKG_VERSION").to_string();
// TODO: Maybe there's a less hacky way to do this..?
let count: Result<i64, sqlx::Error> = sqlx::query(r#"SELECT COUNT(*) FROM pastes"#)
.try_map(|row: PgRow| row.try_get::<i64, _>("count"))
.fetch_one(&state.pool)
.await;
if let Err(e) = count {
eprintln!("Error occurred while retrieving paste count: {:?}", e);
return HttpResponse::InternalServerError().json(ApiResponse {
success: false,
data: ApiError {
message: "Error occurred while retrieving paste count, please try again."
.to_string(),
},
});
}
HttpResponse::Ok().json(ApiResponse {
success: true,
data: GetStatsResponse {
count: count.unwrap(),
version,
},
})
}
// Badges
#[get("/v")]
pub async fn get_version_badge() -> impl Responder {
let version = env!("CARGO_PKG_VERSION").to_string();
let badge = BadgeBuilder::new()
.label("version")
.message(&version)
.color_parse("#31748f")
.label_color_parse("#191724")
.style(Style::FlatSquare)
.build()
.expect("Failed to build badge")
.svg();
HttpResponse::Ok().content_type("image/svg+xml").body(badge)
}
#[get("/t")]
pub async fn get_total_pastes_badge(state: web::Data<AppState>) -> impl Responder {
let count: Result<i64, sqlx::Error> = sqlx::query(r#"SELECT COUNT(*) FROM pastes"#)
.try_map(|row: PgRow| row.try_get::<i64, _>("count"))
.fetch_one(&state.pool)
.await;
if let Err(e) = count {
eprintln!("Error occurred while retrieving paste count: {:?}", e);
return HttpResponse::InternalServerError().json(ApiResponse {
success: false,
data: ApiError {
message: "Error occurred while retrieving paste count, please try again."
.to_string(),
},
});
}
let badge = BadgeBuilder::new()
.label("total pastes")
.message(&count.unwrap().to_string())
.color_parse("#ebbcba")
.label_color_parse("#191724")
.style(Style::FlatSquare)
.build()
.expect("Failed to build badge")
.svg();
HttpResponse::Ok().content_type("image/svg+xml").body(badge)
}

View File

@ -1,30 +1,34 @@
# replace `example.tld` with your domain
# replace `/location/of/zer0bin` with the location of the zer0bin folder
# uncomment the `brotli on;` lines if you have the nginx brotoli plugin
# uncomment the `ssl_certificate` lines if you have letsencrypt certs
# comment out line 15 and uncomment line 16 if you have the nginx brotoli plugin
# uncomment lines 51 and 52 if you have letsencrypt certs
server {
#listen 80 is default
server_name www.example.tld;
server_name example.tld;
return 301 https://example.tld$request_uri;
# brotli on;
}
server {
listen 443;
server_name example.tld;
gzip_static on;
# brotli on;
root /location/of/zer0bin/frontend/dist;
rewrite ^/~/(.*)$ /index.html;
rewrite ^/(?!.*api)(?!.*\.).*$ /index.html;
location / {
index index.html;
expires 30d;
add_header Cache-Control "public, no-transform";
}
location ~ \.(css|js|html) {
try_files $uri =404;
expires 30d;
add_header Cache-Control "public, no-transform";
}
location ^~ /.well-known/ {
@ -37,11 +41,13 @@ server {
proxy_pass http://localhost:8000/;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
add_header Last-Modified $date_gmt;
add_header Cache-Control 'no-store, no-cache';
if_modified_since off;
expires off;
etag off;
}
expires 30d;
add_header Cache-Control "public, no-transform";
# ssl_certificate /etc/letsencrypt/live/example.tld/fullchain.pem;
# ssl_certificate_key /etc/letsencrypt/live/example.tld/privkey.pem;
}

View File

@ -1,10 +0,0 @@
{
"extends": "@parcel/config-default",
"compressors": {
"*.{html,css,js,svg,map}": [
"...",
"@parcel/compressor-gzip",
"@parcel/compressor-brotli"
]
}
}

1
frontend/.yarnrc.yml Normal file
View File

@ -0,0 +1 @@
nodeLinker: node-modules

3
frontend/config.example.json Executable file → Normal file
View File

@ -1,3 +1,4 @@
{
"api_url": "https://example.tld/api"
"api_url": "https://yourdomain.tld/api",
"confetti_chance": "10"
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

195
frontend/favicon.svg Normal file
View File

@ -0,0 +1,195 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="256"
height="256"
viewBox="0 0 256 256"
fill="none"
version="1.1"
id="svg12"
sodipodi:docname="zer0bin.svg"
inkscape:version="1.1.2 (0a00cf5339, 2022-02-04, custom)"
inkscape:export-filename="/home/kainoa/Downloads/zer0bin.png"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs16">
<g
id="SVG"
fill="#ffffff"
transform="scale(2) translate(20,79)">
<path
id="S"
d="M 5.482,31.319 C2.163,28.001 0.109,23.419 0.109,18.358 C0.109,8.232 8.322,0.024 18.443,0.024 C28.569,0.024 36.782,8.232 36.782,18.358 L26.042,18.358 C26.042,14.164 22.638,10.765 18.443,10.765 C14.249,10.765 10.850,14.164 10.850,18.358 C10.850,20.453 11.701,22.351 13.070,23.721 L13.075,23.721 C14.450,25.101 15.595,25.500 18.443,25.952 L18.443,25.952 C23.509,26.479 28.091,28.006 31.409,31.324 L31.409,31.324 C34.728,34.643 36.782,39.225 36.782,44.286 C36.782,54.412 28.569,62.625 18.443,62.625 C8.322,62.625 0.109,54.412 0.109,44.286 L10.850,44.286 C10.850,48.480 14.249,51.884 18.443,51.884 C22.638,51.884 26.042,48.480 26.042,44.286 C26.042,42.191 25.191,40.298 23.821,38.923 L23.816,38.923 C22.441,37.548 20.468,37.074 18.443,36.697 L18.443,36.692 C13.533,35.939 8.800,34.638 5.482,31.319 L5.482,31.319 L5.482,31.319 Z" />
<path
id="V"
d="M 73.452,0.024 L60.482,62.625 L49.742,62.625 L36.782,0.024 L47.522,0.024 L55.122,36.687 L62.712,0.024 L73.452,0.024 Z" />
<path
id="G"
d="M 91.792,25.952 L110.126,25.952 L110.126,44.286 L110.131,44.286 C110.131,54.413 101.918,62.626 91.792,62.626 C81.665,62.626 73.458,54.413 73.458,44.286 L73.458,44.286 L73.458,18.359 L73.453,18.359 C73.453,8.233 81.665,0.025 91.792,0.025 C101.913,0.025 110.126,8.233 110.126,18.359 L99.385,18.359 C99.385,14.169 95.981,10.765 91.792,10.765 C87.597,10.765 84.198,14.169 84.198,18.359 L84.198,44.286 L84.198,44.286 C84.198,48.481 87.597,51.880 91.792,51.880 C95.981,51.880 99.380,48.481 99.385,44.291 L99.385,44.286 L99.385,36.698 L91.792,36.698 L91.792,25.952 L91.792,25.952 Z" />
</g>
<clipPath
id="_clipPath_8TWIgR1z3pxinjWBiigzcEIrVJKv9Gq4">
<rect
width="500"
height="500"
id="rect836" />
</clipPath>
<filter
id="Hmac7mZraFWHw0G84Yxj4QuzeTFp0E7Y"
x="-0.22015058"
y="-0.085804489"
width="1.4403012"
height="1.171609"
filterUnits="objectBoundingBox"
color-interpolation-filters="sRGB">
<feGaussianBlur
in="SourceGraphic"
stdDeviation="6.440413594258542"
id="feGaussianBlur843" />
<feOffset
dx="0"
dy="0"
result="pf_100_offsetBlur"
id="feOffset845" />
<feFlood
flood-color="#000000"
flood-opacity="0.65"
id="feFlood847" />
<feComposite
in2="pf_100_offsetBlur"
operator="in"
result="pf_100_dropShadow"
id="feComposite849" />
<feBlend
in="SourceGraphic"
in2="pf_100_dropShadow"
mode="normal"
id="feBlend851" />
</filter>
<linearGradient
id="linearGradient5041">
<stop
style="stop-color:#3e4b4b;stop-opacity:1;"
offset="0"
id="stop5043" />
<stop
style="stop-color:#1e3449;stop-opacity:1;"
offset="1"
id="stop5045" />
</linearGradient>
<radialGradient
r="640"
fy="825.16089"
fx="293.49887"
cy="825.16089"
cx="293.49887"
gradientTransform="matrix(2.7998301,-1.4738538,0.45507806,0.86449643,-926.2596,769.338)"
gradientUnits="userSpaceOnUse"
id="radialGradient3133"
xlink:href="#linearGradient4453-1"
inkscape:collect="always" />
<linearGradient
id="linearGradient4453-1">
<stop
id="stop4455-4"
offset="0"
style="stop-color:#070808;stop-opacity:1" />
<stop
id="stop4457-0"
offset="1"
style="stop-color:#152534;stop-opacity:1" />
</linearGradient>
</defs>
<sodipodi:namedview
id="namedview14"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
showgrid="false"
inkscape:zoom="1.28"
inkscape:cx="111.32812"
inkscape:cy="116.40625"
inkscape:window-width="1183"
inkscape:window-height="686"
inkscape:window-x="1353"
inkscape:window-y="730"
inkscape:window-maximized="1"
inkscape:current-layer="svg12" />
<rect
style="fill:#191724;fill-opacity:1;stroke:#9ccfd8;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect2248"
width="256"
height="256"
x="0"
y="0" />
<g
inkscape:label="Layer 1"
id="layer1"
style="display:none"
transform="translate(-606.58583,-699.5242)">
<image
y="392.14789"
x="-90.714287"
id="image3047"
xlink:href="../../tomasi/Projects/nimrod/logo/new-symbols.png"
height="329"
width="800" />
</g>
<path
inkscape:connector-curvature="0"
d="m 602.64247,29.71093 h -28.65 v 7.28362 c 0,1.59787 0.4668,2.98732 1.4003,4.16834 0.9336,1.18104 2.0863,1.84067 3.4542,1.77155 h 23.6088 v 5.013 h -25.1124 c -2.2405,0 -4.1698,-0.86841 -5.7879,-2.60522 -1.556,-1.80627 -2.3339,-3.95992 -2.3339,-6.46093 V 14.28805 c 0,-2.50097 0.7779,-4.61988 2.3339,-6.35673 1.6181,-1.80625 3.5474,-2.70938 5.7879,-2.70942 h 17.1773 c 2.2405,4e-5 4.1387,0.90317 5.6946,2.70942 1.6181,1.73685 2.4272,3.85576 2.4272,6.35673 v 15.42288 m -4.9576,-4.59617 V 16.1748 c 0,-1.59784 -0.4668,-2.98729 -1.4003,-4.16836 -0.9336,-1.18099 -2.1161,-1.77151 -3.5475,-1.77154 h -13.8901 c -1.3693,3e-5 -2.5206,0.59055 -3.4542,1.77154 -0.9335,1.18107 -1.6566,2.59635 -1.4003,4.16836 v 8.93996 h 23.6924 m -40.8208,-41.56827 -0.093,64.40095 h -25.4857 c -2.2406,0 -4.1699,-0.86841 -5.788,-2.60522 -1.5559,-1.80627 -2.3339,-3.95992 -2.3339,-6.46093 l 0.093,-24.59324 c 0.062,-2.50097 0.8713,-4.61988 2.4272,-6.35673 1.5559,-1.80625 3.4541,-2.70938 5.6947,-2.70942 h 20.3414 l 0.093,-21.67541 h 5.051 m -5.1444,59.80479 -0.093,-33.53321 h -18.7445 c -1.3692,4e-5 -2.5206,0.66002 -3.4542,1.97996 -0.9335,1.32001 -1.4003,2.77893 -1.4003,4.37677 l 0.093,20.81975 c 0,1.59787 0.4357,3.05679 1.307,4.37675 0.8713,1.31999 1.9915,1.97998 3.3608,1.97998 h 18.9312 m -40.4211,-4.46999 c 0,2.50101 -0.8091,4.65466 -2.4272,6.46093 -1.5559,1.73681 -3.4541,2.60522 -5.6946,2.60522 h -19.0443 c -2.2406,0 -4.1699,-0.86841 -5.788,-2.60522 -1.5559,-1.80627 -2.3339,-3.95992 -2.3339,-6.46093 V 14.28805 c 0,-2.50097 0.778,-4.61988 2.3339,-6.35673 1.6181,-1.80625 3.5474,-2.70938 5.788,-2.70942 h 19.0443 c 2.2405,4e-5 4.1387,0.90317 5.6946,2.70942 1.6181,1.73685 2.4272,3.85576 2.4272,6.35673 v 24.59324 m -4.9576,-1.88674 V 16.1748 c 0,-1.59784 -0.4668,-2.98729 -1.4003,-4.16836 -0.9336,-1.18099 -2.1161,-1.77151 -3.5475,-1.77154 h -15.7572 c -1.3692,3e-5 -2.5206,0.59055 -3.4541,1.77154 -0.9336,1.18107 -1.4004,2.57052 -1.4004,4.16836 v 20.81975 c 0,1.59787 0.4668,2.98732 1.4004,4.16834 0.9335,1.18104 2.0849,1.77155 3.4541,1.77155 h 15.7572 c 1.4314,0 2.6139,-0.59051 3.5475,-1.77155 0.9335,-1.18102 1.4003,-2.57047 1.4003,-4.16834 m -43.2742,-8.62734 h -4.9577 V 16.1748 c 0,-1.59784 -0.4667,-2.98729 -1.4003,-4.16836 -0.9335,-1.18099 -2.116,-1.77151 -3.5474,-1.77154 h -13.8902 c -1.3692,3e-5 -2.5206,0.59055 -3.4541,1.77154 -0.9336,1.18107 -1.4003,2.57052 -1.4003,4.16836 v 20.81975 c 0,1.59787 0.4667,2.98732 1.4003,4.16834 0.9335,1.18104 2.0849,1.77155 3.4541,1.77155 h 23.5155 l 0.093,5.013 h -25.1124 c -2.2405,0 -4.1698,-0.86841 -5.7879,-2.60522 -1.5559,-1.80627 -2.3339,-3.95992 -2.3339,-6.46093 V 14.28805 c 0,-2.50097 0.778,-4.61988 2.3339,-6.35673 1.6181,-1.80625 3.5474,-2.70938 5.7879,-2.70942 h 17.1773 c 2.2405,4e-5 4.1387,0.90317 5.6946,2.70942 1.6181,1.73685 2.4272,3.85576 2.4272,6.35673 v 14.07916"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:87.357px;line-height:125%;font-family:Discognate;-inkscape-font-specification:Discognate;letter-spacing:0px;word-spacing:0px;display:none;fill:#ffffff;fill-opacity:1;stroke:none"
id="path4870" />
<g
id="g881"
transform="translate(-2.593955,-1.015618)">
<path
fill="currentColor"
d="m 130.59396,234.67648 c -55.515318,0 -78.87335,-25.08496 -78.87335,-105.66087 0,-80.575902 23.358032,-105.660854 78.87335,-105.660854 55.51531,0 78.87334,25.084952 78.87334,105.660854 0,80.57591 -23.35803,105.66087 -78.87334,105.66087 z m 0,-29.18977 c 32.79723,0 48.15593,-11.40225 48.15593,-76.4711 0,-65.068838 -15.3587,-76.471096 -48.15593,-76.471096 -32.797246,0 -48.15594,11.402258 -48.15594,76.471096 0,65.06885 15.358694,76.4711 48.15594,76.4711 z"
id="path1181"
style="fill:#9ccfd8;fill-opacity:1;stroke-width:0.155958"
sodipodi:nodetypes="ssssssssss" />
<g
id="g1392"
transform="matrix(1.9416434,-0.45122023,0.48590571,2.0908983,88.365407,95.983077)">
<path
fill="#c1694f"
d="M 3.968,33.446 C 2.211,35.204 0.47,36.312 0.079,35.921 -0.312,35.53 0.797,33.789 2.554,32.032 4.311,30.274 6.052,29.166 6.443,29.557 6.833,29.948 5.725,31.688 3.968,33.446 Z"
id="path1368"
style="fill:#eb6f92;fill-opacity:1" />
<path
fill="#ffcc4d"
d="M 6.443,29.558 4.321,27.436 c 0,0 -1.083,1.393 -2.284,3.63 -0.9,1.676 -1.251,2.734 -1.251,2.734 l 0.707,0.707 0.707,0.707 c 0,0 1.059,-0.352 2.734,-1.251 2.237,-1.201 3.629,-2.284 3.629,-2.284 z"
id="path1370"
style="fill:#f6c177;fill-opacity:1" />
<path
fill="#31373d"
d="m 34.02,1.98 c -3.535,-3.536 -18.164,10.297 -18.871,11.004 -0.707,0.707 -1.304,1.348 -0.928,1.724 L 12.1,16.829 C 9.978,18.951 3.614,26.728 4.321,27.435 l 2.122,2.122 2.121,2.121 c 0.707,0.707 8.485,-5.657 10.607,-7.778 l 2.121,-2.121 c 0.376,0.376 1.017,-0.222 1.724,-0.929 C 23.723,20.144 37.556,5.516 34.02,1.98 Z"
id="path1372"
style="fill:#31748f;fill-opacity:1" />
<path
fill="#ffcc4d"
d="m 23.016,20.851 c 0.085,-0.084 0.362,-0.375 0.774,-0.817 l -7.823,-7.822 c -0.442,0.411 -0.732,0.689 -0.817,0.774 -0.707,0.707 -1.304,1.348 -0.928,1.724 l 3.535,3.536 3.536,3.535 c 0.375,0.374 1.016,-0.223 1.723,-0.93 z"
id="path1374"
style="fill:#f6c177;fill-opacity:1" />
<path
fill="#ffac33"
d="M 31.212,2.001 C 30.285,1.074 29.048,0.102 27.28,0.986 25.512,1.87 19.967,5.427 17.402,7.991 c -1.322,1.322 -1.247,2.102 -0.751,2.165 0.821,0.106 1.37,0.088 2.122,-0.663 0.75,-0.751 0.883,-2.033 0.883,-2.033 0,0 3.05,-2.342 5.458,-3.778 2.409,-1.437 3.268,-1.682 4.11,-0.84 0.842,0.842 1.988,-0.841 1.988,-0.841 z"
id="path1376"
style="fill:#ebbcba;fill-opacity:1" />
<path
fill="#ffac33"
d="m 28.87,2.487 4.643,4.643 c 0.353,-0.709 0.631,-1.384 0.818,-2.011 l -3.45,-3.45 C 30.254,1.857 29.58,2.135 28.87,2.487 Z"
id="path1378"
style="fill:#ebbcba;fill-opacity:1" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Binary file not shown.

5
frontend/index.html Normal file
View File

@ -0,0 +1,5 @@
<!DOCTYPE html>
<link rel="icon" type="image/x-icon" href="/favicon.svg" />
<link rel="stylesheet" href="/style/style.scss" />
<script type="module" src="/src/index.ts" defer></script>
<pug src="index.pug"></pug>

View File

@ -1,39 +1,57 @@
doctype html
head
meta(charset='UTF-8')
meta(name='viewport' content='width=device-width, initial-scale=1.0')
title zer0bin
link(rel='shortcut icon' type='image/x-icon' href='favicon.ico')
meta(name='theme-color' content='#90BDC9')
meta(name='keywords' content='zerobin, zer0bin, paste, paste bin, pastebin, pastebin alternative, foss pastebin, open source pastebin, free pastebin, ghostbin, hastebin, pastebin.com, free pastebin online, paste online, github paste, github gist, github gist paste')
link(href='style/style.scss' rel='stylesheet')
link(href='style/rosepine.min.css' rel='stylesheet')
meta(name='title' content='zer0bin')
meta(name='description' content='🖊 Just a place to paste')
meta(property='og:type' content='website')
meta(property='og:title' content='zer0bin')
meta(property='og:description' content='🖊 Just a place to paste')
meta(property='og:image' content='https://raw.githubusercontent.com/zer0bin-dev/.github/main/zer0bin.png')
meta(property='twitter:title' content='zer0bin')
meta(property='twitter:description' content='🖊 Just a place to paste')
meta(property='twitter:image' content='https://raw.githubusercontent.com/zer0bin-dev/.github/main/zer0bin.png')
script(defer='' type='module' src='src/index.ts')
!= '<!--\n'
!= '▀▀█ █▀▀ █▀▀█ █▀▀█ █▀▀▄ ▀ █▀▀▄ \n'
!= '▄▀ █▀▀ █▄▄▀ █▄▀█ █▀▀▄ █ █ █ \n'
!= '▀▀▀ ▀▀▀ ▀ ▀▀ █▄▄█ ▀▀▀ ▀ ▀ ▀ \n'
!= 'Thank you for using zer0bin!\n'
!= 'If you\'re reading this message, why not help with development?\n'
!= 'https://github.com/zer0bin-dev/zer0bin'
!= '\n-->\n'
ul.noselect#messages
.button-wrapper.noselect(style='position: fixed')
a.logo.noselect(href='/') zer0bin
.buttons.noselect
button#save-button.btn(aria-label='Save')
a(href='/' aria-label='New paste')
button#new-button.btn(aria-label='New paste')
button#copy-button.btn(aria-label='Copy')
a(href='https://github.com/zer0bin-dev/zer0bin' aria-label='GitHub repo')
button#github-button.btn(aria-label='GitHub')
span.viewcounter.noselect#viewcounter-label Views:&nbsp;
span.viewcounter.noselect#viewcounter-count
.scrollbar-container
.wrapper
.line-numbers.noselect
pre#code-view-pre
code#code-view
textarea#text-area(spellcheck='false' autofocus='' name='value' aria-label='Paste input area')
html(lang='en')
head
meta(charset='UTF-8')
meta(name='viewport' content='width=device-width, initial-scale=1.0')
title zer0bin
meta(name='theme-color' content='#90BDC9')
meta(name='keywords' content='zerobin, zer0bin, paste, paste bin, pastebin, pastebin alternative, foss pastebin, open source pastebin, free pastebin, ghostbin, hastebin, pastebin.com, free pastebin online, paste online, github paste, github gist, github gist paste')
meta(name='darkreader' content='NO-DARKREADER-PLUGIN')
meta(name='title' content='zer0bin')
meta(name='description' content='🖊 Just a place to paste')
meta(property='og:type' content='website')
meta(property='og:title' content='zer0bin')
meta(property='og:description' content='🖊 Just a place to paste')
meta(property='og:image' content='https://raw.githubusercontent.com/zer0bin-dev/.github/main/zer0bin.png')
meta(property='twitter:title' content='zer0bin')
meta(property='twitter:description' content='🖊 Just a place to paste')
meta(property='twitter:image' content='https://raw.githubusercontent.com/zer0bin-dev/.github/main/zer0bin.png')
body
ul.noselect#messages
.button-wrapper.noselect()
a.logo.noselect(href='/') zer0bin
.buttons.noselect
button#save-button.btn(aria-label='Save')
button#markdown-button.btn(aria-label='Markdown')
button#single-view-button.btn(aria-label='Single View')
//- .fireBody(style='visibility: hidden')
//- - var parts = 20;
//- - while (parts--) {
//- .particle
//- - }
button#new-button.btn(aria-label='New paste')
button#copy-button.btn(aria-label='Copy')
button#share-button.btn(aria-label='Share')
a(href='https://github.com/zer0bin-dev/zer0bin' aria-label='GitHub repo')
button#github-button.btn(aria-label='GitHub')
span.viewcounter.noselect#viewcounter-label(style='visibility: hidden; display: none') Views:&nbsp;
span.viewcounter.noselect#viewcounter-count(style='visibility: hidden; display: none')
.bottom-button-wrapper
button#hide-button.btn(aria-label='Hide')
.scrollbar-container
.wrapper
.line-numbers.noselect
pre#code-view-pre(style='visibility: hidden')
code#code-view
textarea#text-area(spellcheck='false' autofocus='' name='value' aria-label='Paste input area' disabled='' style='visibility: hidden')

View File

@ -1,31 +1,33 @@
{
"name": "zer0bin",
"source": "index.pug",
"version": "0.6.0",
"version": "1.1.1",
"browserslist": "> 0.5%, last 2 versions, not dead",
"license": "MIT",
"scripts": {
"start": "parcel index.pug",
"build": "parcel build index.pug"
"dev": "vite",
"build": "vite build",
"preview": "vite preview"
},
"devDependencies": {
"@parcel/compressor-brotli": "^2.3.2",
"@parcel/compressor-gzip": "^2.3.2",
"@parcel/config-default": "^2.3.2",
"@parcel/transformer-pug": "2.3.2",
"@parcel/transformer-sass": "^2.3.2",
"@types/core-js": "^2.5.5",
"@types/node": "^17.0.21",
"parcel": "^2.3.2"
"pug": "^3.0.2",
"sass": "^1.50.0",
"vite": "^2.9.0",
"vite-plugin-compression": "^0.5.1",
"vite-plugin-pug": "^0.3.1"
},
"description": "just a place to paste",
"repository": "https://github.com/Domterion/zer0bin",
"repository": "https://github.com/zer0bin-dev/zer0bin",
"author": "Domterion, ThatOneCalculator",
"dependencies": {
"@ant-design/icons": "^4.7.0",
"@ant-design/icons-svg": "^4.2.1",
"highlight.js": "^11.4.0",
"highlight.js": "^11.5.0",
"js-confetti": "^0.10.2",
"smooth-scrollbar": "^8.7.4"
"marked": "^4.0.12",
"no-darkreader": "^1.0.1",
"smooth-scrollbar": "^8.7.4",
"tippy.js": "^6.3.7"
}
}

2
frontend/src/env.d.ts vendored Normal file
View File

@ -0,0 +1,2 @@
declare const API_URL: string
declare const CONFETTI_CHANCE: string

161
frontend/src/icons.ts Normal file
View File

@ -0,0 +1,161 @@
import {
SaveOutlined,
FileAddOutlined,
GithubOutlined,
CopyOutlined,
ForkOutlined,
HeartOutlined,
StarOutlined,
EyeOutlined,
EyeInvisibleOutlined,
FireOutlined,
FileMarkdownOutlined,
ShareAltOutlined,
} from "@ant-design/icons-svg"
import { renderIconDefinitionToSVGElement } from "@ant-design/icons-svg/es/helpers"
import tippy from "tippy.js"
import "../style/tooltip.scss"
import "tippy.js/animations/scale.css"
import { IconDefinition } from "@ant-design/icons-svg/lib/types"
const saveButton = <HTMLButtonElement>document.getElementById("save-button")
const newButton = <HTMLButtonElement>document.getElementById("new-button")
const copyButton = <HTMLButtonElement>document.getElementById("copy-button")
const hideButton = <HTMLButtonElement>document.getElementById("hide-button")
const githubButton = <HTMLButtonElement>document.getElementById("github-button")
const shareButton = <HTMLButtonElement>document.getElementById("share-button")
const markdownButton = <HTMLButtonElement>(
document.getElementById("markdown-button")
)
const singleViewButton = <HTMLButtonElement>(
document.getElementById("single-view-button")
)
const extraSVGAttrs = {
width: "1em",
height: "1em",
fill: "currentColor",
}
function renderIcon(elem: HTMLButtonElement, icon: IconDefinition) {
elem.innerHTML += renderIconDefinitionToSVGElement(icon, {
extraSVGAttrs: extraSVGAttrs,
})
}
renderIcon(saveButton, SaveOutlined)
renderIcon(newButton, FileAddOutlined)
renderIcon(copyButton, CopyOutlined)
renderIcon(githubButton, GithubOutlined)
renderIcon(hideButton, EyeInvisibleOutlined)
renderIcon(markdownButton, FileMarkdownOutlined)
renderIcon(singleViewButton, FireOutlined)
renderIcon(shareButton, ShareAltOutlined)
tippy("#save-button", {
content: "Save paste<br><span class='keybind'>Ctrl + S</span>",
placement: "bottom",
animation: "scale",
theme: "rosepine",
allowHTML: true,
})
tippy("#markdown-button", {
content: "Markdown mode<br><span class='keybind'>Ctrl + M</span>",
placement: "bottom",
animation: "scale",
theme: "rosepine",
allowHTML: true,
})
tippy("#single-view-button", {
content:
"Single view<br><span class='keybind'>Deletes after seen 👻</span>",
placement: "bottom",
animation: "scale",
theme: "rosepine",
allowHTML: true,
})
tippy("#new-button", {
content: "New paste<br><span class='keybind'>Ctrl + N</span>",
placement: "bottom",
animation: "scale",
theme: "rosepine",
allowHTML: true,
})
tippy("#copy-button", {
content: "Duplicate paste<br><span class='keybind'>Ctrl + D</span>",
placement: "bottom",
animation: "scale",
theme: "rosepine",
allowHTML: true,
})
tippy("#share-button", {
content: `Share paste<br><span class='keybind'>Copies URL</span>`,
placement: "top",
animation: "scale",
theme: "rosepine",
allowHTML: true,
})
tippy("#github-button", {
content: `GitHub<br><span class='keybind'>
${renderIconDefinitionToSVGElement(StarOutlined, {
extraSVGAttrs: extraSVGAttrs,
})} ${renderIconDefinitionToSVGElement(ForkOutlined, {
extraSVGAttrs: extraSVGAttrs,
})} ${renderIconDefinitionToSVGElement(HeartOutlined, {
extraSVGAttrs: extraSVGAttrs,
})}</span>`,
placement: "bottom",
animation: "scale",
theme: "rosepine",
allowHTML: true,
})
tippy("#hide-button", {
content: "Hide the button pane",
placement: "top",
animation: "scale",
theme: "rosepine",
allowHTML: true,
})
const observer = new MutationObserver(callback)
function callback() {
let theme = ""
if (window.location.pathname == "/") {
theme = "rosepine"
} else {
theme = "rosepine-extended"
}
document.querySelectorAll("button").forEach(function (btn) {
//@ts-ignore
btn._tippy.setProps({ theme: theme })
})
}
observer.observe(document.getElementById("code-view-pre"), {
attributes: true,
})
export function toggleHiddenIcon(hidden: boolean) {
if (!hidden) {
hideButton.innerHTML = renderIconDefinitionToSVGElement(
EyeInvisibleOutlined,
{
extraSVGAttrs: extraSVGAttrs,
}
)
} else {
hideButton.innerHTML = renderIconDefinitionToSVGElement(EyeOutlined, {
extraSVGAttrs: extraSVGAttrs,
})
}
}

View File

@ -1,21 +1,26 @@
import {
SaveOutlined,
FileAddOutlined,
GithubOutlined,
CopyOutlined,
} from "@ant-design/icons-svg"
import { renderIconDefinitionToSVGElement } from "@ant-design/icons-svg/es/helpers"
import hljs from "highlight.js"
import "no-darkreader"
import { marked } from "marked"
import JSConfetti from "js-confetti"
import Scrollbar from "smooth-scrollbar"
const config = require("../config.json")
const apiUrl = config.api_url
import "./icons"
import hljs from "highlight.js/lib/common"
// import hljs from "../min/highlight.min"
import "../min/rosepine.min.css"
import { toggleHiddenIcon } from "./icons"
let rawContent = ""
let buttonPaneHidden = false
let isMarkdown = false
let singleView = false
const jsConfetti = new JSConfetti()
global.rawContent = ""
const lineNumbers = <HTMLElement>document.querySelector(".line-numbers")
const wrapper = <HTMLPreElement>document.querySelector(".wrapper")
const buttonWrapper = <HTMLPreElement>document.querySelector(".button-wrapper")
const editor = <HTMLTextAreaElement>document.getElementById("text-area")
const codeViewPre = <HTMLPreElement>document.getElementById("code-view-pre")
const codeView = <HTMLElement>document.getElementById("code-view")
@ -29,33 +34,23 @@ const viewCounter = <HTMLSpanElement>(
const saveButton = <HTMLButtonElement>document.getElementById("save-button")
const newButton = <HTMLButtonElement>document.getElementById("new-button")
const copyButton = <HTMLButtonElement>document.getElementById("copy-button")
const githubButton = <HTMLButtonElement>document.getElementById("github-button")
const extraSVGAttrs = {
width: "1em",
height: "1em",
fill: "currentColor",
}
saveButton.innerHTML += renderIconDefinitionToSVGElement(SaveOutlined, {
extraSVGAttrs: extraSVGAttrs,
})
newButton.innerHTML += renderIconDefinitionToSVGElement(FileAddOutlined, {
extraSVGAttrs: extraSVGAttrs,
})
copyButton.innerHTML += renderIconDefinitionToSVGElement(CopyOutlined, {
extraSVGAttrs: extraSVGAttrs,
})
githubButton.innerHTML += renderIconDefinitionToSVGElement(GithubOutlined, {
extraSVGAttrs: extraSVGAttrs,
})
const hideButton = <HTMLButtonElement>document.getElementById("hide-button")
const shareButton = <HTMLButtonElement>document.getElementById("share-button")
const markdownButton = <HTMLButtonElement>(
document.getElementById("markdown-button")
)
const singleViewButton = <HTMLButtonElement>(
document.getElementById("single-view-button")
)
function hide(element: HTMLElement) {
element.style.display = "none"
element.style.visibility = "hidden"
element.style.opacity = "0"
}
function show(element: HTMLElement) {
element.style.display = null;
element.style.visibility = "visible"
element.style.opacity = "1"
}
function disable(element: HTMLButtonElement) {
@ -67,8 +62,8 @@ function enable(element: HTMLButtonElement) {
}
async function postPaste(content: string, callback: Function) {
const payload = { content }
await fetch(`${apiUrl}/p/n`, {
const payload = { content, single_view: singleView }
await fetch(`${API_URL}/p/n`, {
method: "POST",
headers: {
"Content-Type": "application/json",
@ -77,17 +72,22 @@ async function postPaste(content: string, callback: Function) {
})
.then((response) => response.json())
.then((data) => {
callback(null, data)
if (data["success"]) {
callback(null, data)
return
}
callback(data || { data: { message: "An unkown error occured!" } })
})
.catch((error) => {
callback(
error || `{"data": { "message": "An unkown error occured!" } }`
)
.catch(() => {
callback({
data: { message: "An API error occurred, please try again." },
})
})
}
async function getPaste(id: string, callback: Function) {
await fetch(`${apiUrl}/p/${id}`, {
await fetch(`${API_URL}/p/${id}`, {
method: "GET",
headers: {
"Content-Type": "application/json",
@ -96,12 +96,16 @@ async function getPaste(id: string, callback: Function) {
})
.then((response) => response.json())
.then((data) => {
callback(null, data)
if (data["success"]) {
callback(null, data)
return
}
callback(data || { data: { message: "An unkown error occured!" } })
})
.catch((error) => {
callback(
error || `{"data": { "message": "An unkown error occured!" } }`
)
.catch(() => {
callback({
data: { message: "An API error occurred, please try again." },
})
})
}
@ -113,20 +117,23 @@ function newPaste() {
enable(saveButton)
disable(newButton)
disable(copyButton)
disable(shareButton)
enable(singleViewButton)
editor.value = ""
global.rawContent = ""
rawContent = ""
wrapper.classList.add("text-area-proper")
show(editor)
editor.disabled = false
hide(codeViewPre)
hide(viewCounterLabel)
hide(viewCounter)
viewCounterLabel.style.display = "none"
viewCounter.style.display = "none"
}
function addMessage(message: string) {
console.log("L")
let msg = document.createElement("li")
msg.innerHTML = message
messages.insertBefore(msg, messages.firstChild)
@ -139,25 +146,55 @@ function addMessage(message: string) {
}, 3000)
}
function viewPaste(content: string, views: string) {
function viewPaste(content: string, views: string, singleView: boolean) {
lineNumbers.innerHTML = ""
for (let i = 1; i <= content.split("\n").length; i++) {
lineNumbers.innerHTML =
lineNumbers.innerHTML +
`${i}
<br>`
if (
content.startsWith("---") ||
content.startsWith("md ") ||
content.startsWith("md\n")
) {
codeView.innerHTML = marked.parse(content.substring(3))
} else {
for (let i = 1; i <= content.split("\n").length; i++) {
lineNumbers.innerHTML = lineNumbers.innerHTML + `${i}<br>`
}
codeView.innerHTML = hljs.highlightAuto(content).value
}
codeView.innerHTML = hljs.highlightAuto(content).value
viewCounter.textContent = views.trim()
if (singleView) {
show(singleViewButton.firstElementChild as HTMLElement)
singleViewButton.lastElementChild.classList.add("fire")
addMessage("This is a single-view paste!")
}
enable(shareButton)
shareButton.addEventListener("click", function () {
const url = window.location.toString()
if (navigator.canShare) {
navigator.share({
title: "zer0bin paste",
url: url,
})
} else {
navigator.clipboard.writeText(url)
addMessage("Copied URL to clipboard!")
}
})
disable(saveButton)
disable(markdownButton)
enable(newButton)
enable(copyButton)
disable(singleViewButton)
hide(editor)
show(codeViewPre)
show(viewCounterLabel)
show(viewCounter)
viewCounterLabel.style.display = null
viewCounter.style.display = null
viewCounter.textContent = views
try {
wrapper.classList.remove("text-area-proper")
@ -166,27 +203,26 @@ function viewPaste(content: string, views: string) {
Scrollbar.init(document.querySelector(".scrollbar-container"))
}
saveButton.addEventListener("click", async function () {
async function savePaste() {
if (editor.value === "") {
return
}
const val: string = editor.value?.toString()!
await postPaste(val, function (err, res) {
console.log(res)
if (err) {
addMessage(err["data"]["message"])
} else {
window.history.pushState(null, "", `/~/${res["data"]["id"]}`)
window.history.pushState(null, "", `/${res["data"]["id"]}`)
global.rawContent = res["data"]["content"]
viewPaste(global.rawContent, "0")
const rand = Math.floor(Math.random() * 40)
if ([1, 2, 3, 4].includes(rand)) {
rawContent = res["data"]["content"]
viewPaste(rawContent, "0", res["data"]["single_view"])
const rand = Math.floor(
Math.random() * parseInt(CONFETTI_CHANCE ?? "10") * 6
)
if (rand < 5) {
jsConfetti.addConfetti({
confettiColors: [
"#eb6f92",
@ -203,34 +239,60 @@ saveButton.addEventListener("click", async function () {
})
} else if (rand === 6) {
jsConfetti.addConfetti({
emojis: ["🐢", "🚀", "✨"],
emojis: ["🐈", "🧶", "📦"],
})
}
}
})
})
copyButton.addEventListener("click", function () {
const content = editor.value
}
async function duplicatePaste() {
const content = rawContent
window.history.pushState(null, "", "/")
newPaste()
global.rawContent = content
rawContent = content
editor.value = content
}
function toggleMarkdown() {
let val = editor.value
markdownButton.lastElementChild.classList.toggle("markdown")
if (isMarkdown) {
isMarkdown = false
val = val.substring(val.indexOf("\n") + 1)
} else {
isMarkdown = true
val = `---\n${val}`
}
}
saveButton.addEventListener("click", async function () {
await savePaste()
})
newButton.addEventListener("click", function () {
window.location.href = "/"
document.addEventListener("keydown", (e) => {
if (e.ctrlKey && e.code === "KeyS") {
e.preventDefault()
savePaste()
} else if (e.ctrlKey && e.code === "KeyN") {
e.preventDefault()
newPaste()
} else if (e.ctrlKey && e.code === "KeyD") {
e.preventDefault()
duplicatePaste()
} else if (e.ctrlKey && e.code === "KeyM") {
e.preventDefault()
toggleMarkdown()
}
})
editor.addEventListener(
"keydown",
function (e: KeyboardEvent) {
if (e.key == "Tab") {
if (e.code == "Tab") {
e.preventDefault()
let start: number = this.selectionStart
let end: number = this.selectionEnd
@ -245,6 +307,41 @@ editor.addEventListener(
false
)
copyButton.addEventListener("click", async function () {
await duplicatePaste()
})
newButton.addEventListener("click", function () {
window.location.href = "/"
})
hideButton.addEventListener("click", function () {
if (!buttonPaneHidden) {
buttonPaneHidden = true
hide(buttonWrapper)
} else {
buttonPaneHidden = false
show(buttonWrapper)
}
toggleHiddenIcon(buttonPaneHidden)
})
markdownButton.addEventListener("click", function () {
toggleMarkdown()
})
singleViewButton.addEventListener("click", function () {
singleViewButton.lastElementChild.classList.toggle("fire")
if (singleView) {
singleView = false
hide(singleViewButton.firstElementChild as HTMLElement)
} else {
singleView = true
show(singleViewButton.firstElementChild as HTMLElement)
}
})
async function handlePopstate() {
const path = window.location.pathname
@ -252,7 +349,6 @@ async function handlePopstate() {
newPaste()
} else {
const split = path.split("/")
const id = split[split.length - 1]
await getPaste(id, function (err, res) {
@ -260,8 +356,12 @@ async function handlePopstate() {
window.history.pushState(null, "", `/`)
newPaste()
} else {
global.rawContent = res["data"]["content"]
viewPaste(global.rawContent, res["data"]["views"].toString())
rawContent = res["data"]["content"]
viewPaste(
rawContent,
res["data"]["views"].toString(),
res["data"]["single_view"]
)
}
})
}

View File

@ -24,7 +24,7 @@
// "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
/* Modules */
"module": "es6" /* Specify what module code is generated. */,
"module": "esnext" /* Specify what module code is generated. */,
// "rootDir": "./", /* Specify the root folder within your source files. */
"moduleResolution": "node" /* Specify how TypeScript looks up a file from a given module specifier. */,
// "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */

View File

@ -0,0 +1,7 @@
@font-face {
font-family: "Cartograph CF";
src: url("../fonts/FiraCode-VF.woff2") format("woff2");
font-weight: normal;
font-style: normal;
font-display: swap;
}

14
frontend/style/font.scss Normal file
View File

@ -0,0 +1,14 @@
@font-face {
font-family: "Cartograph CF";
src: url("../fonts/CartographCF-Regular.woff2") format("woff2");
font-weight: normal;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: "Cartograph CF";
src: url("../fonts/CartographCF-RegularItalic.woff2") format("woff2");
font-weight: normal;
font-style: italic;
font-display: swap;
}

View File

@ -1,13 +1,3 @@
@font-face {
font-family: "Cartograph CF";
src: url("../fonts/CartographCF-Regular.woff2") format("woff2"),
url("../fonts/CartographCF-Regular.woff") format("woff"),
url("../fonts/CartographCF-Regular.ttf") format("truetype");
font-weight: normal;
font-style: normal;
font-display: swap;
}
$love: #eb6f92;
$gold: #f6c177;
$rose: #ebbcba;
@ -24,6 +14,8 @@ $bg_trans: rgba(31, 29, 46, 0.8);
$font-mono: "Cartograph CF", ui-monospace, SFMono-Regular, Menlo, Monaco,
Consolas, "Liberation Mono", "Courier New", monospace;
@import "./font.scss";
@keyframes rainbow {
0%,
100% {
@ -88,7 +80,7 @@ pre {
text-align: end;
user-select: none;
font-size: 15px;
padding-right: 8px;
padding-right: 11px;
line-height: 1.5em;
}
#code-view-pre {
@ -126,20 +118,22 @@ textarea {
width: 100%;
height: 100%;
padding: 0;
padding-left: 1rem;
margin: 0;
border: none;
outline: 0;
color: $text;
font-family: $font-mono;
font-size: 15px;
}
.button-wrapper {
position: fixed !important;
top: 0;
right: 0;
padding: 1rem 1rem 0.5rem 1rem;
padding: 0.7rem 0.7rem 0.5rem 0.7rem;
background-color: $bg_surface;
border-bottom-left-radius: 10px;
z-index: 10;
transition: opacity 0.2s, visibility 0.2s;
}
.buttons {
display: flex;
@ -178,11 +172,42 @@ a {
&:disabled {
color: $muted;
}
transition: all 0.2s ease-in;
}
.btn[disabled] {
color: $muted;
cursor: auto;
}
.bottom-button-wrapper {
position: fixed !important;
bottom: 0;
right: 0;
padding: 1rem 1rem 0.5rem 1rem;
z-index: 10;
.btn {
color: $muted;
&:hover {
color: $gold;
}
}
}
// #share-button {
// position: fixed !important;
// bottom: 0;
// left: 0;
// z-index: 10;
// color: $muted;
// &:hover {
// color: $rose;
// }
// padding: 10px;
// }
.keybind {
color: $subtle;
font-size: 11px;
font-family: $font-mono;
}
.logo {
font-size: 1.8rem;
font-weight: 700;
@ -209,6 +234,58 @@ a {
animation: rainbow 3s ease infinite !important;
}
}
.markdown {
color: $iris;
}
.fire {
color: $love;
}
// $dur: 1s;
// $blur: 0.02em;
// $fireRad: 3em;
// $parts: 20;
// $partSize: 5em;
// .fireBody {
// font-size: 3px;
// filter: blur($blur);
// -webkit-filter: blur($blur);
// margin: 2em auto 0 auto;
// position: absolute;
// width: 6em;
// height: 5em;
// z-index: 0;
// opacity: 0.5;
// }
// .particle {
// animation: rise $dur ease-in infinite;
// background-image: radial-gradient($love 100%, $love 100%);
// border-radius: 50%;
// mix-blend-mode: screen;
// opacity: 0;
// position: absolute;
// bottom: 0;
// width: $partSize;
// height: $partSize;
// @for $p from 1 through $parts {
// &:nth-of-type(#{$p}) {
// animation-delay: $dur * random();
// left: calc((100% - #{$partSize}) * calc(($p - 1) / $parts));
// }
// }
// }
// @keyframes rise {
// from {
// opacity: 0;
// transform: translateY(0) scale(1);
// }
// 25% {
// opacity: 1;
// }
// to {
// opacity: 0;
// transform: translateY(-10em) scale(0);
// }
// }
#messages {
position: absolute;
top: 0;
@ -220,8 +297,14 @@ a {
width: 400px;
li {
background-color: $bg_trans;
font-size: 13px;
font-family: $font-mono;
color: $text;
padding: 7px;
}
}
@media only screen and (hover: none) and (pointer: coarse) {
.button-wrapper {
opacity: 0.8;
}
}

View File

@ -0,0 +1,30 @@
$text: #e0def4;
$bg: #26233a;
$font-mono: "Cartograph CF", ui-monospace, SFMono-Regular, Menlo, Monaco,
Consolas, "Liberation Mono", "Courier New", monospace;
@import "./font.scss";
.rosepine-parent {
color: $text;
background-color: $bg;
opacity: 0.8;
padding: 10px;
font-family: $font-mono;
font-size: 13px;
border-radius: 10px;
> .tippy-backdrop {
background-color: $bg;
}
> .tippy-svg-arrow {
fill: $bg;
}
}
.tippy-box[data-theme~="rosepine"] {
@extend .rosepine-parent;
margin-top: 0.3rem;
}
.tippy-box[data-theme~="rosepine-extended"] {
@extend .rosepine-parent;
margin-top: 2rem;
}

40
frontend/vite.config.ts Normal file
View File

@ -0,0 +1,40 @@
import { defineConfig, loadEnv } from "vite"
import pugPlugin from "vite-plugin-pug"
import viteCompression from "vite-plugin-compression"
import { createRequire } from "module"
export default defineConfig(async ({ mode }) => {
let config: any
const env = loadEnv(mode, process.cwd(), "")
try {
// @ts-ignore
// lazy hack so vite doesn't emit:
// [rollup-plugin-dynamic-import-variables] Unexpected token (46:55)
// file: zer0bin/frontend/src/index.ts:46:55
// error during build:
// SyntaxError: Unexpected token (46:55)
const _config = await import("./config.json")
config = {
api_url: JSON.stringify(_config.api_url),
confetti_chance: JSON.stringify(_config.confetti_chance),
}
} catch (e) {
config = {
api_url: JSON.stringify(env.ZEROBIN_API_URL ?? env.API_URL),
confetti_chance: JSON.stringify(
env.ZEROBIN_CONFETTI_CHANCE ?? env.CONFETTI_CHANCE
),
}
}
return {
plugins: [pugPlugin(), viteCompression()],
define: {
API_URL: config.api_url,
CONFETTI_CHANCE: config.confetti_chance,
},
}
})

1944
frontend/yarn.lock Normal file

File diff suppressed because it is too large Load Diff