Code Monkey home page Code Monkey logo

anchr's Introduction

Anchr

Anchr is a small toolbox for common tasks on the internet, including bookmarks, link shortening and image uploads.

🚀 Features

If you like this project, please consider sponsoring it!

🗒 Description

The idea arose when someday I considered it useful to have a collection of web links or bookmarks – like those you have in Chrome or Firefox – accessible from anywhere without needing to synchronize your browser profile. Just like if you’re somewhere on another PC, find a useful article on the internet and want to save it quickly for later at home. This is what Anchr’s collections feature does. It saves links – with an optional description for easier search and separated into categories / collections.

The second feature is to upload images. You can easily upload one or more photos from your computer or mobile device and send them to friends or include them into forum posts or the like. Special with Anchr’s image hosting is that users are given the opportunity to client-sided encrypt images with a password. As a result no one without the password will ever see their photos’ content.

The last feature are shortlinks – actually not any different from those you know from goo.gl or bit.ly. They’re useful if you have a very long web link including many query parameters, access tokens, session ids, special characters and the like and want to share them. Often special characters break the linking or your chat application has a maximum length for hyperlinks. Or you just want to keep clarity in your document or emails. In this case it can be very helpful to make the links as short as any possible. Additionally, shortlinks are checked against Google's Safe Browsing API to prevent your site to reference phishing sites or the like.

Anchr’s focus is on ease and quickness of use – short loading times, flat menu hierarchies, etc. There's also a Chrome extension out there, which you can use to save or shorten links directly from the website.

📡 How to run?

Prerequisites

In order to host Anchr on your own, you need a few things.

  • Node.js >= 20.x
  • MongoDB >= 6.x
    • Alternative 1: Mongo Atlas (hosted cloud MongoDB)
    • Alternative 2: FerretDB (with Postgres or SQLite)

Database Setup

$ mongosh
$ > use anchr;  // choose 'anchr' as your database
$ > db.createUser({user: 'anchr', pwd: passwordPrompt(), roles: [{ role: 'dbOwner', db: 'anchr' }]});  // create user 'anchr'
$ > exit

