netcut.cn style, minimal editable online clipboard.
Developed using Flask, Vue 3, Vuetify 3, TypeScript. Full i18n support.
Runs on Node.js v18.16.0, Python 3.11.3.
- Install
poetryandyarn. - Install Python and Node.js dependencies.
# Install python dependencies
pushd server
poetry install --no-root
popd
# Install nodejs dependencies
pushd frontend
yarn install
popd- Edit
server/app/note_const.py,server/app/config.py. - Copy
.env.developmentto.env.productionand edit it. Also edit.envif needed. - Generate
APP_SECRETas described inserver/app/config.pyand save it to.env.production. - Init database using
flask db upgradeinserverdirectory. - Modify
server/app/__init__.pyand configureProxyFixif you are deploying behind a reverse proxy.
First, you need to build frontend files.
cd frontend
yarn buildThen, you can run the server.
cd server
FLASK_ENV=production poetry run python wsgi.py
# PowerShell: $env:FLASK_ENV='production'; poetry run python wsgi.py# Get clip named my_clip
curl http://example.com/raw/my_clip?my_password# frontend
cd frontend
yarn dev
# backend
cd server
poetry run python wsgi.pypoetry shell
flask db init
flask db migrate
flask db upgradePassword protect: sha512(note.password) through Internet, pbkdf2_sha256(sha512(note.password)) in database.
File access: JWT generated with note.name and pbkdf2_sha256(sha512(note.password)) (the hash stored in database as above)
Content encryption: AES-256-CBC/PKCS7 with sha256(note.password), see CryptoJS behaviour
Example rule:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<clear />
<rule name="clip-server" stopProcessing="true">
<match url="^clip-basepath(/(api|raw|socket\.io).+)$" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{CACHE_URL}" pattern="^(.+)?://.+$" />
</conditions>
<serverVariables>
<set name="HTTP_SEC_WEBSOCKET_EXTENSIONS" value="" />
<set name="HTTP_X_FORWARDED_PREFIX" value="/clip-basepath/" />
<set name="HTTP_X_FORWARDED_HOST" value="example.com" />
</serverVariables>
<action type="Rewrite" url="{C:1}://127.0.0.1:5000{R:1}" />
</rule>
<rule name="clip-frontend" stopProcessing="true">
<match url="^clip-basepath(/.*)?$" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Rewrite" url="/clip-basepath/index.html" />
</rule>
</rules>
</rewrite>
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="209715200" />
</requestFiltering>
</security>
</system.webServer>
</configuration>- Download and install URL Rewrite
- View Server Variables: add
HTTP_SEC_WEBSOCKET_EXTENSIONS,HTTP_X_FORWARDED_PREFIX,HTTP_X_FORWARDED_HOSTto allowlist - URL Rewrite Rules: see
web.configbelow - Virtual directory: point from
clip-basepathtoserver/app/templates
How to set URL length and HTTP POST content length limits in IIS - WKB240363
Clip uses Socket.IO to support Instant Sync feature, which allows multi users to edit together. A WebSocket server will run on the same port of backend Flask server.
