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
poetry
andyarn
. - 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.development
to.env.production
and edit it. Also edit.env
if needed. - Generate
APP_SECRET
as described inserver/app/config.py
and save it to.env.production
. - Init database using
flask db upgrade
inserver
directory. - Modify
server/app/__init__.py
and configureProxyFix
if you are deploying behind a reverse proxy.
First, you need to build frontend files.
cd frontend
yarn build
Then, 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.py
poetry shell
flask db init
flask db migrate
flask db upgrade
Password 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_HOST
to allowlist - URL Rewrite Rules: see
web.config
below - Virtual directory: point from
clip-basepath
toserver/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.