Configuration

  1. $ git clone https://github.com/muety/anchr
  2. Copy .env.example to .env and edit the contents to set environment variables:
    • PORT: TCP port to start the server on (default: 3000)
    • LISTEN_ADDR: IPv4 address to make the server listen on (default: 127.0.0.1)
    • ANCHR_PUBLIC_URL: Public base URL of your hosted instance (no trailing slash) (default: http://localhost:3000)
    • ANCHR_DB_USER: MongoDB user name (default: anchr)
    • ANCHR_DB_PASSWORD: MongoDB password (required)
    • ANCHR_DB_HOST: MongoDB host name (default: localhost)
    • ANCHR_DB_PORT: MongoDB port (default: 27017)
    • ANCHR_DB_NAME: MongoDB database name (default: anchr)
    • ANCHR_UPLOAD_DIR: Absolute path to a file system directory (must exist!) to persist uploaded images to (default: /var/data/anchr)
    • ANCHR_SECRET: A (preferably long), random character sequence to be used for the JSON Web Token (default: shhh)
    • ANCHR_LOG_PATH: Absolute file path for access logs (directory must exist!) (default: /var/log/anchr/access.log)
    • ANCHR_ERROR_LOG_PATH: Absolute file path for error logs (directory must exist!) (default: /var/log/anchr/error.log)
    • ANCHR_GOOGLE_API_KEY: Your API key for Google APIs (required for safe browse checking incoming shortlinks), which you get from the Developers Console (default: '', leave blank to disable safe browse checking)
    • ANCHR_FB_CLIENT_ID and ANCHR_FB_SECRET: OAuth credentials for Facebook Login (default: '', leave blank to disable Facebook login)
    • ANCHR_GOOGLE_CLIENT_ID and ANCHR_GOOGLE_SECRET: OAuth credentials for Google Login (default: '', leave blank to disable Google login)
    • ANCHR_ALLOW_SIGNUP: Whether to allow sign up of new users (default: true)
    • ANCHR_VERIFY_USERS: Whether require new users to activate their accounts with an e-mail link (requires mailing) (default: true)
    • ANCHR_BASIC_AUTH: Whether to allow authenticating using HTTP Basic Auth (default: true)
    • ANCHR_EXPOSE_METRICS: Whether to expose Prometheus metrics under the public /api/metrics endpoint (default: false)
    • ANCHR_MAIL_SENDER: Sender address in mails from Anchr.io (default: Anchr.io <[email protected]>)
    • ANCHR_SMTP_HOST: SMTP server host for sending mails (leave empty to disable mailing)
    • ANCHR_SMTP_PORT: SMTP server port (default: 587)
    • ANCHR_SMTP_TLS: Whether to establish a TLS connection with the SMTP server (not to be confused with STARTTLS) (default: false)
    • ANCHR_SMTP_USER: SMTP server login username
    • ANCHR_SMTP_PASS: SMTP server login password
    • ANCHR_MAILWHALE_URL: Public URL of your MailWhale instance when using it for mails instead of SMTP (default: https://mailwhale.dev)
    • ANCHR_MAILWHALE_CLIENT_ID: MailWhale client ID for authentication
    • ANCHR_MAILWHALE_CLIENT_SECRET: MailWhale client secret for authentication
    • ANCHR_TELEGRAM_BOT_TOKEN: Telegram bot token (from @BotFather). Leave empty for disabling Telegram integration.
    • ANCHR_TELEGRAM_URL_SECRET: Secret to append to Telegram webhook path for security purposes. Can be any random string.

⚙️ Run

Setup

  1. $ source env.sh
  2. $ corepack enable
  3. $ yarn
  4. $ cd public && ../node_modules/.bin/bower install && cd ..

Option 1: Run Natively

For development
  1. Run backend $ yarn start
  2. Run frontend $ yarn start:frontend
  3. Go to http://localhost:9000 and enjoy live reload
In production
  1. $ yarn run build (to build frontend)
  2. $ yarn run production

Option 2: Run with Docker

  1. source env.sh
  2. docker-compose up

🤖 Telegram Bot Setup

  1. Create a new bot with @BotFather
  2. Configure ANCHR_TELEGRAM_BOT_TOKEN and ANCHR_TELEGRAM_URL_SECRET variables
  3. Configure the webhook:
curl https://api.telegram.org/bot<BOT_TOKEN>/setWebhook?url=https://<ANCHR_URL>/api/telegram/updates/<URL_SECRET>

🧰 Tooling

ShareX (Windows only)

You can integrate Anchr with ShareX on Windows and make it be used as a custom target for image uploads and shortlinks.

  1. Generate an HTTP basic auth hash Base64 hash of [email protected]:yourpassword
  2. Insert your newly generated hash in
  3. Import both files as custom uploaders in ShareX

🧩 Project History

The project's origins lie in 2014, back when the MEAN stack was the sh*t. It was the author's first real web project and a great opportunity to learn. The project is maintained ever since, however, considered mostly feature-complete. Dependencies are updated occasionally. Because the project started quite a couple of years ago, some parts are still based on old-fashioned JavaScript ES5 syntax, alongside vintage tools like Grunt and Bower. Certainly, this is not state-of-the-art in web dev anymore. However, to keep consistency with existing code, the original code style should still be followed in new contributions. Update: Just recently, all backend-side code was refactored to modern JavaScript syntax to ease development.

🧑‍💻 Developer Notes

Upgrade packges

# Backend
$ yarn plugin import interactive-tools
$ yarn upgrade-interactive

# Frontend
$ cat bower.json | jq   '.dependencies | keys[]' -r | xargs npx bower update

📓 License

GNU General Public License v3 (GPL-3) @ Ferdinand Mütsch

anchr's People

Contributors

amixsty avatar gitoffthelawn avatar kidonng avatar muety avatar pgebert avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

anchr's Issues

Replace deprecated MongoDB methods

when I treid to add a new link to collection, an error occurred as below:

[2019-06-11 10:03:43.856] [ERROR] defaultLogger - RES: 203.141.134.112 POST /api/collection/Q
5Fga/links 5cffd9e449a8f92230e6fd56 500 Unknown modifier: $pushAll MongoError: Unknown modifi
er: $pushAll
    at Function.MongoError.create (/srv/anchr/node_modules/mongodb-core/lib/error.js:31:11)
    at toError (/srv/anchr/node_modules/mongoose/node_modules/mongodb/lib/utils.js:114:22)
    at /srv/anchr/node_modules/mongoose/node_modules/mongodb/lib/collection.js:985:67
    at /srv/anchr/node_modules/mongodb-core/lib/topologies/server.js:780:13
    at Callbacks.emit (/srv/anchr/node_modules/mongodb-core/lib/topologies/server.js:95:3)
    at Connection.messageHandler (/srv/anchr/node_modules/mongodb-core/lib/topologies/server.js:249:23)
    at Socket.<anonymous> (/srv/anchr/node_modules/mongodb-core/lib/connection/connection.js:265:22)
    at Socket.emit (events.js:198:13)
    at addChunk (_stream_readable.js:288:12)
    at readableAddChunk (_stream_readable.js:269:11)
    at Socket.Readable.push (_stream_readable.js:224:10)
    at TCP.onStreamRead [as onread] (internal/stream_base_commons.js:94:17)

I had the same error on both Mongo 3.6 and Mongo 4.0.10

Env variable batch script for Windows

I'd like to have a batch script that is equivalent to env.sh to read environment variables from .env and sets them for the current user session. However, I am totally not familiar with batch syntax, so a little help would be great here!

Expose basic metrics via Prometheus interface

Use prom-client to expose metrics like:

  • Total number of users
  • Total number of collections
  • Total number of links in collections
  • Total number of shortlinks
  • Total number of uploaded images (plain, encrypted)
  • Total disk space volume occupied by images

Backend code refactoring / cleanup

  • Better modularity
    • Currently, most logic is contained inside controllers, which also define the REST interface at the same time. Business logic and presentation logic are strongly interleaved, which makes it super hard to be reused. Some parts methods are outsourced to controllers/utils in a quite hacky way and without following a common interface.
  • Refactor to modern ES6-style JavaScript syntax (requires #53)

Make the WebExtension work for Chrome

Although the WebExtensions standard itself is compatible with Chrome, there are various issues that still need to be solved. The extension can be loaded in Chrome, but the following problems occur when using it:

  • Options be clicked
  • Settings can't be saved
  • Probably everything else wouldn't work as well, as it seems that the global browser variable is missing in Chrome.

image

Chrome/Firefox bookmark import

This would be a lifesaver! I'm been on the look out for a bookmark server so that i can import my chrome bookmarks (I have ~5000). Anchr does just that, except for the bookmark import.

Is chrome/firefox bookmark import on the horizon? This would also entail folder capability for the bookmarks.

  • Import netscape compatible bookmarks (chrome/firefox).
  • Flatten folder hierarchy to 1 level.
  • Tags.

anchr.io blocked because "Malware Domain"

When i try to open anchr.io with ublockOrigin in chrome, it loads only the HTML, all JS and CSS are blocked. When i look it up in ublockOrigin's console, it says "Domain ||anchr.io^ found in https://www.malwaredomains.com/" therefore i can't open it (it works with deactivated ublockOrigin though)

As this is probably not expected behavior, someone has probably hacked your site and distributed (or is distributing) malware within...

Compact log messages

/remote endpoint logs while error objects when DNS couldn't be resolved (Error: getaddrinfo ENOTFOUND) instead of just a simple info or warning message.

Error while running 'npm run build'

While running 'npm run build', an error occurred. How can I fix this error?

Loading "cdnify.js" tasks...ERROR
>> ReferenceError: primordials is not defined
Warning: Task "cdnify" failed. Use --force to continue.

Aborted due to warnings.


Execution Time (2019-06-11 06:23:33 UTC-7)
loading tasks             224ms  ▇▇▇▇ 9%
wiredep:app               133ms  ▇▇▇ 5%
wiredep:test               30ms  ▇ 1%
loading grunt-usemin       29ms  ▇ 1%
concurrent:dist           694ms  ▇▇▇▇▇▇▇▇▇▇▇▇▇ 27%
loading grunt-postcss      35ms  ▇ 1%
postcss:server            233ms  ▇▇▇▇▇ 9%
postcss:dist               42ms  ▇ 2%
concat:generated           84ms  ▇▇ 3%
loading grunt-google-cdn  987ms  ▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 38%
Total 2.6s

npm ERR! code ELIFECYCLE
npm ERR! errno 3
npm ERR! [email protected] build: `cd public && grunt build && cd ..`
npm ERR! Exit status 3
npm ERR! 
npm ERR! Failed at the [email protected] build script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /srv/anchr/.npm/_logs/2019-06-11T13_23_35_790Z-debug.log
  • /srv/anchr/.npm/_logs/2019-06-11T13_23_35_790Z-debug.log
0 info it worked if it ends with ok
1 verbose cli [ '/usr/bin/node', '/usr/bin/npm', 'run', 'build' ]
2 info using [email protected]
3 info using [email protected]
4 verbose config Skipping project config: /srv/anchr/.npmrc. (matches userconfig)
5 verbose run-script [ 'prebuild', 'build', 'postbuild' ]
6 info lifecycle [email protected]~prebuild: [email protected]
7 info lifecycle [email protected]~build: [email protected]
8 verbose lifecycle [email protected]~build: unsafe-perm in lifecycle true
9 verbose lifecycle [email protected]~build: PATH: /usr/lib/node_modules/npm/node_modules/npm-lifecycle/node-gyp-bin:/srv/anchr/node_modules/.bin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
10 verbose lifecycle [email protected]~build: CWD: /srv/anchr
11 silly lifecycle [email protected]~build: Args: [ '-c', 'cd public && grunt build && cd ..' ]
12 silly lifecycle [email protected]~build: Returned: code: 3  signal: null
13 info lifecycle [email protected]~build: Failed to exec build script
14 verbose stack Error: [email protected] build: `cd public && grunt build && cd ..`
14 verbose stack Exit status 3
14 verbose stack     at EventEmitter.<anonymous> (/usr/lib/node_modules/npm/node_modules/npm-lifecycle/index.js:301:16)
14 verbose stack     at EventEmitter.emit (events.js:200:13)
14 verbose stack     at ChildProcess.<anonymous> (/usr/lib/node_modules/npm/node_modules/npm-lifecycle/lib/spawn.js:55:14)
14 verbose stack     at ChildProcess.emit (events.js:200:13)
14 verbose stack     at maybeClose (internal/child_process.js:1021:16)
14 verbose stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:283:5)
15 verbose pkgid [email protected]
16 verbose cwd /srv/anchr
17 verbose Linux 4.19.0-5-amd64
18 verbose argv "/usr/bin/node" "/usr/bin/npm" "run" "build"
19 verbose node v12.4.0
20 verbose npm  v6.9.0
21 error code ELIFECYCLE
22 error errno 3
23 error [email protected] build: `cd public && grunt build && cd ..`
23 error Exit status 3
24 error Failed at the [email protected] build script.
24 error This is probably not a problem with npm. There is likely additional logging output above.
25 verbose exit [ 3, true ]

Show loading spinner while resolving website title of new link

When typing or pasting a new link for a collection, a call to /api/remote/page is issued to make the backend crawl the website's HTML title attribute. While this request is pending, a small loading spinner should be shown next to the link description input field to give the user clearer feedback.

Unable to shorten links or upload images

I get errors when I try to shorten links or upload images, I am able to add links to collections though.

This is the error from the server logs when I try to upload an image

req: ***.***.**.*** POST /api/image,
req: ***.***.**.*** POST /api/image  5f427aa90a39630017365047 500 EXDEV: cross-device link not permitted, rename '/tmp/5UZfoKaIBM5ZIDvmBLD1t4Yq.jpg' -> '/var/data/anchr/ChxdP.jpg' Error: EXDEV: cross-device link not permitted, rename '/tmp/5UZfoKaIBM5ZIDvmBLD1t4Yq.jpg' -> '/var/data/anchr/ChxdP.jpg'

and the error when I try to shorten a link

req: ***.***.**.*** POST /api/shortlink,
res:  ***.***.**.*** POST /api/shortlink  5f427aa90a39630017365047 500 Something went wrong.Error: Request failed with status code 403

IP removed for privacy.

Telegram bot

Telegram bot as an interface to Anchr, covering all features:

  • List collections, e.g. /list
  • List links of particular collection, e.g. /list <id> [search|
  • Add links to collection e.g. /add <url> [description]
  • Shorten links, e.g. /shorten <url>
  • Upload images, e.g. just send the bot a picture

Loosely inspired by https://www.producthunt.com/posts/sendtoemail

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.