beavuck-time 2.3.5 → 2.3.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/api.js +20 -0
- package/build/config/corsOptions.js +60 -0
- package/build/config/logger.js +36 -0
- package/build/controllers/nowController.js +30 -0
- package/build/errors/BeavuckTimeClientError.js +13 -0
- package/build/errors/BeavuckTimeServerError.js +16 -0
- package/build/errors/CorsError.js +13 -0
- package/build/errors/base/BeavuckTimeError.js +14 -0
- package/build/middlewares/corsMiddleware.js +34 -0
- package/build/middlewares/errorHandler.js +47 -0
- package/build/middlewares/notFoundHandler.js +9 -0
- package/build/middlewares/rateLimiter.js +16 -0
- package/build/models/now.js +14 -0
- package/build/routes/routes.js +54 -0
- package/build/server.js +63 -0
- package/build/services/nowService.js +11 -0
- package/build/types/isoTimestamp.js +4 -0
- package/build/utils/urlUtil.js +31 -0
- package/openapi/swagger.json +1 -1
- package/package.json +14 -4
- package/.env +0 -21
- package/.env.test +0 -30
- package/.gitlab/issue_templates/bug.md +0 -53
- package/.gitlab/issue_templates/enhancement.md +0 -53
- package/.gitlab/merge_request_templates/bug_fix.md +0 -9
- package/.gitlab/merge_request_templates/enhancement.md +0 -9
- package/.gitlab-ci.yml +0 -158
- package/.nvmrc +0 -1
- package/.sonarlint/connectedMode.json +0 -4
- package/DOCKERHUB_OVERVIEW.md +0 -185
- package/Dockerfile +0 -25
- package/HELP.md +0 -53
- package/api-tests/bruno/bruno.json +0 -9
- package/api-tests/bruno/collection.bru +0 -7
- package/api-tests/bruno/environments/local.bru +0 -8
- package/api-tests/bruno/now/nok/nok_no_origin.bru +0 -19
- package/api-tests/bruno/now/nok/nok_non_recognized_referrer.bru +0 -23
- package/api-tests/bruno/now/nok/nok_non_trusted_origin.bru +0 -23
- package/api-tests/bruno/now/nok/nok_non_truted_origin_nor_referrer.bru +0 -24
- package/api-tests/bruno/now/ok/ok_same_origin.bru +0 -23
- package/api-tests/bruno/now/ok/ok_same_referrer.bru +0 -23
- package/api-tests/bruno/now/ok/ok_trusted_origin.bru +0 -23
- package/eslint.config.mjs +0 -28
- package/sonar-project.properties +0 -9
- package/src/__tests__/api.test.ts +0 -98
- package/src/__tests__/middlewares/errorHandler.test.ts +0 -93
- package/src/__tests__/utils/urlUtil.test.ts +0 -53
- package/src/api.ts +0 -19
- package/src/config/corsOptions.ts +0 -63
- package/src/config/logger.ts +0 -38
- package/src/controllers/nowController.ts +0 -19
- package/src/errors/BeavuckTimeClientError.ts +0 -12
- package/src/errors/BeavuckTimeServerError.ts +0 -18
- package/src/errors/CorsError.ts +0 -12
- package/src/errors/base/BeavuckTimeError.ts +0 -12
- package/src/middlewares/corsMiddleware.ts +0 -32
- package/src/middlewares/errorHandler.ts +0 -57
- package/src/middlewares/notFoundHandler.ts +0 -8
- package/src/middlewares/rateLimiter.ts +0 -15
- package/src/models/now.ts +0 -14
- package/src/routes/routes.ts +0 -84
- package/src/server.ts +0 -83
- package/src/services/nowService.ts +0 -9
- package/src/types/isoTimestamp.ts +0 -8
- package/src/utils/urlUtil.ts +0 -29
- package/tsconfig.json +0 -38
- package/tsoa.json +0 -12
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
## 🗒️ Summary
|
|
2
|
-
|
|
3
|
-
(_Summarize the bug encountered concisely. "X happens"_)
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## 🐛 What is the current bug behavior?
|
|
8
|
-
|
|
9
|
-
(_What actually happens. "When W, then X"_)
|
|
10
|
-
|
|
11
|
-
---
|
|
12
|
-
|
|
13
|
-
## 🟢 What is the expected correct behavior?
|
|
14
|
-
|
|
15
|
-
(_What you should see instead. "When W, then 42"_)
|
|
16
|
-
|
|
17
|
-
---
|
|
18
|
-
|
|
19
|
-
## 📋 Steps to reproduce
|
|
20
|
-
|
|
21
|
-
(_How one can reproduce the issue - this is very important. Please use a numbered list_)
|
|
22
|
-
|
|
23
|
-
1. Step 1
|
|
24
|
-
2. Step 2
|
|
25
|
-
3. Step 3
|
|
26
|
-
|
|
27
|
-
...
|
|
28
|
-
|
|
29
|
-
---
|
|
30
|
-
|
|
31
|
-
## 📜 Relevant logs and/or screenshots
|
|
32
|
-
|
|
33
|
-
(_Paste any relevant logs - please use code blocks (```) to format console output, logs, etc. as it's very hard to read otherwise._)
|
|
34
|
-
|
|
35
|
-
(_for example_:
|
|
36
|
-
|
|
37
|
-
```
|
|
38
|
-
Error: something went wrong
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
)
|
|
42
|
-
|
|
43
|
-
---
|
|
44
|
-
|
|
45
|
-
## ⛳ Possible fixes
|
|
46
|
-
|
|
47
|
-
(_Optional: If you have an idea of how to fix this, link to the code or describe the solution_)
|
|
48
|
-
|
|
49
|
-
---
|
|
50
|
-
|
|
51
|
-
(_Automatically adds the bug label for easier tracking_)
|
|
52
|
-
|
|
53
|
-
/label ~bug
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
## 🗒️ Summary
|
|
2
|
-
|
|
3
|
-
(_Summarize the enhancement you'd like to see implemented concisely. "Add X functionality"_)
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## 🔍 What problem does this enhancement solve?
|
|
8
|
-
|
|
9
|
-
(_Describe the problem this enhancement would address. "Currently, Y is a limitation, and adding X would solve it"_)
|
|
10
|
-
|
|
11
|
-
---
|
|
12
|
-
|
|
13
|
-
## 🎯 What is the proposed solution?
|
|
14
|
-
|
|
15
|
-
(_Describe how you envision this enhancement being implemented. "Add a new method for Z"_)
|
|
16
|
-
|
|
17
|
-
---
|
|
18
|
-
|
|
19
|
-
## 🚀 Why is this enhancement valuable to the product?
|
|
20
|
-
|
|
21
|
-
(_Explain why this enhancement would improve the product. "This would make the process faster, reduce errors, etc."_)
|
|
22
|
-
|
|
23
|
-
---
|
|
24
|
-
|
|
25
|
-
## 📋 Steps to use the feature (if the enhancement is indeed a feature)
|
|
26
|
-
|
|
27
|
-
(_How will users interact with this feature? Describe the user journey or interface interactions.
|
|
28
|
-
For bonus points, use a user story format, and add a
|
|
29
|
-
[sequence diagram](https://mermaid.js.org/syntax/sequenceDiagram.html) or [flowchart](https://mermaid.js.org/syntax/flowchart.html)_)
|
|
30
|
-
|
|
31
|
-
(_For example_:
|
|
32
|
-
|
|
33
|
-
```mermaid
|
|
34
|
-
sequenceDiagram
|
|
35
|
-
participant Client
|
|
36
|
-
participant API
|
|
37
|
-
Client->>API: GET /now (ask for time)
|
|
38
|
-
API->>Client: {"now": "2024-06-14T18:25:46.835Z"} (responds with time)
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
)
|
|
42
|
-
|
|
43
|
-
---
|
|
44
|
-
|
|
45
|
-
## 📜 Additional details, mockups, or screenshots
|
|
46
|
-
|
|
47
|
-
(_If applicable, attach any additional context, mockups, or screenshots that help explain the enhancement_)
|
|
48
|
-
|
|
49
|
-
---
|
|
50
|
-
|
|
51
|
-
(_Automatically adds the enhancement label for easier tracking_)
|
|
52
|
-
|
|
53
|
-
/label ~enhancement
|
package/.gitlab-ci.yml
DELETED
|
@@ -1,158 +0,0 @@
|
|
|
1
|
-
########~~~~-- Stages --~~~~########
|
|
2
|
-
|
|
3
|
-
stages:
|
|
4
|
-
- secure
|
|
5
|
-
- test
|
|
6
|
-
- update
|
|
7
|
-
- build
|
|
8
|
-
- deploy
|
|
9
|
-
|
|
10
|
-
########~~~~-- Variables & defaults --~~~~########
|
|
11
|
-
|
|
12
|
-
variables:
|
|
13
|
-
IMAGE: "${CI_DEPENDENCY_PROXY_DIRECT_GROUP_IMAGE_PREFIX}/node:lts-jod"
|
|
14
|
-
SCRIPT_TO_INSTALL_DEPS: "apt-get update && apt-get install -y git bash curl jq && npm install -g npm@latest && npm ci"
|
|
15
|
-
|
|
16
|
-
default:
|
|
17
|
-
image: $IMAGE
|
|
18
|
-
interruptible: true
|
|
19
|
-
|
|
20
|
-
########~~~~-- Workflows --~~~~########
|
|
21
|
-
|
|
22
|
-
workflow:
|
|
23
|
-
auto_cancel:
|
|
24
|
-
on_new_commit: interruptible
|
|
25
|
-
on_job_failure: all
|
|
26
|
-
rules:
|
|
27
|
-
- if: "$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH"
|
|
28
|
-
- if: "$CI_COMMIT_TAG"
|
|
29
|
-
- if: "$CI_PIPELINE_SOURCE == 'schedule'"
|
|
30
|
-
- if: "$CI_PIPELINE_SOURCE == 'merge_request_event'"
|
|
31
|
-
|
|
32
|
-
########~~~~-- Includes --~~~~########
|
|
33
|
-
|
|
34
|
-
include:
|
|
35
|
-
- component: "$CI_SERVER_FQDN/beavuck-services/ci-cd-catalog/secret-finder/secret-finder@main"
|
|
36
|
-
inputs:
|
|
37
|
-
job_name: "find_secrets"
|
|
38
|
-
stage_config: "secure"
|
|
39
|
-
|
|
40
|
-
- component: "$CI_SERVER_FQDN/beavuck-services/ci-cd-catalog/command-runner/command-runner@main"
|
|
41
|
-
inputs:
|
|
42
|
-
job_name: "format"
|
|
43
|
-
stage_config: ".pre"
|
|
44
|
-
branch_name: "$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME"
|
|
45
|
-
command: "npm ci && npm run clean"
|
|
46
|
-
commit_message: "🎨 Format code automatically"
|
|
47
|
-
image: "$IMAGE"
|
|
48
|
-
script_to_install_deps: "$SCRIPT_TO_INSTALL_DEPS"
|
|
49
|
-
consecutive_command_commits_allowed: false
|
|
50
|
-
|
|
51
|
-
- component: "$CI_SERVER_FQDN/beavuck-services/ci-cd-catalog/command-runner/command-runner@main"
|
|
52
|
-
inputs:
|
|
53
|
-
job_name: "update"
|
|
54
|
-
stage_config: "update"
|
|
55
|
-
branch_name: "chore/update-dependencies"
|
|
56
|
-
command: "npm run update-dependencies && npm run up-patch"
|
|
57
|
-
commit_message: "⚙️ Update dependencies automatically"
|
|
58
|
-
image: "$IMAGE"
|
|
59
|
-
script_to_install_deps: "$SCRIPT_TO_INSTALL_DEPS"
|
|
60
|
-
consecutive_command_commits_allowed: true
|
|
61
|
-
|
|
62
|
-
- component: "$CI_SERVER_FQDN/beavuck-services/ci-cd-catalog/docker-publisher/docker-publisher@main"
|
|
63
|
-
inputs:
|
|
64
|
-
job_name: "publish_to_docker"
|
|
65
|
-
stage_config: "deploy"
|
|
66
|
-
image_name: "beavuck/time"
|
|
67
|
-
publish_to_dockerhub: true
|
|
68
|
-
|
|
69
|
-
find_secrets:
|
|
70
|
-
rules:
|
|
71
|
-
- if: "$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH"
|
|
72
|
-
- if: "$CI_PIPELINE_SOURCE == 'merge_request_event'"
|
|
73
|
-
|
|
74
|
-
update:
|
|
75
|
-
rules:
|
|
76
|
-
- if: "$CI_PIPELINE_SOURCE == 'schedule' && $IS_UPDATE == 'true'"
|
|
77
|
-
|
|
78
|
-
format:
|
|
79
|
-
rules:
|
|
80
|
-
- if: "$CI_PIPELINE_SOURCE == 'merge_request_event'"
|
|
81
|
-
|
|
82
|
-
publish_to_docker:
|
|
83
|
-
rules:
|
|
84
|
-
- if: "$CI_COMMIT_TAG"
|
|
85
|
-
when: manual
|
|
86
|
-
|
|
87
|
-
########~~~~-- Jobs --~~~~########
|
|
88
|
-
|
|
89
|
-
run_integration_tests:
|
|
90
|
-
stage: test
|
|
91
|
-
variables:
|
|
92
|
-
API_PORT: 3000
|
|
93
|
-
HOST_URL: http://localhost:3000
|
|
94
|
-
TRUSTED_ORIGINS: http://localhost:8477
|
|
95
|
-
before_script:
|
|
96
|
-
- npm install -g npm@latest
|
|
97
|
-
- npm ci
|
|
98
|
-
- npm run build
|
|
99
|
-
- npm start & sleep 10
|
|
100
|
-
script: npm run run-integration-tests
|
|
101
|
-
rules:
|
|
102
|
-
- if: "$CI_PIPELINE_SOURCE == 'merge_request_event'"
|
|
103
|
-
- if: "$CI_COMMIT_TAG"
|
|
104
|
-
needs:
|
|
105
|
-
- job: find_secrets
|
|
106
|
-
optional: true
|
|
107
|
-
|
|
108
|
-
coverage:
|
|
109
|
-
stage: test
|
|
110
|
-
artifacts:
|
|
111
|
-
paths: [coverage/lcov.info]
|
|
112
|
-
reports:
|
|
113
|
-
coverage_report:
|
|
114
|
-
coverage_format: cobertura
|
|
115
|
-
path: coverage/cobertura-coverage.xml
|
|
116
|
-
before_script: npm install -g npm@latest && npm ci
|
|
117
|
-
script: npm run test
|
|
118
|
-
rules:
|
|
119
|
-
- if: "$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH"
|
|
120
|
-
- if: "$CI_PIPELINE_SOURCE == 'merge_request_event'"
|
|
121
|
-
- if: "$CI_COMMIT_TAG"
|
|
122
|
-
needs:
|
|
123
|
-
- job: find_secrets
|
|
124
|
-
optional: true
|
|
125
|
-
|
|
126
|
-
analyze:
|
|
127
|
-
stage: test
|
|
128
|
-
image:
|
|
129
|
-
name: "${CI_DEPENDENCY_PROXY_DIRECT_GROUP_IMAGE_PREFIX}/sonarsource/sonar-scanner-cli:latest"
|
|
130
|
-
entrypoint: [""]
|
|
131
|
-
cache:
|
|
132
|
-
key: "${CI_JOB_NAME}"
|
|
133
|
-
paths: [.sonar/cache]
|
|
134
|
-
variables:
|
|
135
|
-
SONAR_USER_HOME: "${CI_PROJECT_DIR}/.sonar" # Defines the location of the analysis task cache
|
|
136
|
-
GIT_DEPTH: 0 # Tells git to fetch all the branches of the project, required by the analysis task
|
|
137
|
-
script:
|
|
138
|
-
- git config --global --add safe.directory "/builds/$CI_PROJECT_PATH"
|
|
139
|
-
- LATEST_TAG=$(git describe --tags `git rev-list --tags --max-count=1`)
|
|
140
|
-
- if [ "$CI_COMMIT_BRANCH" == "$CI_DEFAULT_BRANCH" ]; then PROJECT_VERSION=$LATEST_TAG; else PROJECT_VERSION=$LATEST_TAG-$CI_MERGE_REQUEST_ID; fi
|
|
141
|
-
- sonar-scanner -Dsonar.projectVersion=$PROJECT_VERSION
|
|
142
|
-
rules:
|
|
143
|
-
- if: "$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH"
|
|
144
|
-
- if: "$CI_PIPELINE_SOURCE == 'merge_request_event'"
|
|
145
|
-
needs:
|
|
146
|
-
- job: find_secrets
|
|
147
|
-
optional: true
|
|
148
|
-
- job: coverage
|
|
149
|
-
artifacts: true
|
|
150
|
-
|
|
151
|
-
publish_to_npm:
|
|
152
|
-
stage: deploy
|
|
153
|
-
before_script:
|
|
154
|
-
- echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > .npmrc
|
|
155
|
-
script: npm publish --access public
|
|
156
|
-
rules:
|
|
157
|
-
- if: "$CI_COMMIT_TAG"
|
|
158
|
-
when: manual
|
package/.nvmrc
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
lts/jod
|
package/DOCKERHUB_OVERVIEW.md
DELETED
|
@@ -1,185 +0,0 @@
|
|
|
1
|
-
# ⏲️ Beavuck Time
|
|
2
|
-
|
|
3
|
-
## 📊 Status
|
|
4
|
-
|
|
5
|
-
[](https://sonarcloud.io/summary/new_code?id=beavuck-services_time)
|
|
6
|
-
|
|
7
|
-
[](https://sonarcloud.io/summary/new_code?id=beavuck-services_time)
|
|
8
|
-
[](https://sonarcloud.io/summary/new_code?id=beavuck-services_time)
|
|
9
|
-
|
|
10
|
-
[](https://sonarcloud.io/summary/new_code?id=beavuck-services_time)
|
|
11
|
-
[](https://sonarcloud.io/summary/new_code?id=beavuck-services_time)
|
|
12
|
-
|
|
13
|
-
[](https://sonarcloud.io/summary/new_code?id=beavuck-services_time)
|
|
14
|
-
[](https://sonarcloud.io/summary/new_code?id=beavuck-services_time)
|
|
15
|
-
[](https://sonarcloud.io/summary/new_code?id=beavuck-services_time)
|
|
16
|
-
|
|
17
|
-
[](https://sonarcloud.io/summary/new_code?id=beavuck-services_time)
|
|
18
|
-
[](https://sonarcloud.io/summary/new_code?id=beavuck-services_time)
|
|
19
|
-
|
|
20
|
-
[](https://sonarcloud.io/summary/new_code?id=beavuck-services_time)
|
|
21
|
-
|
|
22
|
-
---
|
|
23
|
-
|
|
24
|
-
## 💡 Why
|
|
25
|
-
|
|
26
|
-
You can't count on client devices to all be set up with the correct date and time.
|
|
27
|
-
|
|
28
|
-
But keeping track of time is usually busywork, not the business of your core APIs. And you probably don't want to flood
|
|
29
|
-
your own APIs, whenever you want to get an accurate timestamp for entities in your apps.
|
|
30
|
-
|
|
31
|
-
So you can set up this simple microservice, whose only job should be to answer the question: "what time is it right
|
|
32
|
-
now?"
|
|
33
|
-
|
|
34
|
-
---
|
|
35
|
-
|
|
36
|
-
## 🎯 What
|
|
37
|
-
|
|
38
|
-
Get the current time in ISO format, in UTC timezone.
|
|
39
|
-
|
|
40
|
-
This lightweight service focuses on one job.
|
|
41
|
-
|
|
42
|
-
It needs no persistence layer, is capable of handling multiple concurrent requests, and is protected by a simple
|
|
43
|
-
CORS config for security and performance reasons.
|
|
44
|
-
|
|
45
|
-
Dockerized for easy deployment and scaling.
|
|
46
|
-
|
|
47
|
-
---
|
|
48
|
-
|
|
49
|
-
## 🔍 Where
|
|
50
|
-
|
|
51
|
-
The code lives on [GitLab](https://gitlab.com/beavuck-services/time),
|
|
52
|
-
and the Docker image is hosted on [Docker Hub](https://hub.docker.com/r/beavuck/time)
|
|
53
|
-
|
|
54
|
-
### 🦊 GitLab
|
|
55
|
-
|
|
56
|
-
You can find the code on GitLab, where, once you have read the [CONTRIBUTING.md](https://gitlab.com/beavuck-services/time/-/blob/main/CONTRIBUTING.md?ref_type=heads) file, you can also
|
|
57
|
-
create issues and merge requests.
|
|
58
|
-
|
|
59
|
-
Feel free to fork the repo and make your own changes at will, as per the [UNLICENSE](https://gitlab.com/beavuck-services/time/-/blob/main/UNLICENSE?ref_type=heads).
|
|
60
|
-
|
|
61
|
-
### 🐳 Docker Hub
|
|
62
|
-
|
|
63
|
-
Most devs will only use Docker Hub for their purposes with this project, to use it as is as a dependency for their own
|
|
64
|
-
projects. On Docker Hub, while you're developing, you should use the `beavuck/time:latest` tag to always get the latest
|
|
65
|
-
version.
|
|
66
|
-
|
|
67
|
-
When the time comes to go to production, to protect yourself from surprise breaking changes, you should instead point to
|
|
68
|
-
specific minor version tags, such as `beavuck/time:2.0` : those will not get breaking changes, but they will get
|
|
69
|
-
security updates and bug fixes while they're active.
|
|
70
|
-
|
|
71
|
-
---
|
|
72
|
-
|
|
73
|
-
## ⚙️ Usage
|
|
74
|
-
|
|
75
|
-
### 🪧 Set up (docker-compose example)
|
|
76
|
-
|
|
77
|
-
To run the service in a docker-compose environment, add this in your `docker-compose.yml`'s services section:
|
|
78
|
-
|
|
79
|
-
```yaml
|
|
80
|
-
time:
|
|
81
|
-
image: beavuck/time:latest
|
|
82
|
-
ports:
|
|
83
|
-
- 'SOME_PORT_NUMBER:3000'
|
|
84
|
-
# HOST_PORT:CONTAINER_PORT (Since we are in a container, CONTAINER_PORT corresponds to the API_PORT variable below)
|
|
85
|
-
environment:
|
|
86
|
-
- BEAVUCK_TIME_HOST_URL: https://time-api.example.com
|
|
87
|
-
# BEAVUCK_TIME_HOST_URL: That API's URL. Essential for CORS config.
|
|
88
|
-
- BEAVUCK_TIME_TRUSTED_ORIGINS: https://my.app.com,https://my-other.app.com
|
|
89
|
-
# BEAVUCK_TIME_TRUSTED_ORIGINS: To allow requests from any origin, include * (not recommended). If empty, will only allow requests from the HOST_URL's origin. Defaults to the HOST_URL's origin
|
|
90
|
-
- BEAVUCK_TIME_API_PORT: 3000
|
|
91
|
-
# BEAVUCK_TIME_API_PORT: Optional. Internal port when in a container. Defaults to 3000
|
|
92
|
-
- BEAVUCK_TIME_RATE_LIMIT: 100
|
|
93
|
-
# BEAVUCK_TIME_RATE_LIMIT: Optional. Max allowed number of requests per minute for each IP address. If negative or 0, no limit. Defaults to no limit
|
|
94
|
-
- BEAVUCK_TIME_LOG_LEVEL: info
|
|
95
|
-
# BEAVUCK_TIME_LOG_LEVEL: Optional. Logging levels include error, warn, info, http, verbose, debug, silly. Defaults to info
|
|
96
|
-
- BEAVUCK_TIME_MAX_LOG_FILES: 64
|
|
97
|
-
# BEAVUCK_TIME_MAX_LOG_FILES: Optional. Maximum number of logs to keep. This can be a number of files or number of days. If using days, add 'd' as the suffix. Default is 64
|
|
98
|
-
- BEAVUCK_TIME_MAX_SIZE_LOG_FILES: 1m
|
|
99
|
-
# BEAVUCK_TIME_MAX_SIZE_LOG_FILES: Optional. Maximum size of the file after which it will rotate. This can be a number of bytes, or units of kb, mb, and gb. If using the units, add 'k', 'm', or 'g' as the suffix. The units need to directly follow the number. Default is 1m
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
Here's the simple docker compose file I used to test this service locally:
|
|
103
|
-
|
|
104
|
-
```yaml
|
|
105
|
-
services:
|
|
106
|
-
time:
|
|
107
|
-
image: beavuck/time:latest
|
|
108
|
-
ports:
|
|
109
|
-
- '3000:3000'
|
|
110
|
-
environment:
|
|
111
|
-
BEAVUCK_TIME_HOST_URL: http://127.0.0.1:3000
|
|
112
|
-
BEAVUCK_TIME_TRUSTED_ORIGINS: http://127.0.0.1:8000,http://localhost:8000
|
|
113
|
-
BEAVUCK_TIME_LOG_LEVEL: debug
|
|
114
|
-
```
|
|
115
|
-
|
|
116
|
-
When you're ready, just run your services with:
|
|
117
|
-
|
|
118
|
-
```shell
|
|
119
|
-
docker compose up -d
|
|
120
|
-
```
|
|
121
|
-
|
|
122
|
-
### ✨ Using the service
|
|
123
|
-
|
|
124
|
-
Now, when you run:
|
|
125
|
-
|
|
126
|
-
```shell
|
|
127
|
-
curl --location 'http://localhost:{{SOME_PORT_NUMBER}}/now' \
|
|
128
|
-
--header 'Origin: {{SOME_TRUSTED_ORIGIN}}'
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
you should expect an answer such as:
|
|
132
|
-
|
|
133
|
-
```json
|
|
134
|
-
{
|
|
135
|
-
"now": "2024-06-15T12:35:48.022Z"
|
|
136
|
-
}
|
|
137
|
-
```
|
|
138
|
-
|
|
139
|
-
---
|
|
140
|
-
|
|
141
|
-
## 🛡️ CORS
|
|
142
|
-
|
|
143
|
-
This service is protected by a CORS policy, which you can configure by setting the `TRUSTED_ORIGINS` environment
|
|
144
|
-
variable.
|
|
145
|
-
|
|
146
|
-
When you use the API, keep in mind what roles these headers play:
|
|
147
|
-
|
|
148
|
-
| `"Origin:"` | `"Referrer:"`* | Result |
|
|
149
|
-
| --------------------------------------------------------- | ------------------------------ | ------ |
|
|
150
|
-
| Defined and API `BEAVUCK_TIME_TRUSTED_ORIGINS` set to `*` | Whatever | ✅ |
|
|
151
|
-
| Trusted | Whatever | ✅ |
|
|
152
|
-
| Same as this API's host | Whatever | ✅ |
|
|
153
|
-
| Not defined | Same as this API's host | ✅ |
|
|
154
|
-
| Defined and not trusted | Whatever | 🛑 |
|
|
155
|
-
| Not defined | Not defined | 🛑 |
|
|
156
|
-
| Not defined or not trusted | Different from this API's host | 🛑 |
|
|
157
|
-
* AKA `Referer` (sic).
|
|
158
|
-
---
|
|
159
|
-
|
|
160
|
-
## 📚 Use cases
|
|
161
|
-
|
|
162
|
-
### Batch `POST`s
|
|
163
|
-
|
|
164
|
-
Suppose you're creating timestamped entities in your app, and you want to send them in a batch to your API. Your API
|
|
165
|
-
knows the current time when it gets the request, but not the creation time of each entity.
|
|
166
|
-
|
|
167
|
-

|
|
168
|
-
|
|
169
|
-
And querying your core API for the current time for each entity is a waste of resources -- that's why you're batching
|
|
170
|
-
the operation in the first place.
|
|
171
|
-
|
|
172
|
-

|
|
173
|
-
|
|
174
|
-
So you can use this service to get the current time whenever you need it, and use that as the creation time for each
|
|
175
|
-
entity.
|
|
176
|
-
|
|
177
|
-

|
|
178
|
-
|
|
179
|
-
---
|
|
180
|
-
|
|
181
|
-
## 📜 License
|
|
182
|
-
|
|
183
|
-
Have at it.
|
|
184
|
-
|
|
185
|
-
This project uses the Unlicense. See the [UNLICENSE](https://gitlab.com/beavuck-services/time/-/blob/main/UNLICENSE?ref_type=heads) file for details.
|
package/Dockerfile
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
FROM node:jod-alpine
|
|
2
|
-
|
|
3
|
-
WORKDIR /usr/src/app
|
|
4
|
-
|
|
5
|
-
COPY package*.json tsconfig.json tsoa.json ./
|
|
6
|
-
COPY src ./src
|
|
7
|
-
COPY .env ./.env
|
|
8
|
-
|
|
9
|
-
# building the app
|
|
10
|
-
RUN npm install --ignore-scripts -g npm@latest \
|
|
11
|
-
&& npm ci --ignore-scripts \
|
|
12
|
-
&& npm run build \
|
|
13
|
-
# managing user permissions
|
|
14
|
-
&& apk add --no-cache shadow \
|
|
15
|
-
&& groupadd -r appgroup \
|
|
16
|
-
&& useradd -r -g appgroup appuser \
|
|
17
|
-
&& chown -R appuser:appgroup /usr/src/app \
|
|
18
|
-
# making the image smaller by removing npm
|
|
19
|
-
&& npm uninstall -g npm
|
|
20
|
-
|
|
21
|
-
USER appuser
|
|
22
|
-
|
|
23
|
-
EXPOSE 3000
|
|
24
|
-
|
|
25
|
-
CMD ["node", "build/server.js"]
|
package/HELP.md
DELETED
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
# Beavuck Time
|
|
2
|
-
|
|
3
|
-
## Usage
|
|
4
|
-
|
|
5
|
-
### Set up (outside a container)
|
|
6
|
-
|
|
7
|
-
Install the dependencies, and run the service with:
|
|
8
|
-
|
|
9
|
-
```shell
|
|
10
|
-
npm install
|
|
11
|
-
npm run go
|
|
12
|
-
```
|
|
13
|
-
|
|
14
|
-
### Managing environment variables
|
|
15
|
-
|
|
16
|
-
Environment variables are encrypted. Check out https://dotenvx.com/docs/quickstart to manage them if needed
|
|
17
|
-
|
|
18
|
-
### Using the service
|
|
19
|
-
|
|
20
|
-
When you run:
|
|
21
|
-
|
|
22
|
-
```shell
|
|
23
|
-
curl --location 'http://localhost:3000/now' \
|
|
24
|
-
--header 'Origin: http://localhost:8477'
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
you should expect an answer such as:
|
|
28
|
-
|
|
29
|
-
```json
|
|
30
|
-
{
|
|
31
|
-
"now": "2024-06-14T18:25:46.835Z"
|
|
32
|
-
}
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
### Testing
|
|
36
|
-
|
|
37
|
-
#### Node tests
|
|
38
|
-
|
|
39
|
-
To run the tests, you can use:
|
|
40
|
-
|
|
41
|
-
```shell
|
|
42
|
-
npm test
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
#### API client tests
|
|
46
|
-
|
|
47
|
-
Check out the `run-integration-tests` script in the `package.json` file. If you run the API then run the tests, you
|
|
48
|
-
should see the tests pass.
|
|
49
|
-
|
|
50
|
-
We write those tests using [Bruno](https://docs.usebruno.com/), because Postman is whack and bloaty and impossible to
|
|
51
|
-
version cleanly within a repo.
|
|
52
|
-
|
|
53
|
-
Bruno is pretty neat -- it's made by devs for devs and it has a lot to offer right now, as well as a lot of promise.
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
vars {
|
|
2
|
-
BASE_URL: http://localhost:3000
|
|
3
|
-
TRUSTED_ORIGIN: http://localhost:8477
|
|
4
|
-
NON_TRUSTED_ORIGIN: http://localhost:9632
|
|
5
|
-
NON_RECOGNIZED_REFERRER: http://localhost:9236
|
|
6
|
-
RFC_3339_REGEX: ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z$
|
|
7
|
-
CORS_REGEX: [cC][oO][rR][sS]
|
|
8
|
-
}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
meta {
|
|
2
|
-
name: nok_no_origin
|
|
3
|
-
type: http
|
|
4
|
-
seq: 2
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
get {
|
|
8
|
-
url: {{BASE_URL}}/now
|
|
9
|
-
body: none
|
|
10
|
-
auth: inherit
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
assert {
|
|
14
|
-
res.status: eq 403
|
|
15
|
-
res.body: isDefined
|
|
16
|
-
res.body.message: isDefined
|
|
17
|
-
res.body.message: matches {{CORS_REGEX}}
|
|
18
|
-
res.responseTime: lt 200
|
|
19
|
-
}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
meta {
|
|
2
|
-
name: nok_non_recognized_referrer
|
|
3
|
-
type: http
|
|
4
|
-
seq: 4
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
get {
|
|
8
|
-
url: {{BASE_URL}}/now
|
|
9
|
-
body: none
|
|
10
|
-
auth: inherit
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
headers {
|
|
14
|
-
Referrer: {{NON_RECOGNIZED_REFERRER}}
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
assert {
|
|
18
|
-
res.status: eq 403
|
|
19
|
-
res.body: isDefined
|
|
20
|
-
res.body.message: isDefined
|
|
21
|
-
res.body.message: matches {{CORS_REGEX}}
|
|
22
|
-
res.responseTime: lt 200
|
|
23
|
-
}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
meta {
|
|
2
|
-
name: nok_non_trusted_origin
|
|
3
|
-
type: http
|
|
4
|
-
seq: 1
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
get {
|
|
8
|
-
url: {{BASE_URL}}/now
|
|
9
|
-
body: none
|
|
10
|
-
auth: inherit
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
headers {
|
|
14
|
-
Origin: {{NON_TRUSTED_ORIGIN}}
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
assert {
|
|
18
|
-
res.status: eq 403
|
|
19
|
-
res.body: isDefined
|
|
20
|
-
res.body.message: isDefined
|
|
21
|
-
res.body.message: matches {{CORS_REGEX}}
|
|
22
|
-
res.responseTime: lt 200
|
|
23
|
-
}
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
meta {
|
|
2
|
-
name: nok_non_truted_origin_nor_referrer
|
|
3
|
-
type: http
|
|
4
|
-
seq: 3
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
get {
|
|
8
|
-
url: {{BASE_URL}}/now
|
|
9
|
-
body: none
|
|
10
|
-
auth: inherit
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
headers {
|
|
14
|
-
Origin: {{NON_TRUSTED_ORIGIN}}
|
|
15
|
-
Referrer: {{NON_RECOGNIZED_REFERRER}}
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
assert {
|
|
19
|
-
res.status: eq 403
|
|
20
|
-
res.body: isDefined
|
|
21
|
-
res.body.message: isDefined
|
|
22
|
-
res.body.message: matches {{CORS_REGEX}}
|
|
23
|
-
res.responseTime: lt 200
|
|
24
|
-
}
|