- Nodejs 16.13
- Python 3.6 or later
Install required packages.
# npm install
Make /local/cert
directory in the project root, and store the three keys below in /local/cert
.
- public key (named as
public-key.pem
) - private key (named as
private-key.pem
) - certificate (named as
server-cert.pem
)
# mkdir ./local
# mkdir ./local/cert
# cd ./local/cert
# openssl genrsa 2048 > private-key.pem
# openssl rsa -in private-key.pem -pubout -out public-key.pem
# openssl req -new -key private-key.pem > server-csr.pem
# openssl x509 -req -in server-csr.pem -signkey private-key.pem -out server-cert.pem -days 3650
# cd ../..
Initialize a user list, and set root password.
# npm run init:user
Build server and client codes.
# npm run build
Start server.
# npm start
Access with your browser or issue HTTP requests.
- request
- method:
GET
- path:
/api/v1/public-key
- method:
- response
- data:
{ msg: <string>, key: <string> }
- data:
- request
- method:
POST
- header:
{ Content-Type: application/x-www-form-urlencoded }
- path:
/api/v1/login
- body:
{ username: <string>, password: <string>, encrypted?: <boolean> }
- method:
- response
- data:
{ msg: <string>, token: <string> }
- data:
Note: The password must be encrypted by the public key, and be encoded by Base64.
- request
- method:
GET
- header:
{ X-Access-Token: <string> }
- path:
/api/v1/token
- method:
- response
- data:
{ msg: <string>, iss: <string>, sub: <string>, iat: <string>, exp: <string>, IssueAt: <string>, ExpirationTime: <string> }
- data:
- request
- method:
GET
- header:
{ X-Access-Token: <string> }
- path:
/api/v1/whatsnew
- method:
- response
- data:
<string>
- data:
- request
- method:
GET
- header:
{ X-Access-Token: <string> }
- path:
/api/v1/log/:domain
- method:
- response
- data:
{ msg: <string> }
- data:
- request
- method:
GET
- header:
{ X-Access-Token: <string> }
- path:
/api/v1/log/:domain/projects
- method:
- response
- data:
{ msg: <string>, projects: [{ name: <string>, description: <string> }] }
- data:
- request
- method:
POST
- header:
{ X-Access-Token: <string>, Content-Type: application/x-www-form-urlencoded }
- path:
/api/v1/log/:domain/projects
- body:
{ name: <string>, description?: <string> }
- method:
- response
- header:
{ Location: <URL> }
- data:
{ msg: <string> }
- header:
- request
- method:
GET
- header:
{ X-Access-Token: <string> }
- path:
/api/v1/log/:domain/projects/:projectName
- method:
- response
- data:
{ msg: <string>, status:<string>, description: <string> }
- data:
- request
- method:
PUT
- header:
{ X-Access-Token: <string>, Content-Type: application/x-www-form-urlencoded }
- path:
/api/v1/log/:domain/projects/:projectName
- body:
{ status?: "open" | "close", description?: <string> }
- method:
- response
- data:
{ msg: <string> }
- data:
- request
- method:
DELETE
- header:
{ X-Access-Token: <string> }
- path:
/api/v1/log/:domain/projects/:projectName
- method:
- response
- data:
{ msg: <string> }
- data:
- request
- method:
GET
- header:
{ X-Access-Token: <string> }
- path:
/api/v1/log/:domain/projects/:projectName/bundles
- method:
- response
- data:
{ msg: <string>, projects: [{ id: <number>, name: <string>, description: <string>, available: <boolean>, preserved: <boolean> }] }
- data:
- request
- method:
POST
- header:
{ X-Access-Token: <string>, Content-Type: multipart/form-data }
- path:
/api/v1/log/:domain/projects/:projectName/bundles
- body:
{ bundle: <object>, description?: <string> }
- method:
- response
- header:
{ Location: <URL> }
- data:
{ msg: <string>, id: <number>, name: <string> }
- header:
- request
- method:
GET
- header:
{ X-Access-Token: <string> }
- path:
/api/v1/log/:domain/projects/:projectName/bundles/:bundleId
- method:
- response
- data:
{ msg: <string>, name:<string>, description: <string>, date: <string>, preserved: <boolean> }
- data:
- request
- method:
PUT
- header:
{ X-Access-Token: <string>, Content-Type: application/x-www-form-urlencoded }
- path:
/api/v1/log/:domain/projects/:projectName/bundles/:bundleId
- body:
{ description: <string> }
- method:
- response
- data:
{ msg: <string> }
- data:
- request
- method:
DELETE
- header:
{ X-Access-Token: <string> }
- path:
/api/v1/log/:domain/projects/:projectName/bundles/:bundleId
- method:
- response
- data:
{ msg: <string> }
- data:
- request
- method:
GET
- header:
{ X-Access-Token: <string> }
- path:
/api/v1/log/:domain/projects/:projectName/bundles/:bundleId/files
- method:
- response
- data:
{ msg: <string>, files: <Node> }
- data:
Note: definition
<Node> := <File> | <Directory>
<File> := { name: <string>, file: true }
<Directory> := { name: <string>, file: false, children: [<Node>] }
- request
- method:
GET
- header:
{ X-Access-Token: <string> }
- path:
/api/v1/log/:domain/projects/:projectName/bundles/:bundleId/files/:filepath
- method:
- response
- data:
{ msg: <string>, content: <string>, size: <number>, mtime: <string> }
- data:
- request
- method:
GET
- header:
{ X-Access-Token: <string> }
- path:
/api/v1/log/:domain/projects/:projectName/bundles/:bundleId/files/:filepath
- query:
{ mode: plain }
- method:
- response
- data:
{ msg: <string>, content: <string>, size: <number>, mtime: <string> }
- data:
- request
- method:
GET
- header:
{ X-Access-Token: <string> }
- path:
/api/v1/log/:domain/projects/:projectName/bundles/:bundleId/files/:filepath
- query:
{ mode: json, gzip: true | false }
- method:
- response
- data:
{ msg: <string>, content: <JSON Table>, size: <number>, mtime: <string>, compression: <string> }
- data:
Note: definition
<Table Format> := { title: <string>, labels: [{ "name": <string>, type: <string> }], hasHeader: <boolean>, hasIndex: <boolean>, contentKey: <string> }
<Table Data> := [{ [label: <string>]: <string> }]
<JSON Table> := { format: <Table Format>, data: <Table Data> }
- request
- method:
GET
- header:
{ X-Access-Token: <string> }
- path:
/api/v1/log/:domain/projects/:projectName/bundles/:bundleId/files/:filepath
- query:
{ mode: download, gzip: true | false }
- method:
- response
- data:
<object>
- data: