mirror of https://github.com/zer0bin-dev/zer0bin
Compare commits
369 Commits
v0.4.1-bet
...
main
Author | SHA1 | Date |
---|---|---|
Kainoa Kanter | 832ccc3e88 | |
Kainoa Kanter | 1677032f4e | |
Daniel Mason | 9c245cf827 | |
Kainoa Kanter | ac1f4cf33a | |
hkc | 90d1966779 | |
Kainoa Kanter | f0a3670913 | |
Kainoa Kanter | 81e5a3f7a8 | |
Mars | e7c96047cf | |
Kainoa Kanter | e2037f7522 | |
idanoo | 7eb63190f0 | |
Kainoa Kanter | 82d2087281 | |
Kainoa Kanter | 5e77dcf43b | |
mellowmarshe | db0d09bad7 | |
Noel | 0c78b83b30 | |
Noel | 6e8e2b119a | |
Noel | 479354fe2c | |
Noel | 75de8c53e3 | |
Noel | e9e18e3501 | |
domterion | de58aa84c2 | |
ThatOneCalculator | fd6b91977b | |
ThatOneCalculator | 0050ea2fb9 | |
ThatOneCalculator | 5bb8c3441b | |
Kainoa Kanter | 3ee8b85213 | |
ThatOneCalculator | 535530c34f | |
ThatOneCalculator | 21ec4c1ef0 | |
ThatOneCalculator | d683701360 | |
ThatOneCalculator | 0e1bb82944 | |
ThatOneCalculator | f1ccf6a836 | |
ThatOneCalculator | fa07222803 | |
ThatOneCalculator | 3cfda99765 | |
ThatOneCalculator | d96287c206 | |
mellowmarshe | 1146f4b7da | |
Kainoa Kanter | 7be6aa6cf2 | |
ThatOneCalculator | 6f55b59d7b | |
ThatOneCalculator | 9ff53c1345 | |
ThatOneCalculator | f001286f5b | |
Kainoa Kanter | b03ca2c8f7 | |
ThatOneCalculator | 648b6aac4e | |
ThatOneCalculator | fff67c1a43 | |
ThatOneCalculator | 4f62e7f4ee | |
Kainoa Kanter | 8ad0b5790d | |
ThatOneCalculator | 6ee88465fa | |
Dominic Harris | 36e81a6c4f | |
Kainoa Kanter | 794403ae97 | |
ThatOneCalculator | ead9d9108e | |
ThatOneCalculator | be7617476f | |
ThatOneCalculator | bbccfc4314 | |
ThatOneCalculator | a2b6392b03 | |
ThatOneCalculator | 407a4997f6 | |
ThatOneCalculator | 0081ddeafa | |
ThatOneCalculator | ee5e9a1ca3 | |
ThatOneCalculator | 667e00b894 | |
ThatOneCalculator | 8d6e3b6378 | |
ThatOneCalculator | bd718fadde | |
Kainoa Kanter | 44e996c60d | |
ThatOneCalculator | 18e2ba0200 | |
ThatOneCalculator | 70c84ebaba | |
ThatOneCalculator | abeebd045f | |
ThatOneCalculator | a2b3104c08 | |
ThatOneCalculator | 3eb141ec72 | |
ThatOneCalculator | cbd21b6bb2 | |
ThatOneCalculator | 5fe090c302 | |
ThatOneCalculator | 35004d8f0f | |
ThatOneCalculator | fa78dd4246 | |
ThatOneCalculator | 1bd6d3721a | |
ThatOneCalculator | d260e338f5 | |
ThatOneCalculator | 658538fd61 | |
ThatOneCalculator | 67f753c0d6 | |
ThatOneCalculator | 4a921a947e | |
ThatOneCalculator | d543cfc154 | |
ThatOneCalculator | 5021a3df8d | |
Kainoa Kanter | 4fad42ff6a | |
ThatOneCalculator | 95d45b09d6 | |
ThatOneCalculator | 9a2ccf73c3 | |
Dominic Harris | a78713c24a | |
Dominic Harris | f3e135df46 | |
Dominic Harris | f2eb61fa0e | |
Dominic Harris | 0e0e6daf8f | |
mellowmarshe | 51f3293279 | |
Dominic Harris | 871dcc5c38 | |
Dominic Harris | c179f8bf90 | |
Dominic Harris | dc5c178152 | |
Kainoa Kanter | 1b4da8955d | |
Kainoa Kanter | e11a496e8c | |
ThatOneCalculator | fb81db3add | |
Kainoa Kanter | 113287e5dc | |
ThatOneCalculator | 202cb98c39 | |
Dominic Harris | 161662c4de | |
Dominic Harris | 77340f763c | |
Dominic Harris | c8a46307b8 | |
Dominic Harris | b983bc352f | |
Dominic Harris | 788235d411 | |
ThatOneCalculator | 297042ab0e | |
Dominic Harris | 6bc1e8c421 | |
ThatOneCalculator | fb4b814e0a | |
ThatOneCalculator | f57312e308 | |
Kainoa Kanter | fd3334ea7c | |
Kainoa Kanter | 024feb777a | |
Kainoa Kanter | 92cbc3f49e | |
Dominic Harris | 9b8fcbd757 | |
Kainoa Kanter | bc59fc6359 | |
Kainoa Kanter | e863421fae | |
Kainoa Kanter | 807aa1f516 | |
ThatOneCalculator | 40f2d7a578 | |
ThatOneCalculator | 02f91b3f8d | |
Kainoa Kanter | 30cc4c3890 | |
Kainoa Kanter | 525a254531 | |
Kainoa Kanter | 4e25416f80 | |
Kainoa Kanter | e9db6c2c7b | |
ThatOneCalculator | a5a9620efd | |
ThatOneCalculator | 2f1dd15048 | |
Kainoa Kanter | f844f5f4ae | |
Kainoa Kanter | 062f0c8b22 | |
Kainoa Kanter | f468e12125 | |
ThatOneCalculator | bfc3825d15 | |
ThatOneCalculator | 397479b13c | |
Kainoa Kanter | 921fc40916 | |
ThatOneCalculator | dbfed7a7dc | |
ThatOneCalculator | 4ed5065bef | |
ThatOneCalculator | 1ffb3abdfd | |
ThatOneCalculator | f35b619619 | |
ThatOneCalculator | cc65f2fe78 | |
ThatOneCalculator | 7505d619ea | |
Kainoa Kanter | fa05a899db | |
Kainoa Kanter | aab7682760 | |
Kainoa Kanter | 0408c5f023 | |
ThatOneCalculator | a90250dcec | |
ThatOneCalculator | 46cb4de1ef | |
Kainoa Kanter | 36d648b8b5 | |
ThatOneCalculator | 94e282b039 | |
ThatOneCalculator | 6235dfa6ab | |
ThatOneCalculator | fd84b62cbd | |
ThatOneCalculator | 619b327ec2 | |
ThatOneCalculator | f77fdbf850 | |
Dominic Harris | 15e376c3d9 | |
Dominic Harris | 50581c022b | |
ThatOneCalculator | 63c20b56bc | |
Kainoa Kanter | 083a2a8de9 | |
Kainoa Kanter | ab0c21fd9f | |
ThatOneCalculator | 9b4eed484a | |
ThatOneCalculator | 5ff0cef35e | |
ThatOneCalculator | dbd5ce3eeb | |
ThatOneCalculator | 2bc96946f5 | |
ThatOneCalculator | 2b69f8a615 | |
ThatOneCalculator | 02ca472369 | |
ThatOneCalculator | fa29569ba1 | |
ThatOneCalculator | 8013d12a21 | |
ThatOneCalculator | 50ecb91151 | |
Kainoa Kanter | 294b50150f | |
Kainoa Kanter | 22639a244d | |
Kainoa Kanter | 597fd3663b | |
Kainoa Kanter | 41e290102c | |
ThatOneCalculator | 973e7a91f6 | |
ThatOneCalculator | e9c4842719 | |
ThatOneCalculator | 5948dcfda5 | |
Kainoa Kanter | e6a4341976 | |
Kainoa Kanter | 5056a83225 | |
ThatOneCalculator | 01cffc24d5 | |
ThatOneCalculator | 21c25dce94 | |
ThatOneCalculator | b1e792472b | |
ThatOneCalculator | e4183c9070 | |
ThatOneCalculator | 331abc7c8d | |
ThatOneCalculator | 0610f5bba2 | |
ThatOneCalculator | 6ec8b47cfb | |
ThatOneCalculator | db834b108f | |
ThatOneCalculator | 08352498c8 | |
ThatOneCalculator | 82cb6ff2e5 | |
ThatOneCalculator | 8621c29c9d | |
ThatOneCalculator | 918068f0be | |
ThatOneCalculator | 4184901345 | |
ThatOneCalculator | 2a8a4c3ac5 | |
ThatOneCalculator | 7f33ae0327 | |
ThatOneCalculator | 2155c90bc4 | |
Kainoa Kanter | 1867dde1f2 | |
Kainoa Kanter | 77eebaa42f | |
Kainoa Kanter | 49aaa073ab | |
ThatOneCalculator | a7b149f26e | |
Dominic Harris | 30a843c390 | |
Kainoa Kanter | 4c618f9486 | |
Kainoa Kanter | b6476606f8 | |
Daniel Mason | ed45574c84 | |
Kainoa Kanter | b99e63b018 | |
Dominic Harris | 7333afcbd6 | |
ThatOneCalculator | bbf6cfeada | |
ThatOneCalculator | 2844749225 | |
ThatOneCalculator | f70de0e290 | |
ThatOneCalculator | b8e4c56c10 | |
ThatOneCalculator | 7c5db6ab7c | |
ThatOneCalculator | eaddc25def | |
ThatOneCalculator | fc9ad79149 | |
ThatOneCalculator | b63251206b | |
ThatOneCalculator | 868b9c45be | |
ThatOneCalculator | 44700e686e | |
ThatOneCalculator | be2e0ad5c2 | |
ThatOneCalculator | a66540ca5a | |
Kainoa Kanter | fcbfc52347 | |
Kainoa Kanter | af28ceae14 | |
ThatOneCalculator | e9041ff13d | |
ThatOneCalculator | ac440256c4 | |
ThatOneCalculator | a1a83f4665 | |
ThatOneCalculator | 7394cd4ba7 | |
ThatOneCalculator | a51a23d772 | |
ThatOneCalculator | edd1e98a86 | |
ThatOneCalculator | 67fb649b02 | |
ThatOneCalculator | 38b58bf08c | |
ThatOneCalculator | 173b42ebe7 | |
Kainoa Kanter | c9f38fbde1 | |
ThatOneCalculator | bae89b7899 | |
Dominic Harris | ec20eb89e3 | |
Kainoa Kanter | 1c92c9104d | |
Kainoa Kanter | 131616e9be | |
Kainoa Kanter | 8d39df0ec2 | |
Kainoa Kanter | 32842c0053 | |
Kainoa Kanter | 07a8d8cbdb | |
Kainoa Kanter | e538e85d96 | |
ThatOneCalculator | be183807cc | |
ThatOneCalculator | dfe25ee031 | |
ThatOneCalculator | 3c6db18596 | |
ThatOneCalculator | 10027ff5e3 | |
Kainoa Kanter | 2d1c14f15b | |
ThatOneCalculator | 2c37d6a83f | |
ThatOneCalculator | c20e6a879c | |
ThatOneCalculator | d043839fc9 | |
ThatOneCalculator | fb51056fa0 | |
Kainoa Kanter | 59f73bbd57 | |
Kainoa Kanter | 42c992c5a7 | |
Kainoa Kanter | f37c12db59 | |
Kainoa Kanter | e115434a0e | |
ThatOneCalculator | a5eb9f17cc | |
ThatOneCalculator | 3378fa0aa3 | |
ThatOneCalculator | f4b827d1c6 | |
ThatOneCalculator | 749c928306 | |
Kainoa Kanter | b40820ef9c | |
Kainoa Kanter | b56cfc7c5f | |
Kainoa Kanter | 465cc0169a | |
Kainoa Kanter | bc9611e027 | |
Kainoa Kanter | a5d55afba2 | |
Kainoa Kanter | de9ac516e1 | |
Kainoa Kanter | 5a649e25bb | |
Kainoa Kanter | a5236a16af | |
Kainoa Kanter | ed9416467c | |
Kainoa Kanter | 2274efa958 | |
Kainoa Kanter | a625235635 | |
ThatOneCalculator | 882287280c | |
Kainoa Kanter | 345d461574 | |
Kainoa Kanter | 57253f0c73 | |
Kainoa Kanter | a20a2dfb14 | |
ThatOneCalculator | 18fb4616f9 | |
ThatOneCalculator | 3e135919f4 | |
Kainoa Kanter | bd238e3e19 | |
Kainoa Kanter | 8f8b234b1f | |
ThatOneCalculator | 456a92e3b9 | |
ThatOneCalculator | 58a15dafda | |
ThatOneCalculator | 783dabbe9f | |
Kainoa Kanter | bd844c6adb | |
Dominic Harris | 557e4f1fbf | |
Dominic Harris | 84cb21325f | |
Dominic Harris | 83f9f880bf | |
Dominic Harris | 245b4376a9 | |
Kainoa Kanter | 1729bfc51b | |
Kainoa Kanter | b22e351d57 | |
ThatOneCalculator | 6551e0b315 | |
ThatOneCalculator | 1370d8d1fc | |
Kainoa Kanter | e622facfb8 | |
ThatOneCalculator | bb90482cd4 | |
ThatOneCalculator | b5ab095195 | |
ThatOneCalculator | d65d74b325 | |
ThatOneCalculator | c7b200080e | |
ThatOneCalculator | 3899b674f3 | |
ThatOneCalculator | bca2ee264b | |
Kainoa Kanter | 046f2f192f | |
Kainoa Kanter | 0888e8f3dc | |
Dominic Harris | aa305a3637 | |
Dominic Harris | 2f72e2b182 | |
Dominic Harris | ada569cdaf | |
Dominic Harris | 59196333ac | |
Dominic Harris | cef72bb8ac | |
Dominic Harris | 324f5b381a | |
Dominic Harris | 9744446a46 | |
Dominic Harris | 99d4986f2b | |
Kainoa Kanter | 4393106cd0 | |
Kainoa Kanter | c745d99fd4 | |
Kainoa Kanter | 3b1db4d068 | |
Kainoa Kanter | f2f1c834ab | |
Kainoa Kanter | 834003fcc9 | |
Kainoa Kanter | bb063dcb33 | |
Dominic Harris | dd97a5d4ee | |
Dominic Harris | 0576a2ea4c | |
Kainoa Kanter | db9b5c1226 | |
Kainoa Kanter | 690329d4c3 | |
Kainoa Kanter | d0aebcea08 | |
Kainoa Kanter | 0aa3c601cd | |
Kainoa Kanter | 337777f29a | |
Kainoa Kanter | 2261e78e12 | |
Kainoa Kanter | 6f8999ddf2 | |
Kainoa Kanter | 95393638a6 | |
Kainoa Kanter | a571384077 | |
Kainoa Kanter | 9edfd5c6db | |
Kainoa Kanter | b90c422655 | |
Kainoa Kanter | 5e73810b98 | |
Kainoa Kanter | a9e68e97c3 | |
Kainoa Kanter | fe1786aee2 | |
Kainoa Kanter | 32933e5532 | |
Kainoa Kanter | 25b56f27c3 | |
Kainoa Kanter | f90a4a5a27 | |
Kainoa Kanter | da1dab28f5 | |
Kainoa Kanter | 4e3ef6e21b | |
Dominic Harris | 657e7568b9 | |
Dominic Harris | bdfa49aac6 | |
Kainoa Kanter | a795cea10b | |
Kainoa Kanter | 15147096f5 | |
Kainoa Kanter | 8e6fd8fe19 | |
Kainoa Kanter | 218ace8a4c | |
Kainoa Kanter | 5796f0516d | |
Kainoa Kanter | 8e98e7ed4e | |
Kainoa Kanter | fd4f3a4f94 | |
Kainoa Kanter | 3e06cb2771 | |
Kainoa Kanter | 3083ccc805 | |
Kainoa Kanter | fddbf24383 | |
Kainoa Kanter | 5c0d22e6cd | |
Kainoa Kanter | 736f63ad4c | |
Kainoa Kanter | cb8f0398ff | |
Kainoa Kanter | 1bf9fffa96 | |
Kainoa Kanter | 398ef609e6 | |
Kainoa Kanter | 63617b0953 | |
Kainoa Kanter | 574e0739d3 | |
Kainoa Kanter | 33093422eb | |
Kainoa Kanter | 3b7b87ee83 | |
Kainoa Kanter | 9af8e0d6d2 | |
Kainoa Kanter | 67e7e72120 | |
Kainoa Kanter | acf0b258d7 | |
Kainoa Kanter | c704b9fbac | |
Kainoa Kanter | 252df419e4 | |
Kainoa Kanter | ecf8de98be | |
Kainoa Kanter | ddb917c55c | |
Kainoa Kanter | 502928f436 | |
Kainoa Kanter | b0e2b54d74 | |
Kainoa Kanter | d95d5c761c | |
Kainoa Kanter | 82f2de6ecb | |
Kainoa Kanter | fe1219bd36 | |
Kainoa Kanter | 340d96fd2b | |
Kainoa Kanter | 0752801929 | |
Kainoa Kanter | c7522f5e5b | |
Kainoa Kanter | 45c4cc90a9 | |
Kainoa Kanter | d1ab999114 | |
Kainoa Kanter | 88b4627f8d | |
Kainoa Kanter | 856c8644e2 | |
Kainoa Kanter | 14f3bfd6fb | |
Kainoa Kanter | ea5ca65694 | |
Kainoa Kanter | fc062c79d8 | |
Kainoa Kanter | d37ff39895 | |
Kainoa Kanter | 69b67e13fd | |
Kainoa Kanter | f5296982a1 | |
Kainoa Kanter | 789624dd45 | |
Kainoa Kanter | 0bdc2be98f | |
Kainoa Kanter | 8e2f9cc484 | |
Kainoa Kanter | 219ed0ea00 | |
Kainoa Kanter | 62c7a65077 | |
Kainoa Kanter | bd88d60e82 | |
Dominic Harris | 56d98cfcd3 | |
Dominic Harris | 47ff32f476 | |
Dominic Harris | e0f791f91c | |
Dominic Harris | 305156041d | |
Kainoa Kanter | 0a9cae2fb2 | |
Kainoa Kanter | 3fc1bdbb07 | |
Kainoa Kanter | 3fbdf9fdf0 | |
Kainoa Kanter | fddc0ec22b | |
Kainoa Kanter | 7812c8aadb | |
Dominic Harris | 8114a4a23c |
|
@ -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:
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
**/target/
|
||||
**/.yarn
|
||||
**/node_modules/
|
||||
**/dist/
|
||||
**/.parcel-cache/
|
||||
**/config.json
|
||||
**/package-lock.json
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
{
|
||||
"useTabs": true,
|
||||
"trailingComma": "es5",
|
||||
"tabWidth": 4,
|
||||
"semi": false,
|
||||
"singleQuote": false
|
||||
}
|
|
@ -0,0 +1,128 @@
|
|||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
We as members, contributors, and leaders pledge to make participation in our
|
||||
community a harassment-free experience for everyone, regardless of age, body
|
||||
size, visible or invisible disability, ethnicity, sex characteristics, gender
|
||||
identity and expression, level of experience, education, socio-economic status,
|
||||
nationality, personal appearance, race, religion, or sexual identity
|
||||
and orientation.
|
||||
|
||||
We pledge to act and interact in ways that contribute to an open, welcoming,
|
||||
diverse, inclusive, and healthy community.
|
||||
|
||||
## Our Standards
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
## Enforcement Responsibilities
|
||||
|
||||
Community leaders are responsible for clarifying and enforcing our standards of
|
||||
acceptable behavior and will take appropriate and fair corrective action in
|
||||
response to any behavior that they deem inappropriate, threatening, offensive,
|
||||
or harmful.
|
||||
|
||||
Community leaders have the right and responsibility to remove, edit, or reject
|
||||
comments, commits, code, wiki edits, issues, and other contributions that are
|
||||
not aligned to this Code of Conduct, and will communicate reasons for moderation
|
||||
decisions when appropriate.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies within all community spaces, and also applies when
|
||||
an individual is officially representing the community in public spaces.
|
||||
Examples of representing our community include using an official e-mail address,
|
||||
posting via an official social media account, or acting as an appointed
|
||||
representative at an online or offline event.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported to the community leaders responsible for enforcement at
|
||||
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
|
||||
reporter of any incident.
|
||||
|
||||
## Enforcement Guidelines
|
||||
|
||||
Community leaders will follow these Community Impact Guidelines in determining
|
||||
the consequences for any action they deem in violation of this Code of Conduct:
|
||||
|
||||
### 1. Correction
|
||||
|
||||
**Community Impact**: Use of inappropriate language or other behavior deemed
|
||||
unprofessional or unwelcome in the community.
|
||||
|
||||
**Consequence**: A private, written warning from community leaders, providing
|
||||
clarity around the nature of the violation and an explanation of why the
|
||||
behavior was inappropriate. A public apology may be requested.
|
||||
|
||||
### 2. Warning
|
||||
|
||||
**Community Impact**: A violation through a single incident or series
|
||||
of actions.
|
||||
|
||||
**Consequence**: A warning with consequences for continued behavior. No
|
||||
interaction with the people involved, including unsolicited interaction with
|
||||
those enforcing the Code of Conduct, for a specified period of time. This
|
||||
includes avoiding interactions in community spaces as well as external channels
|
||||
like social media. Violating these terms may lead to a temporary or
|
||||
permanent ban.
|
||||
|
||||
### 3. Temporary Ban
|
||||
|
||||
**Community Impact**: A serious violation of community standards, including
|
||||
sustained inappropriate behavior.
|
||||
|
||||
**Consequence**: A temporary ban from any sort of interaction or public
|
||||
communication with the community for a specified period of time. No public or
|
||||
private interaction with the people involved, including unsolicited interaction
|
||||
with those enforcing the Code of Conduct, is allowed during this period.
|
||||
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
|
||||
individual, or aggression toward or disparagement of classes of individuals.
|
||||
|
||||
**Consequence**: A permanent ban from any sort of public interaction within
|
||||
the community.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
||||
version 2.0, available at
|
||||
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
|
||||
|
||||
Community Impact Guidelines were inspired by [Mozilla's code of conduct
|
||||
enforcement ladder](https://github.com/mozilla/diversity).
|
||||
|
||||
[homepage]: https://www.contributor-covenant.org
|
||||
|
||||
For answers to common questions about this code of conduct, see the FAQ at
|
||||
https://www.contributor-covenant.org/faq. Translations are available at
|
||||
https://www.contributor-covenant.org/translations.
|
|
@ -0,0 +1,10 @@
|
|||
# Contributing Guidelines
|
||||
|
||||
- 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)
|
|
@ -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
|
||||
|
|
139
README.md
139
README.md
|
@ -1,126 +1,77 @@
|
|||
<div align="center">
|
||||
<img src="assets/zero.png" height="110px"/>
|
||||
<a href="https://zer0b.in">
|
||||
<img src="https://raw.githubusercontent.com/zer0bin-dev/.github/main/zer0bin.svg" height="150px"/>
|
||||
<br>
|
||||
<img src="assets/zer0bin.svg" height="100"/>
|
||||
<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/domterion/zer0bin/stargazers">
|
||||
<img alt="Stargazers" src="https://custom-icon-badges.herokuapp.com/github/stars/domterion/zer0bin?style=for-the-badge&logo=star&color=f6c177&logoColor=31748f&labelColor=12101F"></a>
|
||||
<!-- <a href="https://github.com/domterion/zer0bin/releases/latest">
|
||||
<img alt="Releases" src="https://img.shields.io/github/release/domterion/zer0bin?style=for-the-badge&logo=github&color=31748f&logoColor=ebbcba&labelColor=12101F"/></a> -->
|
||||
<a href="https://github.com/domterion/zer0bin/issues">
|
||||
<img alt="Issues" src="https://custom-icon-badges.herokuapp.com/github/issues/domterion/zer0bin?style=for-the-badge&logo=issue-opened&color=9ccfd8&logoColor=eb6f92&labelColor=12101F"></a>
|
||||
<a href="https://github.com/Domterion/zer0bin/blob/main/LICENSE">
|
||||
<img alt="License" src="https://custom-icon-badges.herokuapp.com/github/license/domterion/zer0bin?style=for-the-badge&logo=law&color=c4a7e7&logoColor=ebbcba&labelColor=12101F"></a>
|
||||
<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=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=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.4.1 | 🇺🇸 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://jquery.com/"><img src="https://github.com/tandpfun/skill-icons/raw/main/icons/JQuery.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://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://cdn.discordapp.com/attachments/810799100940255260/953176309813628978/Actix-Dark.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/ai/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://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://www.kernel.org/"><img src="https://github.com/tandpfun/skill-icons/raw/main/icons/Linux-Dark.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
|
||||
- 🌄 Domain with [SSL](https://letsencrypt.org/)
|
||||
- 🐧 \*nix OS
|
||||
# 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
|
||||
|
||||
> This is on a paste with 200 lines!
|
||||
|
||||
### Lighthouse
|
||||
|
||||
![Lighthouse](https://user-images.githubusercontent.com/44733677/158105961-7e186b86-54a8-44ac-ad81-65d6cd4b8eb2.png)
|
||||
|
||||
### Firefox network
|
||||
|
||||
![Firefox Network](https://user-images.githubusercontent.com/44733677/158106344-71c4bb71-450b-4c9a-8473-05e304da41f3.png)
|
||||
See [CONTRIBUTING.md](./CONTRIBUTING.md)
|
||||
|
|
|
@ -1,40 +0,0 @@
|
|||
<svg fill="none" viewBox="0 0 440 80" width="440" height="80" xmlns="http://www.w3.org/2000/svg">
|
||||
<foreignObject width="100%" height="100%">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml">
|
||||
|
||||
<style>
|
||||
h1 {
|
||||
background: linear-gradient(to right,
|
||||
#eb6f92,
|
||||
#c9b065,
|
||||
#ebbcba,
|
||||
#31748f,
|
||||
#9ccfd8,
|
||||
#c4a7e7);
|
||||
-webkit-background-clip: text;
|
||||
background-clip: text;
|
||||
color: transparent;
|
||||
animation: rainbow 5s ease infinite;
|
||||
background-size: 400% 100%;
|
||||
font-family: "Cartograph CF", monospace;
|
||||
font-weight: 600;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
@keyframes rainbow {
|
||||
|
||||
0%,
|
||||
100% {
|
||||
background-position: 0 0;
|
||||
}
|
||||
|
||||
50% {
|
||||
background-position: 100% 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<h1> zer0bin </h1>
|
||||
|
||||
</div>
|
||||
</foreignObject>
|
||||
</svg>
|
Before Width: | Height: | Size: 827 B |
BIN
assets/zero.png
BIN
assets/zero.png
Binary file not shown.
Before Width: | Height: | Size: 4.0 KiB |
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"]
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
ALTER TABLE pastes ADD column single_view BOOLEAN DEFAULT false;
|
|
@ -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();
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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)?
|
||||
|
|
|
@ -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)]
|
||||
|
|
|
@ -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, '&')
|
||||
.replace(/>/g, '>')
|
||||
.replace(/</g, '<')
|
||||
.replace(/"/g, '"');
|
||||
*/
|
||||
|
||||
// let cleaned = data
|
||||
// .content
|
||||
// .clone()
|
||||
// .replace("&", "&")
|
||||
// .replace("<", "<")
|
||||
// .replace(">", ">")
|
||||
// .replace(r#"""#, """);
|
||||
|
||||
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)
|
||||
}
|
||||
|
|
|
@ -1,56 +1,34 @@
|
|||
# replace example.tld with your domain
|
||||
# replace /location/to with the parent folder of zer0bin
|
||||
# replace `example.tld` with your domain
|
||||
# replace `/location/of/zer0bin` with the location of the zer0bin folder
|
||||
# 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;
|
||||
return 301 https://example.tld$request_uri;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
server_name example.tld;
|
||||
|
||||
root /location/to/zer0bin/frontend/dist;
|
||||
|
||||
rewrite ^/~/(.*)$ /index.html;
|
||||
|
||||
location / {
|
||||
index index.html;
|
||||
}
|
||||
|
||||
location ~ \.(css|js|html) {
|
||||
try_files $uri =404;
|
||||
}
|
||||
|
||||
location ^~ /.well-known/ {
|
||||
alias /var/www/.well-known/;
|
||||
}
|
||||
|
||||
location /api/ {
|
||||
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
|
||||
add_header 'Access-Control-Allow-Origin' '*';
|
||||
proxy_pass http://localhost:8000/;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header Host $host;
|
||||
}
|
||||
|
||||
return 301 https://example.tld$request_uri;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 443;
|
||||
server_name example.tld;
|
||||
|
||||
gzip_static on;
|
||||
# brotli on;
|
||||
|
||||
root /location/to/zer0bin/frontend/dist;
|
||||
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/ {
|
||||
|
@ -63,10 +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;
|
||||
}
|
||||
|
||||
# If you have letsencrypt certs provided by certbot:
|
||||
|
||||
# ssl_certificate /etc/letsencrypt/live/example.tld/fullchain.pem;
|
||||
# ssl_certificate_key /etc/letsencrypt/live/example.tld/privkey.pem;
|
||||
}
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
nodeLinker: node-modules
|
|
@ -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 |
|
@ -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.
Binary file not shown.
Binary file not shown.
|
@ -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>
|
|
@ -1,38 +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/Domterion/zer0bin/main/assets/zero.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/Domterion/zer0bin/main/assets/zero.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/Domterion/zer0bin' aria-label='GitHub repo')
|
||||
button#github-button.btn(aria-label='GitHub')
|
||||
span.viewcounter.noselect#viewcounter-label(style='display: none') Views:
|
||||
span.viewcounter.noselect#viewcounter-count
|
||||
.wrapper
|
||||
.line-numbers.noselect
|
||||
pre#code-view-pre(style='display: none')
|
||||
code#code-view
|
||||
textarea#text-area(spellcheck='false' autofocus='' name='value' style='display: none')
|
||||
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:
|
||||
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')
|
|
@ -1,28 +1,33 @@
|
|||
{
|
||||
"name": "zer0bin",
|
||||
"source": "index.pug",
|
||||
"version": "0.4.1",
|
||||
"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/transformer-pug": "^2.3.2",
|
||||
"@parcel/transformer-sass": "^2.3.2",
|
||||
"@types/core-js": "^2.5.5",
|
||||
"@types/jquery": "^3.5.14",
|
||||
"@types/node": "^17.0.21",
|
||||
"parcel": "^2.3.2",
|
||||
"ts-migrate": "^0.1.28"
|
||||
"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-svg": "^4.2.1",
|
||||
"highlight.js": "^11.4.0",
|
||||
"jquery": "^3.6.0"
|
||||
"highlight.js": "^11.5.0",
|
||||
"js-confetti": "^0.10.2",
|
||||
"marked": "^4.0.12",
|
||||
"no-darkreader": "^1.0.1",
|
||||
"smooth-scrollbar": "^8.7.4",
|
||||
"tippy.js": "^6.3.7"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
declare const API_URL: string
|
||||
declare const CONFETTI_CHANCE: string
|
|
@ -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,
|
||||
})
|
||||
}
|
||||
}
|
|
@ -1,61 +1,69 @@
|
|||
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 $ from "jquery"
|
||||
import "no-darkreader"
|
||||
|
||||
const config = require("../config.json")
|
||||
const apiUrl = config.api_url
|
||||
import { marked } from "marked"
|
||||
import JSConfetti from "js-confetti"
|
||||
import Scrollbar from "smooth-scrollbar"
|
||||
|
||||
const extraSVGAttrs = {
|
||||
width: "1em",
|
||||
height: "1em",
|
||||
fill: "currentColor",
|
||||
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()
|
||||
|
||||
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")
|
||||
const messages = <HTMLElement>document.getElementById("messages")
|
||||
const viewCounterLabel = <HTMLSpanElement>(
|
||||
document.getElementById("viewcounter-label")
|
||||
)
|
||||
const viewCounter = <HTMLSpanElement>(
|
||||
document.getElementById("viewcounter-count")
|
||||
)
|
||||
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 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.visibility = "hidden"
|
||||
element.style.opacity = "0"
|
||||
}
|
||||
|
||||
const svgSave = renderIconDefinitionToSVGElement(SaveOutlined, {
|
||||
extraSVGAttrs: extraSVGAttrs,
|
||||
})
|
||||
function show(element: HTMLElement) {
|
||||
element.style.visibility = "visible"
|
||||
element.style.opacity = "1"
|
||||
}
|
||||
|
||||
const svgFileAdd = renderIconDefinitionToSVGElement(FileAddOutlined, {
|
||||
extraSVGAttrs: extraSVGAttrs,
|
||||
})
|
||||
function disable(element: HTMLButtonElement) {
|
||||
element.disabled = true
|
||||
}
|
||||
|
||||
const svgCopy = renderIconDefinitionToSVGElement(CopyOutlined, {
|
||||
extraSVGAttrs: extraSVGAttrs,
|
||||
})
|
||||
function enable(element: HTMLButtonElement) {
|
||||
element.disabled = false
|
||||
}
|
||||
|
||||
const svgGithub = renderIconDefinitionToSVGElement(GithubOutlined, {
|
||||
extraSVGAttrs: extraSVGAttrs,
|
||||
})
|
||||
|
||||
const lineNumbers = $(".line-numbers")
|
||||
const editor = $("#text-area")
|
||||
const codeViewPre = $("#code-view-pre")
|
||||
const codeView = $("#code-view")
|
||||
const messages = $("#messages")
|
||||
const viewCounterLabel = $("#viewcounter-label")
|
||||
const viewCounter = $("#viewcounter-count")
|
||||
|
||||
const saveButton = $("#save-button")
|
||||
const newButton = $("#new-button")
|
||||
const copyButton = $("#copy-button")
|
||||
const githubButton = $("#github-button")
|
||||
|
||||
saveButton.append(svgSave)
|
||||
newButton.append(svgFileAdd)
|
||||
copyButton.append(svgCopy)
|
||||
githubButton.append(svgGithub)
|
||||
|
||||
global.rawContent = ""
|
||||
|
||||
function postPaste(content: string, callback: Function) {
|
||||
const payload = { content }
|
||||
fetch(`${apiUrl}/p/n`, {
|
||||
async function postPaste(content: string, callback: Function) {
|
||||
const payload = { content, single_view: singleView }
|
||||
await fetch(`${API_URL}/p/n`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
|
@ -64,21 +72,22 @@ function postPaste(content: string, callback: Function) {
|
|||
})
|
||||
.then((response) => response.json())
|
||||
.then((data) => {
|
||||
console.log(data)
|
||||
callback(null, data)
|
||||
if (data["success"]) {
|
||||
callback(null, data)
|
||||
return
|
||||
}
|
||||
|
||||
callback(data || { data: { message: "An unkown error occured!" } })
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error)
|
||||
callback(
|
||||
error || `{"data": { "message": "An unkown error occured!" } }`
|
||||
)
|
||||
.catch(() => {
|
||||
callback({
|
||||
data: { message: "An API error occurred, please try again." },
|
||||
})
|
||||
})
|
||||
global.rawContent = ""
|
||||
viewCounterLabel.hide()
|
||||
}
|
||||
|
||||
function getPaste(id: string, callback: Function) {
|
||||
fetch(`${apiUrl}/p/${id}`, {
|
||||
async function getPaste(id: string, callback: Function) {
|
||||
await fetch(`${API_URL}/p/${id}`, {
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
|
@ -87,120 +96,285 @@ 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." },
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function newPaste() {
|
||||
lineNumbers.html(">")
|
||||
Scrollbar.destroyAll()
|
||||
|
||||
saveButton.prop("disabled", false)
|
||||
newButton.prop("disabled", true)
|
||||
copyButton.prop("disabled", true)
|
||||
lineNumbers.innerHTML = ">"
|
||||
|
||||
editor.val("")
|
||||
enable(saveButton)
|
||||
disable(newButton)
|
||||
disable(copyButton)
|
||||
disable(shareButton)
|
||||
enable(singleViewButton)
|
||||
|
||||
editor.show()
|
||||
codeViewPre.hide()
|
||||
editor.value = ""
|
||||
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) {
|
||||
let msg = $(`<li>${message}</li>`)
|
||||
messages.prepend(msg)
|
||||
let msg = document.createElement("li")
|
||||
msg.innerHTML = message
|
||||
messages.insertBefore(msg, messages.firstChild)
|
||||
|
||||
setTimeout(function () {
|
||||
msg.slideUp("fast", function () {
|
||||
$(this).remove()
|
||||
})
|
||||
msg.classList.add("fadeOut"),
|
||||
function () {
|
||||
msg.remove()
|
||||
}
|
||||
}, 3000)
|
||||
}
|
||||
|
||||
function viewPaste(content: string, views: string) {
|
||||
lineNumbers.html("")
|
||||
for (let i = 1; i <= content.split("\n").length; i++) {
|
||||
lineNumbers.append(`${i}
|
||||
<br>`)
|
||||
function viewPaste(content: string, views: string, singleView: boolean) {
|
||||
lineNumbers.innerHTML = ""
|
||||
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.html(hljs.highlightAuto(content).value)
|
||||
|
||||
saveButton.prop("disabled", true)
|
||||
newButton.prop("disabled", false)
|
||||
copyButton.prop("disabled", false)
|
||||
if (singleView) {
|
||||
show(singleViewButton.firstElementChild as HTMLElement)
|
||||
singleViewButton.lastElementChild.classList.add("fire")
|
||||
addMessage("This is a single-view paste!")
|
||||
}
|
||||
|
||||
viewCounter.text(views)
|
||||
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!")
|
||||
}
|
||||
})
|
||||
|
||||
editor.hide()
|
||||
codeViewPre.show()
|
||||
viewCounterLabel.show()
|
||||
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")
|
||||
} catch (error) {}
|
||||
|
||||
Scrollbar.init(document.querySelector(".scrollbar-container"))
|
||||
}
|
||||
|
||||
saveButton.click(function () {
|
||||
if (editor.val() === "") {
|
||||
async function savePaste() {
|
||||
if (editor.value === "") {
|
||||
return
|
||||
}
|
||||
const val: string = editor.val()?.toString()!
|
||||
const val: string = editor.value?.toString()!
|
||||
|
||||
postPaste(val, function (err, res) {
|
||||
await postPaste(val, function (err, res) {
|
||||
if (err) {
|
||||
addMessage(err["data"]["message"])
|
||||
} else {
|
||||
window.history.pushState(null, "", `/~/${res["data"]["id"]}`)
|
||||
global.rawContent = res["data"]["content"]
|
||||
viewPaste(global.rawContent, "0")
|
||||
window.history.pushState(null, "", `/${res["data"]["id"]}`)
|
||||
|
||||
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",
|
||||
"#f6c177",
|
||||
"#ebbcba",
|
||||
"#31748f",
|
||||
"#9ccfd8",
|
||||
"#c4a7e7",
|
||||
],
|
||||
})
|
||||
} else if (rand === 5) {
|
||||
jsConfetti.addConfetti({
|
||||
emojis: ["🦀"],
|
||||
})
|
||||
} else if (rand === 6) {
|
||||
jsConfetti.addConfetti({
|
||||
emojis: ["🐈", "🧶", "📦"],
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
copyButton.click(function () {
|
||||
async function duplicatePaste() {
|
||||
const content = rawContent
|
||||
window.history.pushState(null, "", "/")
|
||||
let content = global.rawContent
|
||||
newPaste()
|
||||
global.rawContent = content
|
||||
editor.val(global.rawContent)
|
||||
|
||||
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()
|
||||
})
|
||||
|
||||
editor.keydown(function (e: KeyboardEvent) {
|
||||
if (e.key == "Tab") {
|
||||
document.addEventListener("keydown", (e) => {
|
||||
if (e.ctrlKey && e.code === "KeyS") {
|
||||
e.preventDefault()
|
||||
let start: string = this.selectionStart
|
||||
let end: string = this.selectionEnd
|
||||
this.value =
|
||||
this.value.substring(0, start) + "\t" + this.value.substring(end)
|
||||
this.selectionStart = this.selectionEnd = start + 1
|
||||
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()
|
||||
}
|
||||
})
|
||||
|
||||
function handlePopstate() {
|
||||
editor.addEventListener(
|
||||
"keydown",
|
||||
function (e: KeyboardEvent) {
|
||||
if (e.code == "Tab") {
|
||||
e.preventDefault()
|
||||
|
||||
let start: number = this.selectionStart
|
||||
let end: number = this.selectionEnd
|
||||
|
||||
this.value =
|
||||
this.value.substring(0, start) +
|
||||
"\t" +
|
||||
this.value.substring(end)
|
||||
|
||||
this.selectionStart = this.selectionEnd = start + 1
|
||||
}
|
||||
},
|
||||
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
|
||||
|
||||
if (path == "/") {
|
||||
newPaste()
|
||||
} else {
|
||||
const split = path.split("/")
|
||||
|
||||
const id = split[split.length - 1]
|
||||
|
||||
getPaste(id, function (err, res) {
|
||||
await getPaste(id, function (err, res) {
|
||||
if (err) {
|
||||
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"]
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
$(window).bind("popstate", function () {
|
||||
handlePopstate()
|
||||
window.addEventListener("popstate", async () => {
|
||||
await handlePopstate()
|
||||
})
|
||||
|
||||
$(document).ready(function () {
|
||||
handlePopstate()
|
||||
})
|
||||
document.addEventListener(
|
||||
"DOMContentLoaded",
|
||||
async () => {
|
||||
await handlePopstate()
|
||||
},
|
||||
false
|
||||
)
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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% {
|
||||
|
@ -33,6 +25,11 @@ $font-mono: "Cartograph CF", ui-monospace, SFMono-Regular, Menlo, Monaco,
|
|||
background-position: 100% 0;
|
||||
}
|
||||
}
|
||||
.fadeOut {
|
||||
visibility: hidden;
|
||||
opacity: 0;
|
||||
transition: visibility 0s 3s, opacity 2s linear;
|
||||
}
|
||||
body {
|
||||
height: 100%;
|
||||
background-color: $bg_base;
|
||||
|
@ -63,10 +60,18 @@ pre {
|
|||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
}
|
||||
.wrapper .scroll-content {
|
||||
display: flex;
|
||||
}
|
||||
.scrollbar-container {
|
||||
height: 100%;
|
||||
}
|
||||
.wrapper {
|
||||
display: flex;
|
||||
padding: 1rem 0.5rem;
|
||||
font-size: 1rem;
|
||||
}
|
||||
.text-area-proper {
|
||||
height: calc(100% - 2rem);
|
||||
}
|
||||
.line-numbers {
|
||||
|
@ -75,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 {
|
||||
|
@ -113,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;
|
||||
|
@ -165,9 +172,41 @@ 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;
|
||||
|
@ -195,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;
|
||||
|
@ -206,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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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,
|
||||
},
|
||||
}
|
||||
})
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue