Skip to content

Commit

Permalink
init API
Browse files Browse the repository at this point in the history
  • Loading branch information
M1CK431 committed Jan 7, 2024
0 parents commit 1ff8446
Show file tree
Hide file tree
Showing 21 changed files with 5,707 additions and 0 deletions.
7 changes: 7 additions & 0 deletions api/.env.development
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
NODE_ENV=development
HOST=localhost
PORT=3000
ALLOWED_DOMAINS=[]
RATE_LIMIT_MS=1000
REDIRECT_LIMIT=10
CURL=curl
28 changes: 28 additions & 0 deletions api/.eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
module.exports = {
root: true,
env: {
es2022: true,
node: true
},
extends: [
"eslint:recommended",
"plugin:prettier/recommended",
"plugin:node/recommended"
],
overrides: [],
parserOptions: {
ecmaVersion: "latest",
sourceType: "module"
},
plugins: ["prettier"],
rules: {
"prettier/prettier": [
"warn",
{ trailingComma: "none", arrowParens: "avoid" }
],
"no-setter-return": "off",
"no-empty": ["error", { allowEmptyCatch: true }],
"no-unused-vars": "warn",
"node/file-extension-in-import": "error"
}
};
140 changes: 140 additions & 0 deletions api/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
.pnpm-debug.log*

# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json

# Runtime data
pids
*.pid
*.seed
*.pid.lock

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage
*.lcov

# nyc test coverage
.nyc_output

# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# Bower dependency directory (https://bower.io/)
bower_components

# node-waf configuration
.lock-wscript

# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release

# Dependency directories
node_modules/
jspm_packages/

# Snowpack dependency directory (https://snowpack.dev/)
web_modules/

# TypeScript cache
*.tsbuildinfo

# Optional npm cache directory
.npm

# Optional eslint cache
.eslintcache

# Optional stylelint cache
.stylelintcache

# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/

# Optional REPL history
.node_repl_history

# Output of 'npm pack'
*.tgz

# Yarn Integrity file
.yarn-integrity

# dotenv environment variable files
.env.development.local
.env.test.local
.env.production
.env.production.local
.env.local

# parcel-bundler cache (https://parceljs.org/)
.cache
.parcel-cache

# Next.js build output
.next
out

# Nuxt.js build / generate output
.nuxt
dist

# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and not Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public

# vuepress build output
.vuepress/dist

# vuepress v2.x temp and cache directory
.temp
.cache

# Docusaurus cache and generated files
.docusaurus

# Serverless directories
.serverless/

# FuseBox cache
.fusebox/

# DynamoDB Local files
.dynamodb/

# TernJS port file
.tern-port

# Stores VSCode versions used for testing VSCode extensions
.vscode-test

# yarn v2
.yarn/cache
.yarn/unplugged
.yarn/build-state.yml
.yarn/install-state.gz
.pnp.*

# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
153 changes: 153 additions & 0 deletions api/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
# <img alt="logo" src="../webapp/public/url-checker.png" align="left" height="38" /> URL Checker

API for URL Checker, a tool to easily check URLs in a sitemap.

## Setup

### Prerequisites

* At least [Node.js](https://nodejs.org/) v18.12 is required (but always use latest LTS if possible)
* Only Linux based systems are officially supported
* API is using [curl](https://curl.se/) for URL checking, at least v7.70 must be installed

### Install dependencies for Production

Once placed in the `api` directory:

```sh
pnpm i -P
```

### Installation

For obvious security reason, create a dedicated system user/group:

```sh
useradd --system -s /usr/bin/nologin -U url-checker
```

⚠️ If you use another user/group name, don't forget to update the systemd service `User` and `Group` directives (see below).

The API only need write access to its sqlite db:

```sh
chown url-checker: ./db.sqlite
chmod 644 ./db.sqlite
```

⚠️ Other files should be owned by another user/group (`root` for example)\
⚠️ Other files should be read-only for anyone (`644` permissions).

Then copy (or symlink) the provided systemd service and enable/start it:

```sh
ln -sn /etc/systemd/system/url-checker.service ./url-checker.service
# OR, if you need to adapt it for your setup
cp -a ./url-checker.service /etc/systemd/system/

chown root: /etc/systemd/system/url-checker.service
chmod 644 /etc/systemd/system/url-checker.service

systemctl daemon-reload
systemctl enable --now url-checker
```

🎉️ That's it! The API should now be up and running on default [http://localhost:3000/graphql](http://localhost:3000/graphql)

ℹ️ By default, nothing is publicly exposed. See [Setup with Apache web server](../webapp/README.md#setup-with-apache-web-server) for a reverse proxy configuration example.

### Customize configuration

There are some settings you can change as environment variables:

| Name | Default | Description |
| ------------------- | ------------- | ------------------------------------------------------------- |
| `HOST` | `localhost` | Host to listen on |
| `PORT` | `3000` | Port to listen on |
| `ALLOWED_DOMAINS` | `[]` | Array of allowed**domains hostname** to check |
| `RATE_LIMIT_MS` | `1000` | Single URL check rate limit (in ms) |
| `REDIRECT_LIMIT` | `10` | Max internal cascading redirections to follow |
| `CURL` | `curl` | `curl` binary to use (see [troubleshooting](#troubleshooting)) |

A sample [environment file](./.env.development) is provided with default values for the development environnement.\
Example `ALLOWED_DOMAINS` valid value: `["toto.com", "titi.fr"]`.

## Upgrade

The simplest way to upgrade the API is using the following `git` commands in the monorepo directory (where `.git` stands):

```sh
git fetch
git reset --hard origin/master
```

Then redo the [Install dependencies for Production](#install-dependencies-for-production) step and restart the API systemd service:

```sh
systemctl restart url-checker
```

⚠️ If you have copied the systemd service (for example to use a user/group different from the default),
please ensure that nothing was changed in this file in the upgraded version.

ℹ️ Notice that this will upgrade both API and Webapp so don't forget to also follow [Webapp upgrade instructions](../webapp/README.md#upgrade).

## Troubleshooting

In case you see this error message while trying to check a single URL:

```
ApolloError: Response not successful: Received status code 503
```

You are probably affected by [this curl bug](https://github.com/curl/curl/issues/6905).
No worries, I have a good news for you: a simple workaround is available!

Copy `.env.development` to `.env.production` and change `CURL` env variable with:

```ini
CURL=./curl_7.76.1_workaround_wrapper
```

⚠️ `curl_7.76.1_workaround_wrapper` must be set as executable:

```sh
chmod 755 ./curl_7.76.1_workaround_wrapper
```

Then restart the API systemd service:

```sh
systemctl restart url-checker
```

Everything should now works properly.


## For developers

Following this instructions is needed **only if you want to contribute** to the code of the API.

## Install dependencies

```sh
pnpm i
```

### Hot-Reload for Development

```sh
pnpm dev
```

### Start for Production

```sh
pnpm start
```

### Lint with [ESLint](https://eslint.org/)

```sh
pnpm lint
```
5 changes: 5 additions & 0 deletions api/curl_7.76.1_workaround_wrapper
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/bin/bash
# This is a workaround for this issue:
# https://github.com/curl/curl/issues/6905

curl $@ | sed 's/":000,"/":0,"/g'
Empty file added api/db.sqlite
Empty file.
47 changes: 47 additions & 0 deletions api/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
{
"name": "url-checker",
"version": "1.0.0",
"description": "URL Checker API",
"main": "src",
"type": "module",
"engines": {
"node": ">=18.12.0",
"pnpm": ">=8.0.0"
},
"repository": "https://git.leguidedupatrimoine.com/leguidedupatrimoine/url-checker",
"author": "Le Guide du Patrimoine",
"license": "UNLICENSED",
"private": true,
"scripts": {
"preinstall": "npx only-allow pnpm",
"dev": "node -r dotenv/config --watch src dotenv_config_path=.env.development",
"start": "NODE_ENV=production node -r dotenv/config src dotenv_config_path=.env.production",
"lint": "eslint . --ext .js,.cjs,.mjs --fix --ignore-path .gitignore"
},
"devDependencies": {
"eslint": "^8.56.0",
"eslint-config-node": "^4.1.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-prettier": "^5.0.1",
"prettier": "^3.1.1"
},
"dependencies": {
"@apollo/server": "^4.9.5",
"@as-integrations/koa": "^1.1.1",
"@koa/cors": "^5.0.0",
"@koa/router": "^12.0.1",
"domutils": "^3.1.0",
"dotenv": "^16.3.1",
"graphql": "^16.8.1",
"graphql-parse-resolve-info": "^4.13.0",
"graphql-subscriptions": "^2.0.0",
"graphql-ws": "^5.14.2",
"htmlparser2": "^9.0.0",
"koa": "^2.14.2",
"koa-bodyparser": "^4.4.1",
"sequelize": "^6.35.2",
"sqlite3": "^5.1.6",
"ws": "^8.15.1"
}
}
Loading

0 comments on commit 1ff8446

Please sign in to comment.