@rpcbase/server 0.71.0 → 0.74.0

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/bin.js CHANGED
@@ -6,12 +6,14 @@ require("dotenv").config({path: path.join(__dirname, "./.env")})
6
6
  const yargs = require("yargs/yargs")
7
7
  const {hideBin} = require("yargs/helpers")
8
8
 
9
+ const pack = require("./package.json")
9
10
  const start_server_infrastructure = require("./cli/start_server_infrastructure")
10
11
  const build_server = require("./cli/build_server")
11
12
  const run_agent = require("./cli/run_agent")
12
13
 
13
14
  let is_command = false
14
15
 
16
+ console.log("PACKVER", pack.version)
15
17
 
16
18
  const args = yargs(hideBin(process.argv))
17
19
  .command("start", "runs server/infrastructure", () => {}, (args) => {
@@ -22,7 +24,7 @@ const args = yargs(hideBin(process.argv))
22
24
  is_command = true
23
25
  run_agent()
24
26
  })
25
- .command("build", "build server", () => {}, (args) => {
27
+ .command("build", "Build the server package", () => {}, (args) => {
26
28
  is_command = true
27
29
  build_server()
28
30
  })
package/cli/run_native.js CHANGED
@@ -11,6 +11,10 @@ const mkdirp = require("mkdirp")
11
11
  // TODO: verify mongod and redis-sever and elasticsearch executables are present
12
12
  // and have the right version
13
13
 
14
+ const NO_PRINT_LIST = [
15
+ // "database",
16
+ ]
17
+
14
18
  // load env
15
19
  const get_env = () => {
16
20
  const env_path = path.join(process.cwd(), "./.env")
@@ -19,17 +23,22 @@ const get_env = () => {
19
23
  return env
20
24
  }
21
25
 
22
- const init_processes = () => {
26
+ const init_processes = (args) => {
23
27
  const env = get_env()
24
28
 
25
29
  const infrastructure_conf_dir = path.join(__dirname, "../infrastructure")
26
30
 
27
- // create data dirs
31
+ // db storage
28
32
  const db_path = path.join(process.cwd(), "../infrastructure/data/database/db/")
29
- const db_logs_path = path.join(process.cwd(), "../infrastructure/data/database/log/")
30
33
 
34
+ // db log file
35
+ const db_logs_path = path.join(process.cwd(), "../infrastructure/data/database/log/logs.txt")
36
+
37
+ // session-store + worker-queue
31
38
  const session_store_dir = path.join(process.cwd(), "../infrastructure/data/session-store/data")
39
+ const session_store_logs_path = path.join(process.cwd(), "../infrastructure/data/session-store/log/logs.txt")
32
40
  const worker_queue_dir = path.join(process.cwd(), "../infrastructure/data/worker-queue/data")
41
+ const worker_queue_logs_path = path.join(process.cwd(), "../infrastructure/data/worker-queue/log/logs.txt")
33
42
 
34
43
  // TODO: add a redis cache
35
44
  const processes = [
@@ -46,14 +55,16 @@ const init_processes = () => {
46
55
  {
47
56
  name: "database",
48
57
  dirs: [
49
- db_path, db_logs_path
58
+ db_path,
59
+ path.dirname(db_logs_path),
50
60
  ],
51
61
  cmd: ["mongod", [
52
62
  "--quiet",
53
63
  "--dbpath", db_path,
54
64
  "--port", env.DATABASE_PORT,
55
65
  // "--bind_ip_all",
56
- // "--logpath", "/var/log/logs.txt",
66
+ // if in verbose mode, print to stdout, else write to file
67
+ ...(args.verbose ? [] : ["--logpath", db_logs_path]),
57
68
  "--replSet", "rs0"
58
69
  ]]
59
70
  },
@@ -62,11 +73,13 @@ const init_processes = () => {
62
73
  name: "session-store",
63
74
  dirs: [
64
75
  session_store_dir,
76
+ path.dirname(session_store_logs_path),
65
77
  ],
66
78
  cmd: ["redis-server", [
67
79
  path.join(infrastructure_conf_dir, "./redis/redis.conf"),
68
80
  "--dir", session_store_dir,
69
81
  "--port", env.SESSION_STORE_PORT,
82
+ ...(args.verbose ? [] : ["--logfile", session_store_logs_path]),
70
83
  ]]
71
84
  },
72
85
  // worker-queue
@@ -74,11 +87,13 @@ const init_processes = () => {
74
87
  name: "worker-queue",
75
88
  dirs: [
76
89
  worker_queue_dir,
90
+ path.dirname(worker_queue_logs_path),
77
91
  ],
78
92
  cmd: ["redis-server", [
79
93
  path.join(infrastructure_conf_dir, "./redis/redis.conf"),
80
94
  "--dir", worker_queue_dir,
81
95
  "--port", env.WORKER_QUEUE_PORT,
96
+ ...(args.verbose ? [] : ["--logfile", worker_queue_logs_path]),
82
97
  ]]
83
98
  },
84
99
  ]
@@ -118,22 +133,32 @@ const init_processes = () => {
118
133
 
119
134
  // TODO: run each native process from list
120
135
  // TODO: handle process close
121
- const run_native = (infrastructure_dir, proj_prefix) => {
122
- console.log("running in NATIVE mode")
136
+ const run_native = (infrastructure_dir, proj_prefix, args) => {
137
+ console.log(`running in ${colors.bold(colors.magenta("NATIVE"))} mode`)
123
138
 
124
- const processes = init_processes()
139
+ const processes = init_processes(args)
125
140
 
126
141
  const run_process = (item) => {
127
- // console.log("start process", item)
142
+ // console.log("run_native:run_process:item", item)
128
143
  const ps = spawn(item.cmd[0], item.cmd[1], {env: {...process.env, CONTAINER_MODE: "native"}})
129
144
 
130
- ps.stdout.on("data", (data) => {
131
- process.stdout.write(`${colors.green(item.name)}: ${data.toString()}`)
132
- })
145
+ // TODO: add flag to force print
146
+ if (!NO_PRINT_LIST.includes(item.name)) {
133
147
 
134
- ps.stderr.on("data", (data) => {
135
- process.stderr.write(`${item.name}: ${data.toString()}`)
136
- })
148
+ let prefix = ""
149
+ // avoid printing [server] server:
150
+ if (!args.verbose && item.name !== "server") {
151
+ prefix = `${colors.green(item.name)}: `
152
+ }
153
+
154
+ ps.stdout.on("data", (data) => {
155
+ process.stdout.write(`${prefix}${data.toString()}`)
156
+ })
157
+
158
+ ps.stderr.on("data", (data) => {
159
+ process.stderr.write(`${prefix}${data.toString()}`)
160
+ })
161
+ }
137
162
  }
138
163
 
139
164
  const spawned = processes.map(run_process)
@@ -19,9 +19,9 @@ const start_server = async(args) => {
19
19
  const proj_prefix = path.basename(proj_parent_dir)
20
20
 
21
21
  if (runtime === "docker") {
22
- run_docker(infrastructure_dir, proj_prefix)
22
+ run_docker(infrastructure_dir, proj_prefix, args)
23
23
  } else if (runtime === "native") {
24
- run_native(infrastructure_dir, proj_prefix)
24
+ run_native(infrastructure_dir, proj_prefix, args)
25
25
  } else {
26
26
  throw new Error("unknown runtime")
27
27
  }
package/crypto/index.js CHANGED
@@ -4,10 +4,12 @@ const crypto = require("crypto")
4
4
  const ALGORITHM = "aes-256-cbc"
5
5
  const {CRYPTO_SECRET} = process.env
6
6
 
7
- if (!CRYPTO_SECRET || CRYPTO_SECRET === "") {
7
+ if (!CRYPTO_SECRET || CRYPTO_SECRET.trim() === "") {
8
8
  throw new Error("CRYPTO_SECRET not found in env")
9
9
  }
10
10
 
11
+ // TODO: move to rb:std
12
+
11
13
  const key = crypto.createHash("sha256")
12
14
  .update(String(CRYPTO_SECRET))
13
15
  .digest()
package/database.js CHANGED
@@ -24,6 +24,7 @@ module.exports = async() => {
24
24
  })
25
25
 
26
26
  mongoose.connection.on("disconnected", (arg) => {
27
+ // TODO: add tracing
27
28
  console.log("Mongoose disconnected", arg)
28
29
  })
29
30
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rpcbase/server",
3
- "version": "0.71.0",
3
+ "version": "0.74.0",
4
4
  "license": "SSPL-1.0",
5
5
  "main": "./index.js",
6
6
  "bin": {
@@ -10,7 +10,8 @@
10
10
  "test": "echo \"Error: no test specified\" && exit 0"
11
11
  },
12
12
  "dependencies": {
13
- "@rpcbase/agent": "0.7.0",
13
+ "@rpcbase/agent": "0.9.0",
14
+ "@rpcbase/std": "0.2.0",
14
15
  "body-parser": "1.20.0",
15
16
  "connect-redis": "6.1.3",
16
17
  "cors": "2.8.5",
@@ -19,7 +20,7 @@
19
20
  "express": "4.18.1",
20
21
  "express-session": "1.17.3",
21
22
  "glob": "8.0.3",
22
- "mongoose": "6.3.6",
23
+ "mongoose": "6.4.0",
23
24
  "picocolors": "1.0.0",
24
25
  "postmark": "3.0.11",
25
26
  "redis": "4.1.0",
@@ -0,0 +1,44 @@
1
+ /* @flow */
2
+ const {compare_hash} = require("@rpcbase/std/crypto/hash")
3
+
4
+ const mongoose = require("../../mongoose")
5
+
6
+ const fail = () => ({
7
+ errors: {form: "Invalid email or password"}
8
+ })
9
+
10
+ const sign_in = async({email, password}, ctx) => {
11
+ const User = mongoose.model("User")
12
+
13
+ const {req} = ctx
14
+
15
+ // find the matching user
16
+ // TODO: document ctx param
17
+ // const user = await User.findOne({email}, null, {ctx})
18
+ const user = await User.findOne({email}, null)
19
+
20
+ // console.log("ICII2222", email, password, user)
21
+
22
+ if (!user) {
23
+ return fail()
24
+ }
25
+
26
+ const hashed_pass = user.password_hash
27
+
28
+ // TODO: fix broken bcrypt bins in docker
29
+ // const is_match = await bcrypt.compare(password, hashed_pass)
30
+ console.warn("warning: skipping bcrypt hash check")
31
+ const is_match = await compare_hash(password, hashed_pass)
32
+
33
+ if (is_match) {
34
+ req.session.user_id = user._id.toString()
35
+ await req.session.save()
36
+ return {
37
+ status: "ok"
38
+ }
39
+ } else {
40
+ return fail()
41
+ }
42
+ }
43
+
44
+ module.exports = sign_in
@@ -0,0 +1,57 @@
1
+ /* @flow */
2
+ const {hash_password} = require("@rpcbase/std/crypto/hash")
3
+
4
+ const mongoose = require("../../mongoose")
5
+
6
+ const sign_up = async({email, password}, ctx) => {
7
+ const User = mongoose.model("User")
8
+ const Invite = mongoose.model("Invite")
9
+
10
+ const {req} = ctx
11
+
12
+ // check if the user already exists
13
+ const existing_user = await User.findOne({email}, null, {ctx})
14
+
15
+ if (existing_user) {
16
+ return {
17
+ status: "error",
18
+ message: "User already exists"
19
+ }
20
+ }
21
+
22
+ // check if we have an invite for this user
23
+ const invite = await Invite.findOne({email}, null, {ctx})
24
+ if (invite && !invite.is_ready) {
25
+ console.log("found an invite, but not ready", email)
26
+ return {
27
+ status: "error",
28
+ message: "Your invite is still pending approval. Expect an email in the next weeks to activate your account."
29
+ }
30
+ } else if (!invite) {
31
+ console.log("no invite for signup email:", email)
32
+ return {
33
+ status: "error",
34
+ message: "No valid invite was found for this email"
35
+ }
36
+ }
37
+
38
+ const hash = await hash_password(password)
39
+
40
+ const user = new User({
41
+ email,
42
+ password_hash: hash
43
+ })
44
+
45
+ // sign the user in
46
+ req.session.user_id = user._id.toString()
47
+
48
+ await req.session.save()
49
+ await user.save({ctx})
50
+
51
+ return {
52
+ status: "ok",
53
+ user_id: user._id
54
+ }
55
+ }
56
+
57
+ module.exports = sign_up
@@ -3,6 +3,8 @@ const fs = require("fs")
3
3
  const path = require("path")
4
4
  const glob = require("glob")
5
5
 
6
+ const async_wrapper = require("../helpers/async_wrapper")
7
+
6
8
  const src_path = path.join(process.cwd(), "./src/")
7
9
  const build_dir = path.join(process.cwd(), "build/")
8
10
  const client_build_dir = path.join(build_dir, "./client")
@@ -10,11 +12,6 @@ const client_build_dir = path.join(build_dir, "./client")
10
12
 
11
13
  // TODO: add build time static assets compression
12
14
 
13
- const async_wrapper = fn => (req, res, next) => {
14
- Promise.resolve(fn(req, res, next))
15
- .catch(next)
16
- }
17
-
18
15
  const get_client_routes = () => {
19
16
  const client_files = glob.sync(path.join(client_build_dir, "./**/*"))
20
17
  const routes = client_files
@@ -4,16 +4,12 @@ const path = require("path")
4
4
  const glob = require("glob")
5
5
  const debug = require("debug")
6
6
 
7
+ const async_wrapper = require("../helpers/async_wrapper")
8
+
7
9
  const src_path = path.join(process.cwd(), "./src/")
8
10
  const build_dir = path.join(process.cwd(), "build/")
9
11
 
10
12
 
11
- const async_wrapper = fn => (req, res, next) => {
12
- Promise.resolve(fn(req, res, next))
13
- .catch(next)
14
- }
15
-
16
-
17
13
  const rpc_router = (app) => {
18
14
  const rpc_routes = glob.sync(path.join(build_dir, "./rpc/*"))
19
15