Compare commits

...

98 Commits
0.2.0 ... main

Author SHA1 Message Date
Nicolai Ort 2bd82ceb01
Merge branch 'main' of git.odit.services:kauft.es/linkylinky
ci/woodpecker/push/build Pipeline was successful Details
2023-11-04 16:43:38 +01:00
Nicolai Ort 641cd0dcdc
feat(ci)!: Switch to woodpecker 2023-11-04 16:43:24 +01:00
Nicolai Ort 98b8e9578f
Merge pull request 'Update registry.odit.services/hub/library/node Docker tag to v18' (#24) from renovate/registry.odit.services-hub-library-node-18.x into main
continuous-integration/drone/push Build is passing Details
Reviewed-on: #24
2022-04-30 14:12:57 +00:00
Nicolai Ort c3cc58f4c9
Merge pull request 'Update dependency release-it to v15' (#25) from renovate/release-it-15.x into main
continuous-integration/drone/push Build is passing Details
Reviewed-on: #25
2022-04-30 14:10:18 +00:00
ODIT Renovate Bot c7c32fa386 Update dependency release-it to v15
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/pr Build is passing Details
2022-04-30 12:47:14 +00:00
ODIT Renovate Bot cca7eb0ec3 Update registry.odit.services/hub/library/node Docker tag to v18
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/pr Build is passing Details
2022-04-22 14:46:43 +00:00
Nicolai Ort 2afceb8436
Merge pull request 'Update registry.odit.services/hub/library/node Docker tag to v17.9.0' (#22) from renovate/registry.odit.services-hub-library-node-17.x into main
continuous-integration/drone/push Build is passing Details
Reviewed-on: #22
2022-04-20 18:04:26 +00:00
ODIT Renovate Bot fa15fc36ca Update registry.odit.services/hub/library/node Docker tag to v17.9.0
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/pr Build is passing Details
2022-04-19 20:46:31 +00:00
Nicolai Ort 8b6db25695 Merge pull request 'Update registry.odit.services/hub/library/node Docker tag to v17.7.2' (#21) from renovate/registry.odit.services-hub-library-node-17.x into main
continuous-integration/drone/push Build is passing Details
Reviewed-on: #21
2022-03-26 17:46:11 +00:00
ODIT Renovate Bot 5042166604 Update registry.odit.services/hub/library/node Docker tag to v17.7.2
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/pr Build is passing Details
2022-03-22 20:01:13 +00:00
Nicolai Ort 72164ee20e Merge pull request 'Update dependency dotenv to v16' (#20) from renovate/dotenv-16.x into main
continuous-integration/drone/push Build is passing Details
Reviewed-on: #20
2022-02-04 08:16:24 +00:00
ODIT Renovate Bot cb951b4b12 Update dependency dotenv to v16
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/pr Build is passing Details
2022-02-02 21:32:33 +00:00
Nicolai Ort 0bb30ccc7b 🚀RELEASE 0.8.0
continuous-integration/drone/push Build is passing Details
2022-02-02 15:33:38 +01:00
Nicolai Ort fd5142020d
Added BADGE API endpoint (no auth needed)
continuous-integration/drone/push Build is passing Details
2022-02-02 15:25:55 +01:00
Nicolai Ort 40f1ea4757
Added badge-maker dependency 2022-02-02 15:24:59 +01:00
Nicolai Ort eb053df154 Merge pull request 'Update dependency dotenv to v15' (#19) from renovate/dotenv-15.x into main
continuous-integration/drone/push Build is passing Details
Reviewed-on: #19
2022-02-01 20:34:58 +00:00
ODIT Renovate Bot 5b518c5884 Update dependency dotenv to v15
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/pr Build is passing Details
2022-01-31 05:17:19 +00:00
Nicolai Ort d320b20dfc Merge pull request 'Update dependency dotenv to v14' (#18) from renovate/dotenv-14.x into main
continuous-integration/drone/push Build is passing Details
Reviewed-on: #18
2022-01-17 16:39:02 +00:00
Nicolai Ort 6fd89b75ab Merge pull request 'Update dependency knex to v0.95.15' (#16) from renovate/knex-0.x into main
continuous-integration/drone/push Build is passing Details
Reviewed-on: #16
2022-01-17 16:38:40 +00:00
ODIT Renovate Bot ae4a930ddb Update dependency dotenv to v14
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/pr Build is passing Details
2022-01-17 04:01:54 +00:00
ODIT Renovate Bot bc466e7fd9 Update dependency knex to v0.95.15
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/pr Build is passing Details
2022-01-16 17:02:25 +00:00
Nicolai Ort 28087400b7 🚀RELEASE 0.7.2
continuous-integration/drone/push Build is passing Details
2022-01-16 17:57:33 +01:00
Nicolai Ort 9cf8248522
Pinned knex version (thx sqlite) 2022-01-16 17:57:07 +01:00
Nicolai Ort 35fafa337b Merge pull request 'Update dependency dotenv to v12' (#14) from renovate/dotenv-12.x into main
continuous-integration/drone/push Build is passing Details
Reviewed-on: #14
2022-01-15 11:56:58 +00:00
ODIT Renovate Bot d0eed67697 Update dependency dotenv to v12
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/pr Build is passing Details
2022-01-15 00:01:56 +00:00
Nicolai Ort 36ce64a79d
Docker speedbuild
continuous-integration/drone/push Build is passing Details
2022-01-12 18:26:49 +01:00
Nicolai Ort 4da3cea59f 🚀RELEASE 0.7.1
continuous-integration/drone/push Build is passing Details
2022-01-12 18:19:24 +01:00
Nicolai Ort e06f9253cf
Smol bugfix 2022-01-12 18:19:15 +01:00
Nicolai Ort 93a931830f
Added examples to readme
continuous-integration/drone/push Build is passing Details
2022-01-12 18:17:50 +01:00
Nicolai Ort 85249e83b1
Updated readme w/ native provider
continuous-integration/drone/push Build is passing Details
2022-01-12 18:12:33 +01:00
Nicolai Ort 4ee8de47cf 🚀RELEASE 0.7.0
continuous-integration/drone/push Build is passing Details
2022-01-12 18:04:27 +01:00
Nicolai Ort 8abaabbe51
Added the new providers to the readme 2022-01-12 18:04:14 +01:00
Nicolai Ort 0fa043f0df
Now recognizing r/ pattern
continuous-integration/drone/push Build is passing Details
2022-01-12 17:54:50 +01:00
Nicolai Ort 7211133aba
Implemented reddit name recognition 2022-01-12 17:51:21 +01:00
Nicolai Ort d957ca52ea
Removed yarn lock copy
continuous-integration/drone/push Build is passing Details
2022-01-12 17:40:29 +01:00
Nicolai Ort 231d8ca7ee
Push w/o lockfile
continuous-integration/drone/push Build is failing Details
2022-01-12 17:33:48 +01:00
Nicolai Ort 4a476e93af 🚀RELEASE 0.6.1
continuous-integration/drone/push Build is failing Details
2022-01-12 17:31:58 +01:00
Nicolai Ort 3bfcd64589 Merge pull request 'Update dependency fastify-jwt to v4' (#12) from renovate/fastify-jwt-4.x into main
continuous-integration/drone/push Build is passing Details
Reviewed-on: #12
2022-01-12 16:30:00 +00:00
Nicolai Ort d17825cabf Merge pull request 'Update registry.odit.services/hub/library/node Docker tag to v17' (#11) from renovate/registry.odit.services-hub-library-node-17.x into main
continuous-integration/drone/push Build is passing Details
Reviewed-on: #11
2022-01-12 16:29:36 +00:00
Nicolai Ort 6205151d53 Merge pull request 'Update dependency dotenv to v11' (#13) from renovate/dotenv-11.x into main
continuous-integration/drone/push Build is passing Details
Reviewed-on: #13
2022-01-12 16:29:24 +00:00
ODIT Renovate Bot 4861ca7f3e Update dependency dotenv to v11
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/pr Build is passing Details
2022-01-11 07:02:02 +00:00
ODIT Renovate Bot 575685f24d Update dependency fastify-jwt to v4
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/pr Build is passing Details
2021-11-25 09:00:46 +00:00
ODIT Renovate Bot 0e9f7a526c Update registry.odit.services/hub/library/node Docker tag to v17
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/pr Build is passing Details
2021-11-18 19:00:32 +00:00
Nicolai Ort efb11f6047
Enabled dep dashboard
continuous-integration/drone/push Build is passing Details
2021-10-15 16:23:21 +02:00
Nicolai Ort e95ca8045a Merge pull request 'Update dependency knex to ^0.95.0' (#5) from renovate/knex-0.x into main
continuous-integration/drone/push Build is passing Details
Reviewed-on: #5
2021-10-15 14:22:03 +00:00
ODIT Renovate Bot 2b93f3ea8a Update dependency knex to ^0.95.0
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/pr Build is passing Details
2021-10-15 14:18:41 +00:00
Nicolai Ort 2a7a32fda6 Merge pull request 'Configure Renovate' (#4) from renovate/configure into main
continuous-integration/drone/push Build is passing Details
Reviewed-on: #4
2021-10-15 14:17:08 +00:00
ODIT Renovate Bot d7428af1d8 Add renovate.json
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/pr Build is passing Details
2021-10-15 14:16:47 +00:00
Nicolai Ort 3ca5f6b3b4
Preleminary emoji support
continuous-integration/drone/push Build is passing Details
2021-09-25 19:29:23 +02:00
Nicolai Ort eb96408d33
Working clientside stuff
continuous-integration/drone/push Build is passing Details
closes #3
2021-09-25 18:45:52 +02:00
Nicolai Ort 11bd1b4f1f
Added 'clientside' flag to getters and setters 2021-09-25 18:28:49 +02:00
Nicolai Ort e3214084f6
Added migration for clientside redirects
ref #3
2021-09-25 18:25:53 +02:00
Nicolai Ort 3803ac9197 🚀RELEASE 0.6.0
continuous-integration/drone/push Build is passing Details
2021-09-25 18:03:09 +02:00
Nicolai Ort e1621b72ad
Added rudementary page content
continuous-integration/drone/push Build is passing Details
2021-09-25 17:44:34 +02:00
Nicolai Ort b64a8436e7
Updated opengraph type
ref #2
2021-09-25 17:42:44 +02:00
Nicolai Ort d8ed9a149f
Switched docker base images to odit mirror 2021-09-25 17:38:11 +02:00
Nicolai Ort 9d7125a311
Now with custom opengraph (tm)
continuous-integration/drone/push Build is passing Details
ref #2
2021-09-25 17:35:52 +02:00
Nicolai Ort 6d71a3ebf4
Removed unused log
continuous-integration/drone/push Build is passing Details
2021-09-25 17:27:59 +02:00
Nicolai Ort 75adbf73cf
Now with working bad bot detection
ref #2
2021-09-25 17:27:41 +02:00
Nicolai Ort e5b8557e4c
Getters now return the no_preview status 2021-09-25 17:21:30 +02:00
Nicolai Ort 33d7c94648
New urls can now be created with disabled preview
ref #2
2021-09-25 17:19:36 +02:00
Nicolai Ort f6b2ae523d
Added bot check for native short urls
ref #2
2021-09-25 17:17:42 +02:00
Nicolai Ort 0a500f16cd
Added migration for disallowing bot previews 2021-09-25 17:16:38 +02:00
Nicolai Ort 61da5d8110
Added basic bot checking 2021-09-25 17:14:34 +02:00
Nicolai Ort 773b286216
Added package for bot recognition 2021-09-25 17:12:52 +02:00
Nicolai Ort d097eccbd9
removed logging 2021-09-25 17:12:22 +02:00
Nicolai Ort f15282a3f9
Log user agents
continuous-integration/drone/push Build is passing Details
2021-09-25 17:09:19 +02:00
Nicolai Ort 0a8945a294
Added noindex header to all shorturl routes
continuous-integration/drone/push Build is passing Details
ref #2
2021-09-25 16:59:28 +02:00
Nicolai Ort b871e4295d 🚀RELEASE 0.5.1
continuous-integration/drone/push Build is passing Details
2021-08-21 10:03:16 +02:00
Nicolai Ort 0945060a49
Added optional filtering by provider 2021-08-21 10:02:52 +02:00
Nicolai Ort f7eae96b8c
Shortened return to avoid variable memory asignment 2021-08-21 10:01:24 +02:00
Nicolai Ort c2a50a1480
Changed object property order (just for us pesky humans to improve readability) 2021-08-21 09:59:57 +02:00
Nicolai Ort bb99c2dcd1
Added endpoint to query over all visited urls 2021-08-21 09:59:14 +02:00
Nicolai Ort e8382fb579 🚀RELEASE 0.5.0
continuous-integration/drone/push Build is passing Details
2021-08-21 09:56:21 +02:00
Nicolai Ort b5321377bd
Reverted last change since we can defer it from the provider 2021-08-21 09:54:55 +02:00
Nicolai Ort 6e26bbbf5f
Changed the way visits entrys get compiled to enable provider visits count searches over the default api 2021-08-21 09:53:17 +02:00
Nicolai Ort 59e178476e
Removed visits 404 resolution 2021-08-21 09:51:25 +02:00
Nicolai Ort 824c109a42
Server now inserts provider on visit 2021-08-21 09:49:45 +02:00
Nicolai Ort f48159b31b
Added migration for visits provider 2021-08-21 09:46:28 +02:00
Nicolai Ort 6195001d4b
Added package script for migration creation 2021-08-21 09:45:57 +02:00
Nicolai Ort 0afa80345d 🚀RELEASE 0.4.3
continuous-integration/drone/push Build is passing Details
2021-08-21 07:35:41 +02:00
Nicolai Ort dbb0d177b8
Fixed auth error crashing the entire server thanks to fastify handling stuff not the same way that they do in the docs.....
closes #1
2021-08-21 07:35:13 +02:00
Nicolai Ort 4ffc06db7b 🚀RELEASE 0.4.2
continuous-integration/drone/push Build is passing Details
2021-08-18 17:47:16 +02:00
Nicolai Ort 588f3bae89
Changed register api route and added user deletion route 2021-08-18 17:46:49 +02:00
Nicolai Ort d889432ce8 🚀RELEASE 0.4.1
continuous-integration/drone/push Build is passing Details
2021-08-18 17:39:01 +02:00
Nicolai Ort 44830f08bc
Fixed jwtcount not being recognized 2021-08-18 17:38:47 +02:00
Nicolai Ort 1cd3ebf8c5 🚀RELEASE 0.4.0
continuous-integration/drone/push Build is passing Details
2021-08-18 16:23:39 +02:00
Nicolai Ort 558b69eeaa
Implemented jwt count validation and update on logout 2021-08-18 16:22:50 +02:00
Nicolai Ort 2b22063a81
All authenticated entpoints now accept jwtauth 2021-08-18 16:10:59 +02:00
Nicolai Ort 48cc380504
Implemented jwtcount basics 2021-08-18 16:09:34 +02:00
Nicolai Ort 75473cabe7
Basic jwt implementation :party: 2021-08-18 15:57:23 +02:00
Nicolai Ort 6420ffb055
Switched to fastify-auth to support multiple auth providers 2021-08-18 15:36:16 +02:00
Nicolai Ort a62ee63c83 🚀RELEASE 0.3.0
continuous-integration/drone/push Build is passing Details
2021-08-18 15:22:49 +02:00
Nicolai Ort c89f2a2939
Added stats api route 2021-08-18 15:21:36 +02:00
Nicolai Ort d51c58867d
Added comments 2021-08-16 15:19:04 +02:00
Nicolai Ort 2fa520fdde
Added author info
continuous-integration/drone/push Build is passing Details
2021-08-14 16:02:40 +02:00
Nicolai Ort 5bb7212420
Added license 2021-08-14 16:00:45 +02:00
Nicolai Ort 2226705e3f
Updated readme 2021-08-14 15:52:56 +02:00
15 changed files with 3189 additions and 1591 deletions

View File

@ -1,59 +0,0 @@
---
kind: secret
name: docker_username
get:
path: odit-registry-builder
name: username
---
kind: secret
name: docker_password
get:
path: odit-registry-builder
name: password
---
kind: pipeline
type: kubernetes
name: build:latest
steps:
- name: docker release
image: plugins/docker
depends_on: [clone]
settings:
username:
from_secret: docker_username
password:
from_secret: docker_password
repo: registry.odit.services/kauft.es/linkylinky
tags:
- latest
registry: registry.odit.services
mtu: 1000
when:
branch:
- main
---
kind: pipeline
type: kubernetes
name: build:tags
steps:
- name: build $DRONE_TAG
image: plugins/docker
depends_on: [clone]
settings:
username:
from_secret: docker_username
password:
from_secret: docker_password
repo: registry.odit.services/kauft.es/linkylinky
tags:
- '${DRONE_TAG}'
registry: registry.odit.services
mtu: 1000
trigger:
event:
- tag

38
.woodpecker/build.yml Normal file
View File

@ -0,0 +1,38 @@
steps:
- name: build latest
image: woodpeckerci/plugin-docker-buildx
settings:
repo: registry.odit.services/kauft.es/linkylinky
tags:
- latest
registry: registry.odit.services
platforms: linux/amd64,linux/arm64
cache_from: registry.odit.services/kauft.es/linkylinky:latest
username:
from_secret: odit-registry-builder-username
password:
from_secret: odit-registry-builder-password
secrets:
- source: odit-npm-cache-url
target: NPM_REGISTRY_URL
when:
branch: main
event: push
- name: build tag
image: woodpeckerci/plugin-docker-buildx
settings:
repo: registry.odit.services/kauft.es/linkylinky
tags:
- "${CI_COMMIT_TAG}"
registry: registry.odit.services
platforms: linux/amd64,linux/arm64
cache_from: registry.odit.services/kauft.es/linkylinky:latest
username:
from_secret: odit-registry-builder-username
password:
from_secret: odit-registry-builder-password
secrets:
- source: odit-npm-cache-url
target: NPM_REGISTRY_URL
when:
event: tag

View File

@ -2,8 +2,159 @@
All notable changes to this project will be documented in this file. Dates are displayed in UTC.
#### [0.8.0](https://git.odit.services/kauft.es/linkylinky/compare/0.7.2...0.8.0)
- Added badge-maker dependency [`40f1ea4`](https://git.odit.services/kauft.es/linkylinky/commit/40f1ea47574cd0cf2ab7ea28d9cd70243da40f27)
- Added BADGE API endpoint (no auth needed) [`fd51420`](https://git.odit.services/kauft.es/linkylinky/commit/fd5142020d46a6117f0f00302690511e18d67d14)
- Merge pull request 'Update dependency dotenv to v15' (#19) from renovate/dotenv-15.x into main [`eb053df`](https://git.odit.services/kauft.es/linkylinky/commit/eb053df154e4598da46c275435a4b1bb9b133119)
- Update dependency dotenv to v15 [`5b518c5`](https://git.odit.services/kauft.es/linkylinky/commit/5b518c58848899da19f50d4d9517ef7749ec26a5)
- Merge pull request 'Update dependency dotenv to v14' (#18) from renovate/dotenv-14.x into main [`d320b20`](https://git.odit.services/kauft.es/linkylinky/commit/d320b20dfca67a79b83caf10735f367aafad7fbb)
- Merge pull request 'Update dependency knex to v0.95.15' (#16) from renovate/knex-0.x into main [`6fd89b7`](https://git.odit.services/kauft.es/linkylinky/commit/6fd89b75abbaac37435f8556da2db2d262d7ede4)
- Update dependency dotenv to v14 [`ae4a930`](https://git.odit.services/kauft.es/linkylinky/commit/ae4a930ddb9bafd89967235342a2ad3954e53e13)
- Update dependency knex to v0.95.15 [`bc466e7`](https://git.odit.services/kauft.es/linkylinky/commit/bc466e7fd97d5292c6a00a36b3abce147c862c6b)
#### [0.7.2](https://git.odit.services/kauft.es/linkylinky/compare/0.7.1...0.7.2)
> 16 January 2022
- 🚀RELEASE 0.7.2 [`2808740`](https://git.odit.services/kauft.es/linkylinky/commit/28087400b79d6790939db34a814850df04364947)
- Pinned knex version (thx sqlite) [`9cf8248`](https://git.odit.services/kauft.es/linkylinky/commit/9cf8248522b31e14c4f6f304f620a3040cc2f496)
- Merge pull request 'Update dependency dotenv to v12' (#14) from renovate/dotenv-12.x into main [`35fafa3`](https://git.odit.services/kauft.es/linkylinky/commit/35fafa337b81ad79a9f0f3501624ece40bda7967)
- Docker speedbuild [`36ce64a`](https://git.odit.services/kauft.es/linkylinky/commit/36ce64a79dec5e98dbc90f5d9dbb366bbaaed049)
- Update dependency dotenv to v12 [`d0eed67`](https://git.odit.services/kauft.es/linkylinky/commit/d0eed676971488b2207a05b2200283033d132cba)
#### [0.7.1](https://git.odit.services/kauft.es/linkylinky/compare/0.7.0...0.7.1)
> 12 January 2022
- Added examples to readme [`93a9318`](https://git.odit.services/kauft.es/linkylinky/commit/93a931830f853cea4502b9c74e0d74202efb23ce)
- 🚀RELEASE 0.7.1 [`4da3cea`](https://git.odit.services/kauft.es/linkylinky/commit/4da3cea59f69fe7714323935d2f2e14ba3210f13)
- Updated readme w/ native provider [`85249e8`](https://git.odit.services/kauft.es/linkylinky/commit/85249e83b1ec349d740d72394dfbda4ab4d5984e)
- Smol bugfix [`e06f925`](https://git.odit.services/kauft.es/linkylinky/commit/e06f9253cf39cd76205da448e6758ca3b51130d6)
#### [0.7.0](https://git.odit.services/kauft.es/linkylinky/compare/0.6.1...0.7.0)
> 12 January 2022
- Push w/o lockfile [`231d8ca`](https://git.odit.services/kauft.es/linkylinky/commit/231d8ca7ee0da402322afd3ac8ddce58e14943c1)
- 🚀RELEASE 0.7.0 [`4ee8de4`](https://git.odit.services/kauft.es/linkylinky/commit/4ee8de47cf227a58e8d2a2eedfc06575a1e5a1c0)
- Added the new providers to the readme [`8abaabb`](https://git.odit.services/kauft.es/linkylinky/commit/8abaabbe5170372ca35ff469cee25c65a8f3d729)
- Implemented reddit name recognition [`7211133`](https://git.odit.services/kauft.es/linkylinky/commit/7211133aba22315919443d5314594b7ec027c02b)
- Now recognizing r/ pattern [`0fa043f`](https://git.odit.services/kauft.es/linkylinky/commit/0fa043f0dfbae8b4095375b39c220a901cc6051f)
- Removed yarn lock copy [`d957ca5`](https://git.odit.services/kauft.es/linkylinky/commit/d957ca52ea2332f6cd1c5608467be6245f5082b8)
#### [0.6.1](https://git.odit.services/kauft.es/linkylinky/compare/0.6.0...0.6.1)
> 12 January 2022
- Working clientside stuff [`#3`](https://git.odit.services/kauft.es/linkylinky/issues/3)
- 🚀RELEASE 0.6.1 [`4a476e9`](https://git.odit.services/kauft.es/linkylinky/commit/4a476e93af43c8920448fcfeff3f13edc0bc0681)
- Merge pull request 'Update dependency fastify-jwt to v4' (#12) from renovate/fastify-jwt-4.x into main [`3bfcd64`](https://git.odit.services/kauft.es/linkylinky/commit/3bfcd645890253813cc2e4c740f67d577682934b)
- Merge pull request 'Update registry.odit.services/hub/library/node Docker tag to v17' (#11) from renovate/registry.odit.services-hub-library-node-17.x into main [`d17825c`](https://git.odit.services/kauft.es/linkylinky/commit/d17825cabf2d46d040bd33a3d1ad5a9d0bccfbe5)
- Merge pull request 'Update dependency dotenv to v11' (#13) from renovate/dotenv-11.x into main [`6205151`](https://git.odit.services/kauft.es/linkylinky/commit/6205151d53b374d890276d294d0abc6e6114abe5)
- Update dependency knex to ^0.95.0 [`2b93f3e`](https://git.odit.services/kauft.es/linkylinky/commit/2b93f3ea8a9b2f4be73829fb1041e6233d81fa91)
- Preleminary emoji support [`3ca5f6b`](https://git.odit.services/kauft.es/linkylinky/commit/3ca5f6b3b468ca739bc77e1d9b751625e03f300d)
- Update dependency fastify-jwt to v4 [`575685f`](https://git.odit.services/kauft.es/linkylinky/commit/575685f24d1d0a2c0574741e540f448642990cd5)
- Update dependency dotenv to v11 [`4861ca7`](https://git.odit.services/kauft.es/linkylinky/commit/4861ca7f3e3ed3e62ee774d59cb13a38d5e5e1e1)
- Update registry.odit.services/hub/library/node Docker tag to v17 [`0e9f7a5`](https://git.odit.services/kauft.es/linkylinky/commit/0e9f7a526ce5188e964e7beb78a5fb63870b473f)
- Enabled dep dashboard [`efb11f6`](https://git.odit.services/kauft.es/linkylinky/commit/efb11f6047e37901e20c613393d435f869e8a1f9)
- Merge pull request 'Update dependency knex to ^0.95.0' (#5) from renovate/knex-0.x into main [`e95ca80`](https://git.odit.services/kauft.es/linkylinky/commit/e95ca8045af6afcbc9dfcc9976d107a231d12953)
- Merge pull request 'Configure Renovate' (#4) from renovate/configure into main [`2a7a32f`](https://git.odit.services/kauft.es/linkylinky/commit/2a7a32fda615fa01751deffadafa6df1a5d0fede)
- Added 'clientside' flag to getters and setters [`11bd1b4`](https://git.odit.services/kauft.es/linkylinky/commit/11bd1b4f1f4d079b3ca047472da9da34fb64732d)
- Added migration for clientside redirects [`e321408`](https://git.odit.services/kauft.es/linkylinky/commit/e3214084f6dbf3e1595c54a9594e6d5f12323991)
- Add renovate.json [`d7428af`](https://git.odit.services/kauft.es/linkylinky/commit/d7428af1d81c820fdca7220959485f361956b86e)
#### [0.6.0](https://git.odit.services/kauft.es/linkylinky/compare/0.5.1...0.6.0)
> 25 September 2021
- 🚀RELEASE 0.6.0 [`3803ac9`](https://git.odit.services/kauft.es/linkylinky/commit/3803ac9197a1d4c6535606cde43b1e04b3056f9c)
- Now with custom opengraph (tm) [`9d7125a`](https://git.odit.services/kauft.es/linkylinky/commit/9d7125a31186f3b7f33df4875db12c67cf91f536)
- Added rudementary page content [`e1621b7`](https://git.odit.services/kauft.es/linkylinky/commit/e1621b72ade1fce381f30bcf310a6dcf8d1c65ea)
- Added migration for disallowing bot previews [`0a500f1`](https://git.odit.services/kauft.es/linkylinky/commit/0a500f16cde0b0e38a115dd4e76185a2a45dda49)
- Added basic bot checking [`61da5d8`](https://git.odit.services/kauft.es/linkylinky/commit/61da5d81108a4b86f92e1c05ca99372c6b188347)
- Now with working bad bot detection [`75adbf7`](https://git.odit.services/kauft.es/linkylinky/commit/75adbf73cfbf4fadf2cd632ecb687eff95749f52)
- New urls can now be created with disabled preview [`33d7c94`](https://git.odit.services/kauft.es/linkylinky/commit/33d7c94648d062ece3fa437e71ce1ded70324cd8)
- Added bot check for native short urls [`f6b2ae5`](https://git.odit.services/kauft.es/linkylinky/commit/f6b2ae523da149b72f2be6d9171584cdc0be6e99)
- Added package for bot recognition [`773b286`](https://git.odit.services/kauft.es/linkylinky/commit/773b286216c9e530ccdf3fbfcfe95fa938097be5)
- Getters now return the no_preview status [`e5b8557`](https://git.odit.services/kauft.es/linkylinky/commit/e5b8557e4ccae90981e675c2adae81236aa9144e)
- Added noindex header to all shorturl routes [`0a8945a`](https://git.odit.services/kauft.es/linkylinky/commit/0a8945a294de2bc5bce9410f3ebf20b8f5abd0a5)
- Switched docker base images to odit mirror [`d8ed9a1`](https://git.odit.services/kauft.es/linkylinky/commit/d8ed9a149fddae8e8cc61b78cbc940a9d7ade8f2)
- Updated opengraph type [`b64a843`](https://git.odit.services/kauft.es/linkylinky/commit/b64a8436e745d176cc49ef72434dce0f8f1bcc12)
- Log user agents [`f15282a`](https://git.odit.services/kauft.es/linkylinky/commit/f15282a3f9bdaaf09a36d8662b64a5bc2740633f)
- Removed unused log [`6d71a3e`](https://git.odit.services/kauft.es/linkylinky/commit/6d71a3ebf4d880b8291cacd620f86416cff0d744)
- removed logging [`d097ecc`](https://git.odit.services/kauft.es/linkylinky/commit/d097eccbd925e3627fa710d7891d269b372d174c)
#### [0.5.1](https://git.odit.services/kauft.es/linkylinky/compare/0.5.0...0.5.1)
> 21 August 2021
- 🚀RELEASE 0.5.1 [`b871e42`](https://git.odit.services/kauft.es/linkylinky/commit/b871e4295dc4b067f4f4dd28c3f940c8aa9624e0)
- Added endpoint to query over all visited urls [`bb99c2d`](https://git.odit.services/kauft.es/linkylinky/commit/bb99c2dcd1ce89af1bc27a035be5265345d2a05f)
- Added optional filtering by provider [`0945060`](https://git.odit.services/kauft.es/linkylinky/commit/0945060a49ed35c038df2c04bbd07174bc5654ca)
- Shortened return to avoid variable memory asignment [`f7eae96`](https://git.odit.services/kauft.es/linkylinky/commit/f7eae96b8c3479d333fc00bc36bce451733700db)
- Changed object property order (just for us pesky humans to improve readability) [`c2a50a1`](https://git.odit.services/kauft.es/linkylinky/commit/c2a50a14807e223987464c63fac6d67ed98b1a93)
#### [0.5.0](https://git.odit.services/kauft.es/linkylinky/compare/0.4.3...0.5.0)
> 21 August 2021
- 🚀RELEASE 0.5.0 [`e8382fb`](https://git.odit.services/kauft.es/linkylinky/commit/e8382fb579f769364693974cbe74ce06e9810a9a)
- Removed visits 404 resolution [`59e1784`](https://git.odit.services/kauft.es/linkylinky/commit/59e178476e8f7e64de92ae23e859b87680e7af64)
- Added migration for visits provider [`f48159b`](https://git.odit.services/kauft.es/linkylinky/commit/f48159b31bcaf7c7449c89fb1e3851bcb04f5e3c)
- Reverted last change since we can defer it from the provider [`b532137`](https://git.odit.services/kauft.es/linkylinky/commit/b5321377bde9bd7de13e2eee4dd38a072cf0d4a3)
- Changed the way visits entrys get compiled to enable provider visits count searches over the default api [`6e26bbb`](https://git.odit.services/kauft.es/linkylinky/commit/6e26bbbf5f29e4c1eaa56c5dc41ab77c192d0cfb)
- Server now inserts provider on visit [`824c109`](https://git.odit.services/kauft.es/linkylinky/commit/824c109a420efd0e1e6de01d93827020f3fe5a5f)
- Added package script for migration creation [`6195001`](https://git.odit.services/kauft.es/linkylinky/commit/6195001d4b701d39470ff4be0e265f9afb288e78)
#### [0.4.3](https://git.odit.services/kauft.es/linkylinky/compare/0.4.2...0.4.3)
> 21 August 2021
- Fixed auth error crashing the entire server thanks to fastify handling stuff not the same way that they do in the docs..... [`#1`](https://git.odit.services/kauft.es/linkylinky/issues/1)
- 🚀RELEASE 0.4.3 [`0afa803`](https://git.odit.services/kauft.es/linkylinky/commit/0afa80345d47e09e20d4365634f8532248b2044c)
#### [0.4.2](https://git.odit.services/kauft.es/linkylinky/compare/0.4.1...0.4.2)
> 18 August 2021
- Changed register api route and added user deletion route [`588f3ba`](https://git.odit.services/kauft.es/linkylinky/commit/588f3bae8980f76461d20e15475ec797078b0b54)
- 🚀RELEASE 0.4.2 [`4ffc06d`](https://git.odit.services/kauft.es/linkylinky/commit/4ffc06db7bb84bc7bfc9c57a80927f7201185274)
#### [0.4.1](https://git.odit.services/kauft.es/linkylinky/compare/0.4.0...0.4.1)
> 18 August 2021
- 🚀RELEASE 0.4.1 [`d889432`](https://git.odit.services/kauft.es/linkylinky/commit/d889432ce8a403f6a609423eaf458a5904dc5b98)
- Fixed jwtcount not being recognized [`44830f0`](https://git.odit.services/kauft.es/linkylinky/commit/44830f08bc212f8079b5ac2da3d51eedbe6d5c41)
#### [0.4.0](https://git.odit.services/kauft.es/linkylinky/compare/0.3.0...0.4.0)
> 18 August 2021
- Basic jwt implementation :party: [`75473ca`](https://git.odit.services/kauft.es/linkylinky/commit/75473cabe79975296e473002e16d3abafbd2635e)
- Implemented jwtcount basics [`48cc380`](https://git.odit.services/kauft.es/linkylinky/commit/48cc380504206ea08b3a5082f19ad10bdd7cf773)
- Implemented jwt count validation and update on logout [`558b69e`](https://git.odit.services/kauft.es/linkylinky/commit/558b69eeaa78ea015473c674d5f919d64128a930)
- Switched to fastify-auth to support multiple auth providers [`6420ffb`](https://git.odit.services/kauft.es/linkylinky/commit/6420ffb055f08348c54cd08a193aba5fe5ebc13a)
- 🚀RELEASE 0.4.0 [`1cd3ebf`](https://git.odit.services/kauft.es/linkylinky/commit/1cd3ebf8c5a9413b93ab49c8813dad5c5c547cb2)
- All authenticated entpoints now accept jwtauth [`2b22063`](https://git.odit.services/kauft.es/linkylinky/commit/2b22063a81193c3d698525a050ef300e542c1f05)
#### [0.3.0](https://git.odit.services/kauft.es/linkylinky/compare/0.2.0...0.3.0)
> 18 August 2021
- Added license [`5bb7212`](https://git.odit.services/kauft.es/linkylinky/commit/5bb7212420ba102e743d62a47074191cdb264d2a)
- 🚀RELEASE 0.3.0 [`a62ee63`](https://git.odit.services/kauft.es/linkylinky/commit/a62ee63c838a64d7fd28ae110cad474e2c531995)
- Added stats api route [`c89f2a2`](https://git.odit.services/kauft.es/linkylinky/commit/c89f2a2939b658ffc688646ccce32fc0e1530583)
- Added author info [`2fa520f`](https://git.odit.services/kauft.es/linkylinky/commit/2fa520fdde1d55b2766b4b03e394e21a4f6cbae5)
- Updated readme [`2226705`](https://git.odit.services/kauft.es/linkylinky/commit/2226705e3f57d7d2f3ef5a79947c3ab44ec62c38)
- Added comments [`d51c588`](https://git.odit.services/kauft.es/linkylinky/commit/d51c58867d7508c84f26c236e38567bc6a4adbed)
#### [0.2.0](https://git.odit.services/kauft.es/linkylinky/compare/0.1.4...0.2.0)
> 14 August 2021
- 🚀RELEASE 0.2.0 [`7293295`](https://git.odit.services/kauft.es/linkylinky/commit/72932955d15976947dd553c5deba51cbf541b215)
- Added ebay provider recognition [`12c6d7e`](https://git.odit.services/kauft.es/linkylinky/commit/12c6d7e3da5cb4de6a597b4639f313b8e4319646)
- Ebay provider resolution [`339e2f3`](https://git.odit.services/kauft.es/linkylinky/commit/339e2f39d88d42a961e1e495f319dc0663cdc0a6)
- Now recognizing with and without protocol [`1624e66`](https://git.odit.services/kauft.es/linkylinky/commit/1624e666e83e0afe346bcacb105ea1a1535f0690)

View File

@ -1,15 +1,16 @@
FROM node:16.6.2-alpine3.14
FROM registry.odit.services/hub/library/node:18.0.0-alpine3.14
ARG NPM_REGISTRY_DOMAIN=registry.npmjs.org
ARG NPM_REGISTRY_TOKEN=null
WORKDIR /app
COPY package.json .
COPY yarn.lock .
RUN yarn --production --frozen-lockfile
RUN npm config set registry https://$NPM_REGISTRY_DOMAIN && npm config set //$NPM_REGISTRY_DOMAIN/:_authToken $NPM_REGISTRY_TOKEN
RUN npm i -g pnpm && pnpm i
COPY migrations ./migrations
COPY src ./src
COPY knexfile.js ./
RUN mkdir db
#
# FROM astefanutti/scratch-node:16.0.0
FROM node:16.6.2-alpine3.14
FROM registry.odit.services/hub/library/node:18.0.0-alpine3.14
WORKDIR /app
COPY --from=0 /app /app
ENV NODE_ENV production

24
LICENSE Normal file
View File

@ -0,0 +1,24 @@
MIT License
-----------
Copyright (c) 2021 ODIT.Services (https://odit.services)
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

View File

@ -1,5 +1,24 @@
# LinkyLinky 🔗
> A small url shortener, originaly developed for kauft.es
<p align="center">
<img height="150" src="https://git.odit.services/user/avatar/kauft.es/140">
<h1 align="center">LinkyLinky 🔗</h1>
<h3 align="center">A small url shortener, originaly developed for kauft.es</h3>
</p>
## Features
* Url shortinging to 18-byte hex ids
* Special shortening "providers" for well-used services
### Provider patterns
> The base pattern is always baseurl/providerOrShortCode
| Provider | Pattern | Resolves to | Example | Notes |
| - | - | - | - | - |
| Native (Shortcode) | `/id` | Whatever the database entry points to | https://kauft.es/den-hut | None |
| YouTube (Video) | `/yt/id` | `https://youtu.be/id` | https://kauft.es/yt/dQw4w9WgXcQ | None |
| YouTube (Playlist) | `/ytpl/id` | `https://youtube.com/playlist?list=id` | https://kauft.es/ytpl/PLKIxB9vhdS_3x0A5za3mmu1wdoolgRQ65 | Remember: Private playlists will result in user-side errors |
| Amazon | `/a/id` | `https://amazon.de/dp/id` | https://kauft.es/a/B08Z2TXCPY | Recognizes all kind of cursed amazon urls (+smile and others) |
| eBay | `/e/id` | `https://ebay.de/itm/id` | https://kauft.es/e/373831556670 | Only tested with German eBay |
| Reddit | `/r/id` | `https://redd.it/id` | https://kauft.es/r/4vapin | Powered by the awesome work of u/TheAppleFreak https://kauft.es/r/4vapin |
## Dev Setup 🛠
> Runs on port 3000

View File

@ -0,0 +1,10 @@
exports.up = function(knex) {
return knex.schema.table('users', function (table) {
table.integer("jwtcount").defaultTo(0);
});
};
exports.down = function(knex) {
};

View File

@ -0,0 +1,10 @@
exports.up = function(knex) {
return knex.schema.table('visits', function (table) {
table.text('provider').defaultTo("N/A");
});
};
exports.down = function(knex) {
};

View File

@ -0,0 +1,10 @@
exports.up = function(knex) {
return knex.schema.table('urls', function (table) {
table.boolean('no_preview').defaultTo(false);
});
};
exports.down = function(knex) {
};

View File

@ -0,0 +1,9 @@
exports.up = function(knex) {
return knex.schema.table('urls', function (table) {
table.boolean('clientside').defaultTo(false);
});
};
exports.down = function(knex) {
};

View File

@ -1,28 +1,45 @@
{
"name": "@odit/shortener-backend",
"version": "0.2.0",
"version": "0.8.0",
"main": "index.js",
"license": "MIT",
"private": false,
"author": {
"name": "ODIT.Services",
"email": "info@odit.services",
"url": "https://odit.services"
},
"contributors": [
{
"name": "Nicolai Ort",
"email": "info@nicolai-ort.com",
"url": "https://nicolai-ort.com"
}
],
"scripts": {
"dev": "nodemon src/server.js",
"start": "node src/server.js",
"migrate": "knex migrate:latest",
"release": "release-it"
"release": "release-it",
"create:migration": "knex migrate:make"
},
"dependencies": {
"argon2": "^0.28.2",
"dotenv": "^10.0.0",
"badge-maker": "^3.3.1",
"dotenv": "^16.0.0",
"fastify": "^3.20.1",
"fastify-auth": "^1.1.0",
"fastify-basic-auth": "^2.1.0",
"fastify-cors": "^6.0.2",
"knex": "^0.21.21",
"fastify-jwt": "^4.0.0",
"isbot": "^3.3.3",
"knex": "0.95.15",
"sqlite3": "^5.0.2",
"uniqid": "^5.3.0"
},
"devDependencies": {
"nodemon": "^2.0.12",
"release-it": "^14.11.3"
"release-it": "^15.0.0"
},
"release-it": {
"git": {

4
renovate.json Normal file
View File

@ -0,0 +1,4 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"dependencyDashboard": true
}

View File

@ -2,12 +2,16 @@ const fastify = require('fastify')({ logger: true })
var uniqid = require('uniqid');
require('dotenv').config();
const argon2 = require('argon2');
const isBot = require('isbot')
const { makeBadge, ValidationError } = require('badge-maker')
let config = {
domain: process.env.DOMAIN || "localhost:3000",
https: (process.env.SSL === 'true') || false,
env: process.env.NODE_ENV || 'development',
recognizeProviders: !(process.env.DISABLE_PROVIDERS === 'true'),
registrationEnabled: (process.env.ENABLE_REGISTER === 'true'),
jwt_secret: process.env.JWT_SECRET || "pleaseneverusethisdefaultsecret",
getBaseUrl() {
if (config.https) {
return `https://${config.domain}`;
@ -15,35 +19,88 @@ let config = {
return `http://${config.domain}`;
}
}
const environment = process.env.NODE_ENV || 'development';
const knexConfiguration = require('../knexfile')[environment];
const knexConfiguration = require('../knexfile')[config.env];
const knex = require('knex')(knexConfiguration);
const authenticate = { realm: 'Short' }
fastify.register(require('fastify-auth'))
fastify.register(require('fastify-basic-auth'), { validate, authenticate });
fastify.register(require('fastify-cors'), {
fastify.register(require('fastify-jwt'), {
secret: config.jwt_secret
});
fastify.register(require('fastify-cors'), {
origin: true,
preflight: true,
preflightContinue: true
})
})
fastify.decorate('verifyJWT', function async(request, reply, done) {
let token = request.headers.authorization;
if (!token || token == "" || token == "Bearer") {
done(new Error("No jwt provided"));
}
if (token.startsWith("Bearer")) {
token = token.replace("Bearer ", "");
fastify.log.info("Detected bearer and replaced it")
}
fastify.jwt.verify(token, async (err, decoded) => {
if (err) {
fastify.log.error("JWT validation failed:")
done(new Error("JWT Validation failed"));
}
else {
if (!decoded.payload) {
done(new Error("JWT is empty"));
}
fastify.log.info(`Token verified. User is ${decoded.payload.user}`);
const jwtcount = (await knex.select('jwtcount')
.from('users')
.where('username', '=', decoded.payload.user)
.limit(1))[0].jwtcount;
if (decoded.payload.jwtcount < jwtcount) {
fastify.log.error("Auth ended at jwtcount")
done(new Error("JWT in no longer valid"))
}
else {
fastify.log.info(`JWT count verified`);
request.user = decoded.payload.user;
done()
}
}
})
})
//Automagic Amazn redirects on /a/
fastify.get('/a/:id', async (req, res) => {
res.redirect(302, `https://amazon.de/dp/${req.params.id}`)
await knex('visits').insert({ shortcode: req.params.id, provider: 'a' });
})
//Automagic Youtube redirects on /yt/
fastify.get('/yt/:id', async (req, res) => {
res.redirect(302, `https://youtu.be/${req.params.id}`)
await knex('visits').insert({ shortcode: req.params.id, provider: 'yt' });
})
//Automagic Youtube Playlist redirects on /ytpl/
fastify.get('/ytpl/:id', async (req, res) => {
res.redirect(302, `https://youtube.com/playlist?list=${req.params.id}`)
await knex('visits').insert({ shortcode: req.params.id, provider: 'ytpl' });
})
//Automagic ebay item redirects on /e/
fastify.get('/e/:id', async (req, res) => {
res.redirect(302, `https://ebay.de/itm/${req.params.id}`)
await knex('visits').insert({ shortcode: req.params.id, provider: 'e' });
})
//Automagic reddit redirects on /r/
fastify.get('/r/:id', async (req, res) => {
res.redirect(302, `https://redd.it/${req.params.id}`)
await knex('visits').insert({ shortcode: req.params.id, provider: 'r' });
})
//Normal shorturls
@ -54,15 +111,26 @@ fastify.get('/:shortcode', async (req, res) => {
if (!shortcode) {
return 404;
}
const target = await knex.select('target')
const target = await knex.select('target', 'no_preview', 'clientside')
.from('urls')
.where('shortcode', '=', shortcode)
.limit(1);
if (!target[0]) {
return 404
}
if (isBot(req.headers['user-agent']) && target[0].no_preview) {
res.type("text/html");
return bot_html;
}
if (target[0].clientside) {
res.type("text/html");
return clientside_html.replace("{{targeturl}}", target[0].target)
}
res.redirect(302, target[0].target);
await knex('visits').insert({ shortcode });
await knex('visits').insert({ shortcode, provider: 'native' });
})
//Create new url schema
@ -72,6 +140,8 @@ const newUrlSchema = {
properties: {
target: { type: 'string' },
shortcode: { type: 'string' },
no_preview: { type: 'boolean' },
clientside: { type: 'boolean' }
}
}
};
@ -80,6 +150,8 @@ const newUrlSchema = {
fastify.post('/api', { newUrlSchema }, async (req, res) => {
const target = req.body?.target;
let shortcode = req.body?.shortcode;
let no_preview = req.body?.no_preview || false;
let clientside = req.body?.clientside || false;
//Check if the user provided a target
if (!target) {
@ -99,7 +171,7 @@ fastify.post('/api', { newUrlSchema }, async (req, res) => {
return response;
}
}
const exists = await knex.select('shortcode')
const exists = await knex.select('shortcode', 'no_preview', 'clientside')
.from('urls')
.where('target', '=', target)
.limit(1);
@ -108,7 +180,9 @@ fastify.post('/api', { newUrlSchema }, async (req, res) => {
return {
url: `${config.getBaseUrl()}/${shortcode}`,
shortcode,
target
target,
no_preview: exists[0].no_preview,
clientside: exists[0].clientside
}
}
shortcode = uniqid();
@ -130,12 +204,28 @@ fastify.post('/api', { newUrlSchema }, async (req, res) => {
}
//Create a new db entry
await knex('urls').insert({ target, shortcode });
await knex('urls').insert({ target, shortcode, no_preview, clientside });
return {
url: `${config.getBaseUrl()}/${shortcode}`,
shortcode,
target
target,
no_preview,
clientside
}
});
//Get stats api route
fastify.get('/api/stats', async (req, res) => {
const urls = await knex.select('shortcode')
.from('urls');
const visits = await knex.select('timestamp')
.from('visits');
return {
urls: urls.length,
visits: visits.length,
}
});
@ -148,7 +238,7 @@ fastify.get('/api/:shortcode', async (req, res) => {
return 404;
}
const exists = await knex.select('shortcode', 'target')
const exists = await knex.select('shortcode', 'target', 'no_preview', 'clientside')
.from('urls')
.where('shortcode', '=', shortcode)
.limit(1);
@ -164,12 +254,49 @@ fastify.get('/api/:shortcode', async (req, res) => {
url: `${config.getBaseUrl()}/${exists[0].shortcode}`,
shortcode: exists[0].shortcode,
target: exists[0].target,
no_preview: exists[0].no_preview,
clientside: exists[0].clientside,
visits: visits.length
}
});
//Get url api route
fastify.get('/api/badge/:shortcode', async (req, res) => {
const shortcode = req.params.shortcode;
const label = req.query.label || 'vists';
const color = req.query.color || 'green';
const style = req.query.style || 'for-the-badge';
//This should never happen but better safe than 500
if (!shortcode) {
return 404;
}
const exists = await knex.select('shortcode', 'target', 'no_preview', 'clientside')
.from('urls')
.where('shortcode', '=', shortcode)
.limit(1);
if (exists.length == 0) {
return 404;
}
const visits = await knex.select('timestamp')
.from('visits')
.where('shortcode', '=', shortcode);
const format = {
label,
message: visits.length.toString(),
color,
style
}
res.type('image/svg+xml')
return makeBadge(format);
});
//User registration
fastify.post('/api/register', async (req, res) => {
fastify.post('/api/auth/register', async (req, res) => {
if (!config.registrationEnabled) {
res.statusCode = 400;
return "Registration was disabled by your admin";
@ -201,9 +328,10 @@ fastify.post('/api/register', async (req, res) => {
return "Done!"
});
//Anything in here has some kind of auth
fastify.after(() => {
//Get url api route
fastify.get('/api/:shortcode/visits', { onRequest: fastify.basicAuth }, async (req, res) => {
//Get url visits api route
fastify.get('/api/:shortcode/visits', { onRequest: fastify.auth([fastify.basicAuth, fastify.verifyJWT]) }, async (req, res) => {
const shortcode = req.params.shortcode;
//This should never happen but better safe than 500
@ -211,23 +339,26 @@ fastify.after(() => {
return 404;
}
const exists = await knex.select('shortcode', 'target')
.from('urls')
.where('shortcode', '=', shortcode)
.limit(1);
if (exists.length == 0) {
return 404;
}
const visits = await knex.select('timestamp')
const visits = await knex.select('timestamp', 'provider')
.from('visits')
.where('shortcode', '=', shortcode);
return visits;
});
//Get all visits api route
fastify.get('/api/visits', { onRequest: fastify.auth([fastify.basicAuth, fastify.verifyJWT]) }, async (req, res) => {
if (req.query.provider) {
return await knex.select('shortcode', 'provider', 'timestamp')
.from('visits')
.where("provider", "=", req.query.provider);
}
return await knex.select('shortcode', 'provider', 'timestamp')
.from('visits');
});
//Get url api route
fastify.delete('/api/:shortcode', { onRequest: fastify.basicAuth }, async (req, res) => {
fastify.delete('/api/:shortcode', { onRequest: fastify.auth([fastify.basicAuth, fastify.verifyJWT]) }, async (req, res) => {
const shortcode = req.params.shortcode;
//This should never happen but better safe than 500
@ -244,13 +375,13 @@ fastify.after(() => {
});
//Get all urls api route
fastify.get('/api', { onRequest: fastify.basicAuth }, async (req, res) => {
urls = await knex.select('target', 'shortcode')
fastify.get('/api', { onRequest: fastify.auth([fastify.basicAuth, fastify.verifyJWT]) }, async (req, res) => {
urls = await knex.select('target', 'shortcode', 'no_preview', 'clientside')
.from('urls');
for (let url of urls) {
url.url = `${config.getBaseUrl()}/${url.shortcode}`
if(req.query.showVisits){
if (req.query.showVisits) {
url.visits = (await knex.select('timestamp')
.from('visits')
.where('shortcode', '=', url.shortcode)).length;
@ -260,6 +391,46 @@ fastify.after(() => {
return urls;
});
fastify.post('/api/auth/login', { onRequest: fastify.auth([fastify.basicAuth]) }, async (req, reply) => {
const jwtcount = (await knex.select('jwtcount')
.from('users')
.where('username', '=', req.user)
.limit(1))[0].jwtcount;
const payload = {
user: req.user,
jwtcount
};
const token = fastify.jwt.sign({ payload })
reply.send({ token });
});
fastify.post('/api/auth/check', { onRequest: fastify.auth([fastify.basicAuth, fastify.verifyJWT]) }, (req, reply) => {
return "logged in";
});
fastify.post('/api/auth/logout', { onRequest: fastify.auth([fastify.basicAuth, fastify.verifyJWT]) }, async (req, reply) => {
let jwtcount = (await knex.select('jwtcount')
.from('users')
.where('username', '=', req.user)
.limit(1))[0].jwtcount;
jwtcount += 1;
await knex('users')
.where('username', '=', req.user)
.update({
jwtcount
});
return "Done!";
});
fastify.post('/api/auth/deleteme', { onRequest: fastify.auth([fastify.basicAuth, fastify.verifyJWT]) }, async (req, reply) => {
await knex('users')
.where('username', '=', req.user)
.delete();
return "Done!";
});
});
@ -307,6 +478,16 @@ function checkKnownProviders(target) {
target
}
}
const redditID = target.match(/(((((?:https?:)?\/\/)((?!about\.)[\w-]+?\.)?([rc]edd(?:it\.com|\.it)))(?!\/(?:blog|about|code|advertising|jobs|rules|wiki|contact|buttons|gold|page|help|prefs|user|message|widget)\b)((?:\/r\/[\w-]+\b(?<!\/pcmasterrace))|(?:\/tb))?(\/comments)??(\/\w{2,7}\b(?<!\/46ijrl)(?<!\/wiki))((?:(?!\))\S)*)))/);
if (redditID) {
const shortcode = `r${redditID[9]}`
return {
url: `${config.getBaseUrl()}/${shortcode}`,
shortcode,
target
}
}
return null;
}
@ -326,8 +507,289 @@ async function validate(username, password, req, reply) {
if (!(await argon2.verify(user[0].password, password))) {
return new Error('Wrong credentials');
}
req.user = username;
}
const bot_html = `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta property="og:title" content="LinkyLinky">
<meta property="og:site_name" content="LinkyLinky by Kauft.es">
<meta property="og:url" content="https://kauft.es/">
<meta property="og:description" content="LinkyLinky by Kauft.es is a custom url shortener. You're reading this, b/c someone doesn't want their shorturl to be indexed by bots/crawlers/spiders.">
<meta property="og:type" content="article">
<meta property="og:image" content="https://kauft.es/dashboard/icon_128.png">
<title>LinkyLinky</title>
</head>
<body>
<p align="center">
<img height="150" src="https://kauft.es/dashboard/icon_128.png">
<h1 align="center">LinkyLinky 🔗</h1>
<h3 align="center">A small url shortener, originaly developed for kauft.es</h3>
<p>LinkyLinky by Kauft.es is a custom url shortener.<br>
You're reading this, b/c someone doesn't want their shorturl to be indexed by bots/crawlers/spiders.</p>
</p>
</body>
</html>
`;
const clientside_html = `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<meta name="robot" content="no-index">
</head>
<body>
<style>
body {
background: black;
overflow: hidden;
}
.containCube {
position: relative;
height: 100vh;
width: 100%;
perspective: 800px;
}
.containCube .cube {
position: absolute;
height: 300px;
width: 300px;
top: 0;
right: 0;
bottom: 0;
left: 0;
margin: auto;
box-sizing: border-box;
transform-style: preserve-3d;
transform-origin: 50% 50%;
-webkit-animation: rotate 20s ease-in-out infinite alternate;
animation: rotate 20s ease-in-out infinite alternate;
}
.containCube .cubeGroup {
position: absolute;
display: grid;
box-sizing: border-box;
height: 100%;
width: 100%;
color: white;
text-shadow: 0 0 1px black;
border: 3px dashed white;
}
.containCube .cubeGroup h1 {
margin: auto;
}
.containCube .cube-front {
transform: translatez(150px);
}
.containCube .cube-rear {
transform: translatez(-150px) rotatey(180deg);
}
.containCube .cube-right {
transform-origin: 100%;
transform: rotatey(90deg) translatex(150px);
}
.containCube .cube-left {
transform-origin: 0%;
transform: rotatey(-90deg) translatex(-150px);
}
.containCube .cube-bottom {
transform-origin: 50% 100%;
transform: rotatex(-90deg) translatey(150px);
}
.containCube .cube-top {
transform-origin: 50% 0%;
transform: rotatex(90deg) translatey(-150px);
}
.containCube .cube-1 {
background: red;
}
.containCube .cube-2 {
background: red;
}
.containCube .cube-3 {
background: red;
}
.containCube .cube-4 {
background: red;
}
.containCube .cube-5 {
background: red;
}
.containCube .cube-6 {
background: red;
}
@-webkit-keyframes rotate {
10% {
transform: rotate3d(1, 1, 0, 320deg);
}
20% {
transform: rotate3d(1, 0, 0, -90deg);
}
30% {
transform: rotate3d(1, 1, 0, 440deg);
}
40% {
transform: rotate3d(1, 0, 0, -180deg);
}
50% {
transform: rotate3d(1, 1, 0, 460deg);
}
60% {
transform: rotate3d(0, 1, 0, -195deg);
}
70% {
transform: rotate3d(1, 1, 0, 172deg);
}
80% {
transform: rotate3d(0, 1, 0, -360deg);
}
90% {
transform: rotate3d(1, 1, 0, 280deg);
}
}
@keyframes rotate {
10% {
transform: rotate3d(1, 1, 0, 320deg);
}
20% {
transform: rotate3d(1, 0, 0, -90deg);
}
30% {
transform: rotate3d(1, 1, 0, 440deg);
}
40% {
transform: rotate3d(1, 0, 0, -180deg);
}
50% {
transform: rotate3d(1, 1, 0, 460deg);
}
60% {
transform: rotate3d(0, 1, 0, -195deg);
}
70% {
transform: rotate3d(1, 1, 0, 172deg);
}
80% {
transform: rotate3d(0, 1, 0, -360deg);
}
90% {
transform: rotate3d(1, 1, 0, 280deg);
}
}
@-webkit-keyframes rotateZed {
20% {
transform: translatez(100px);
}
40% {
transform: translatez(-100px);
}
60% {
transform: translatez(100px);
}
80% {
transform: translatez(-100px);
}
}
@keyframes rotateZed {
20% {
transform: translatez(100px);
}
40% {
transform: translatez(-100px);
}
60% {
transform: translatez(100px);
}
80% {
transform: translatez(-100px);
}
}
</style>
<div class="containCube">
<div class="cube">
<div class="cubeGroup cube-front cube-1">
<h1>kauft.es</h1>
</div>
<div class="cubeGroup cube-top cube-2">
<h1>kauft.es</h1>
</div>
<div class="cubeGroup cube-left cube-3">
<h1>kauft.es</h1>
</div>
<div class="cubeGroup cube-right cube-4">
<h1>kauft.es</h1>
</div>
<div class="cubeGroup cube-rear cube-5">
<h1>kauft.es</h1>
</div>
<div class="cubeGroup cube-bottom cube-6">
<h1>kauft.es</h1>
</div>
</div>
</div>
<script>
setTimeout(function () {
location.replace("{{targeturl}}");
}, 3000);//Delay 3 seconds
</script>
</body>
</html>
`;
// Run the server!
const start = async () => {
try {

837
src/🥵🥵🥵.js Normal file
View File

@ -0,0 +1,837 @@
const emojis = [
"😀",
"😃",
"😄",
"😁",
"😆",
"😅",
"😂",
"🤣",
"😊",
"😇",
"🙂",
"🙃",
"😉",
"😌",
"😍",
"😘",
"😗",
"😙",
"😚",
"😋",
"😛",
"😝",
"😜",
"🤪",
"🤨",
"🧐",
"🤓",
"😎",
"🤩",
"😏",
"🤯",
"😳",
"🤗",
"🤔",
"🤭",
"🤫",
"🤥",
"😶",
"😯",
"😮",
"😲",
"😴",
"🤤",
"🤐",
"🤧",
"😷",
"🤒",
"🤑",
"🤠",
"😈",
"👿",
"👹",
"👺",
"🤡",
"💩",
"👻",
"👽",
"👾",
"🤖",
"🎃",
"😺",
"😸",
"😹",
"😻",
"😼",
"😽",
"🙀",
"😿",
"😾",
"🤲",
"👐",
"🙌",
"👏",
"🤝",
"👍",
"👊",
"✊",
"🤛",
"🤜",
"🤞",
"✌️",
"🤟",
"🤘",
"👈",
"👉",
"👆",
"👇",
"☝️",
"✋",
"🤚",
"🖐",
"🖖",
"👋",
"🤙",
"💪",
"✍️",
"💁‍",
"🙅‍",
"🙋‍",
"🤷‍",
"💃",
"🕺🏻",
"🧥",
"👚",
"👕",
"👖",
"👔",
"👗",
"👙",
"👘",
"👠",
"👡",
"👢",
"👞",
"👟",
"🧦",
"🧤",
"🧣",
"🎩",
"🧢",
"👒",
"🎓",
"⛑",
"👑",
"💍",
"👝",
"👛",
"👜",
"💼",
"🎒",
"👓",
"🕶",
"🌂",
"💢",
"♨️",
"❗️",
"❕",
"❓",
"❔",
"⁉️",
"🔅",
"🔆",
"🚸",
"🔰",
"♻️",
"✅",
"🌀",
"💤",
"🚮",
"🆗",
"🔣",
"🆒",
"🔜",
"✔️",
"🔈",
"🔉",
"🔊",
"📢",
"💬",
"💭",
"🗯",
"🀄️",
"🃏",
"🎴",
"🐶",
"🐱",
"🐭",
"🐹",
"🐰",
"🦊",
"🐻",
"🐼",
"🐨",
"🐯",
"🦁",
"🐮",
"🐷",
"🐽",
"🐸",
"🐵",
"🙈",
"🙉",
"🙊",
"🐒",
"🐔",
"🐧",
"🐦",
"🐤",
"🐣",
"🐥",
"🦆",
"🦅",
"🦉",
"🦇",
"🐺",
"🐗",
"🐴",
"🦄",
"🐝",
"🐌",
"🐞",
"🐜",
"🦗",
"🕷",
"🕸",
"🦂",
"🐢",
"🐍",
"🦎",
"🦖",
"🦕",
"🐙",
"🦑",
"🦐",
"🦀",
"🐡",
"🐠",
"🐟",
"🐬",
"🐳",
"🐋",
"🦈",
"🐊",
"🐅",
"🐆",
"🦓",
"🦍",
"🐘",
"🦏",
"🐪",
"🐫",
"🦒",
"🐃",
"🐂",
"🐄",
"🐎",
"🐖",
"🐏",
"🐑",
"🐐",
"🦌",
"🐕",
"🐩",
"🐈",
"🐓",
"🦃",
"🕊",
"🐇",
"🐁",
"🐀",
"🐿",
"🦔",
"🐾",
"🐉",
"🐲",
"🌵",
"🎄",
"🌲",
"🌳",
"🌴",
"🌱",
"🌿",
"☘️",
"🍀",
"🎍",
"🎋",
"🍃",
"🍂",
"🍁",
"🍄",
"🐚",
"🌾",
"💐",
"🌷",
"🌹",
"🥀",
"🌺",
"🌸",
"🌼",
"🌻",
"🌞",
"🌝",
"🌛",
"🌜",
"🌚",
"🌕",
"🌖",
"🌗",
"🌘",
"🌑",
"🌒",
"🌓",
"🌔",
"🌙",
"🌎",
"🌏",
"💫",
"🌟",
"⚡️",
"☄️",
"🌪",
"☀️",
"🌤",
"⛅️",
"🌥",
"☁️",
"🌦",
"🌧",
"⛈",
"🌩",
"🌨",
"❄️",
"☃️",
"⛄️",
"🌬",
"💨",
"☔️",
"☂️",
"🌊",
"🌫",
"🕐",
"🕑",
"🕒",
"🕓",
"🕔",
"🕕",
"🕖",
"🕗",
"🕘",
"🕙",
"🕚",
"🕛",
"🕜",
"🕝",
"🕞",
"🕟",
"🕠",
"🕡",
"🕢",
"🕣",
"🕤",
"🕥",
"🕦",
"🕧",
"🍏",
"🍎",
"🍐",
"🍊",
"🍋",
"🍌",
"🍉",
"🍇",
"🍓",
"🍈",
"🍒",
"🍍",
"🥥",
"🥝",
"🍅",
"🥑",
"🥦",
"🥒",
"🌶",
"🌽",
"🥕",
"🥔",
"🍠",
"🥐",
"🍞",
"🥖",
"🥨",
"🧀",
"🥚",
"🍳",
"🥞",
"🥓",
"🥩",
"🍗",
"🍖",
"🌭",
"🍔",
"🍟",
"🍕",
"🥪",
"🥙",
"🌮",
"🌯",
"🥗",
"🥘",
"🥫",
"🍝",
"🍲",
"🍛",
"🍣",
"🍱",
"🥟",
"🍤",
"🍙",
"🍚",
"🍘",
"🍥",
"🥠",
"🍢",
"🍡",
"🍧",
"🍨",
"🍦",
"🥧",
"🍰",
"🎂",
"🍮",
"🍭",
"🍬",
"🍫",
"🍿",
"🍩",
"🍪",
"🌰",
"🥜",
"🍯",
"🥛",
"🍼",
"☕️",
"🍵",
"🥤",
"🍶",
"🍺",
"🍻",
"🥂",
"🍷",
"🥃",
"🍸",
"🍹",
"🍾",
"🥄",
"🍴",
"🍽",
"🥣",
"🥡",
"🥢",
"⚽️",
"🏀",
"🏈",
"⚾",
"️🎾",
"🏐",
"🏉",
"🎱",
"🏓",
"🏸",
"🏑",
"🏒",
"🏏",
"🥅",
"⛳️",
"🏹",
"🎣",
"🥊",
"🥋",
"🎽",
"🛷",
"⛸",
"🥌",
"🎿",
"⛷",
"🏂",
"🏆",
"🥇",
"🥈",
"🥉",
"🏅",
"🎖",
"🏵",
"🎗",
"🎫",
"🎟",
"🎪",
"🎭",
"🎨",
"🎬",
"🎤",
"🎧",
"🎼",
"🎹",
"🥁",
"🎷",
"🎺",
"🎸",
"🎻",
"🎲",
"🎳",
"🎮",
"🎰",
"🚗",
"🚕",
"🚙",
"🚌",
"🚎",
"🏎",
"🚓",
"🚑",
"🚒",
"🚐",
"🚚",
"🚛",
"🚜",
"🛴",
"🚲",
"🛵",
"🏍",
"🚔",
"🚍",
"🚘",
"🚖",
"🚡",
"🚠",
"🚟",
"🚃",
"🚋",
"🚞",
"🚝",
"🚄",
"🚅",
"🚈",
"🚂",
"🚆",
"🚇",
"🚊",
"🚉",
"✈️",
"🛫",
"🛬",
"🛩",
"💺",
"🛰",
"🚀",
"🛸",
"🚁",
"🛶",
"⛵️",
"🚤",
"🛥",
"🛳",
"⛴",
"🚢",
"⚓️",
"⛽️",
"🚧",
"🚦",
"🚥",
"🚏",
"🗺",
"🗿",
"🗽",
"🗼",
"🏰",
"🏯",
"🏟",
"🎡",
"🎢",
"🎠",
"⛲️",
"⛱",
"🏖",
"🏝",
"🏜",
"🌋",
"⛰",
"🏔",
"🗻",
"🏕",
"⛺️",
"🏠",
"🏡",
"🏘",
"🏚",
"🏗",
"🏭",
"🏢",
"🏬",
"🏣",
"🏤",
"🏥",
"🏦",
"🏨",
"🏪",
"🏫",
"🏩",
"💒",
"🏛",
"⛪️",
"🕌",
"🕍",
"🕋",
"⛩",
"🛤",
"🛣",
"🗾",
"🎑",
"🏞",
"🌅",
"🌄",
"🌠",
"🎇",
"🎆",
"🌇",
"🏙",
"🌃",
"🌌",
"🌉",
"🌁",
"⌚️",
"📱",
"📲",
"💻",
"⌨️",
"🖥",
"🖨",
"🖱",
"🖲",
"🕹",
"🗜",
"💽",
"💾",
"💿",
"📀",
"📼",
"📷",
"📸",
"📹",
"🎥",
"📽",
"🎞",
"📞",
"☎️",
"📟",
"📠",
"📺",
"📻",
"🎙",
"🎚",
"🎛",
"⏱",
"⏲",
"⏰",
"🕰",
"⏳",
"📡",
"🔋",
"🔌",
"🔦",
"🕯",
"🛢",
"💵",
"💴",
"💶",
"💷",
"💰",
"💳",
"💎",
"⚖️",
"🔧",
"🔨",
"🛠",
"⛏",
"🔩",
"⚙️",
"⛓",
"🔫",
"💣",
"🔪",
"🗡",
"⚔️",
"🛡",
"🏺",
"📿",
"💈",
"⚗️",
"🔭",
"🔬",
"🕳",
"💊",
"💉",
"🌡",
"🚽",
"🚰",
"🚿",
"🛁",
"🛎",
"🔑",
"🗝",
"🚪",
"🛋",
"🛏",
"🛌",
"🖼",
"🛍",
"🛒",
"🎏",
"🎀",
"🎎",
"🏮",
"🎐",
"✉️",
"📩",
"📨",
"📧",
"💌",
"📥",
"📤",
"📦",
"🏷",
"📪",
"📫",
"📬",
"📭",
"📮",
"📯",
"📜",
"📃",
"📄",
"📑",
"📊",
"📈",
"📉",
"🗒",
"🗓",
"📆",
"📅",
"🗑",
"📇",
"🗃",
"🗳",
"🗄",
"📋",
"📁",
"📂",
"🗂",
"🗞",
"📰",
"📓",
"📔",
"📒",
"📕",
"📗",
"📘",
"📙",
"📖",
"🔖",
"🔗",
"📎",
"🖇",
"📐",
"📏",
"📌",
"📍",
"✂️",
"🖊",
"🖋",
"✒️",
"🖌",
"🖍",
"📝",
"✏️",
"🔍",
"🔎",
"🔏",
"🔐",
"🔒",
"🔓",
"🏳️",
"🏁",
"🚩",
"❤️",
"🧡",
"💛",
"💚",
"💙",
"💜",
"🖤",
"💔",
"❣️",
"💕",
"💞",
"💓",
"💗",
"💖",
"💘",
"💝",
"✨",
"💥",
"🔥",
"🌈",
"💧",
"💦",
"🍑",
"🍆",
"🍜",
"🎯",
"🚨",
"💡",
"💸",
"🔮",
"🎁",
"🎈",
"🎊",
"🎉",
"📚",
"🔔",
"📣",
"💅",
"👀",
"🧠",
"🏳️‍🌈",
"🐛",
"🦋",
"💄",
"💋",
"👄",
"💯",
"🎵",
"🎶",
"🙏",
"⭐️"
];
const getEmoji = (number = 10) => {
let id = "";
while (number > 0) {
id += emojis[Math.floor(Math.random() * emojis.length)];
number--;
}
return id;
}
module.exports = getEmoji;

3049
yarn.lock

File diff suppressed because it is too large Load Diff