@prosopo/client-example-server 2.7.14 → 2.7.16
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/CHANGELOG.md +30 -0
- package/dist/app.js +59 -56
- package/dist/bundle/prosopo_client_example_server.app.bundle.js +13158 -12864
- package/dist/cjs/app.cjs +73 -0
- package/dist/cjs/controllers/auth.cjs +155 -0
- package/dist/cjs/models/user.cjs +23 -0
- package/dist/cjs/routes/routes.cjs +23 -0
- package/dist/cjs/utils/connection.cjs +15 -0
- package/dist/cjs/utils/database.cjs +10 -0
- package/dist/controllers/auth.js +131 -129
- package/dist/models/user.js +21 -20
- package/dist/routes/routes.js +20 -13
- package/dist/utils/connection.js +12 -11
- package/dist/utils/database.js +8 -6
- package/package.json +22 -13
- package/vite.cjs.config.ts +23 -0
- package/vite.esm.config.ts +24 -0
- package/dist/app.d.ts +0 -2
- package/dist/app.d.ts.map +0 -1
- package/dist/app.js.map +0 -1
- package/dist/controllers/auth.d.ts +0 -8
- package/dist/controllers/auth.d.ts.map +0 -1
- package/dist/controllers/auth.js.map +0 -1
- package/dist/models/user.d.ts +0 -19
- package/dist/models/user.d.ts.map +0 -1
- package/dist/models/user.js.map +0 -1
- package/dist/routes/routes.d.ts +0 -6
- package/dist/routes/routes.d.ts.map +0 -1
- package/dist/routes/routes.js.map +0 -1
- package/dist/utils/connection.d.ts +0 -4
- package/dist/utils/connection.d.ts.map +0 -1
- package/dist/utils/connection.js.map +0 -1
- package/dist/utils/database.d.ts +0 -3
- package/dist/utils/database.d.ts.map +0 -1
- package/dist/utils/database.js.map +0 -1
package/dist/cjs/app.cjs
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const path = require("node:path");
|
|
4
|
+
const common = require("@prosopo/common");
|
|
5
|
+
const dotenv = require("@prosopo/dotenv");
|
|
6
|
+
const server = require("@prosopo/server");
|
|
7
|
+
const util = require("@prosopo/util");
|
|
8
|
+
const cors = require("cors");
|
|
9
|
+
const express = require("express");
|
|
10
|
+
const routes = require("./routes/routes.cjs");
|
|
11
|
+
const connection = require("./utils/connection.cjs");
|
|
12
|
+
const database = require("./utils/database.cjs");
|
|
13
|
+
dotenv.loadEnv();
|
|
14
|
+
function getEnvFile(filename = ".env", filepath = "./") {
|
|
15
|
+
const env = process.env.NODE_ENV || "development";
|
|
16
|
+
return path.join(filepath, `${filename}.${env}`);
|
|
17
|
+
}
|
|
18
|
+
var ProsopoVerificationType = /* @__PURE__ */ ((ProsopoVerificationType2) => {
|
|
19
|
+
ProsopoVerificationType2["api"] = "api";
|
|
20
|
+
ProsopoVerificationType2["local"] = "local";
|
|
21
|
+
return ProsopoVerificationType2;
|
|
22
|
+
})(ProsopoVerificationType || {});
|
|
23
|
+
const logger = common.getLogger("info", module);
|
|
24
|
+
async function main() {
|
|
25
|
+
dotenv.loadEnv();
|
|
26
|
+
const apiPrefix = process.env.NODE_ENV && process.env.NODE_ENV === "production" ? "" : `${process.env.NODE_ENV}-`;
|
|
27
|
+
const verifyEndpoint = process.env.PROSOPO_VERIFY_ENDPOINT || `https://${apiPrefix}api.prosopo.io/siteverify`;
|
|
28
|
+
const verifyType = Object.keys(
|
|
29
|
+
ProsopoVerificationType
|
|
30
|
+
).includes(process.env.PROSOPO_VERIFICATION_TYPE) ? process.env.PROSOPO_VERIFICATION_TYPE : "api";
|
|
31
|
+
const app = express();
|
|
32
|
+
app.use(cors({ origin: true, credentials: true }));
|
|
33
|
+
app.use(express.urlencoded({ extended: true }));
|
|
34
|
+
app.use(express.json());
|
|
35
|
+
app.use((_, res, next) => {
|
|
36
|
+
res.setHeader("Access-Control-Allow-Origin", "*");
|
|
37
|
+
res.setHeader(
|
|
38
|
+
"Access-Control-Allow-Methods",
|
|
39
|
+
"GET, POST, PUT, PATCH, DELETE"
|
|
40
|
+
);
|
|
41
|
+
res.setHeader(
|
|
42
|
+
"Access-Control-Allow-Headers",
|
|
43
|
+
"Origin, Content-Type, X-Auth-Token, Authorization"
|
|
44
|
+
);
|
|
45
|
+
next();
|
|
46
|
+
});
|
|
47
|
+
app.options("/*", (_, res) => {
|
|
48
|
+
res.sendStatus(200);
|
|
49
|
+
});
|
|
50
|
+
const uri = await database.memoryServerSetup();
|
|
51
|
+
logger.info(() => ({ msg: "mongo uri", data: { uri } }));
|
|
52
|
+
const mongoose = connection(uri);
|
|
53
|
+
if (!process.env.PROSOPO_SITE_PRIVATE_KEY) {
|
|
54
|
+
const mnemonicError = new common.ProsopoEnvError("GENERAL.MNEMONIC_UNDEFINED", {
|
|
55
|
+
context: { missingParams: ["PROSOPO_SITE_PRIVATE_KEY"] },
|
|
56
|
+
logger
|
|
57
|
+
});
|
|
58
|
+
logger.error(() => ({ err: mnemonicError }));
|
|
59
|
+
}
|
|
60
|
+
const config = server.getServerConfig();
|
|
61
|
+
logger.info(() => ({ msg: "Config", data: { config } }));
|
|
62
|
+
app.use(routes(mongoose, config, verifyEndpoint, verifyType));
|
|
63
|
+
app.listen(
|
|
64
|
+
config.serverUrl ? Number.parseInt(util.at(config.serverUrl.split(":"), 2)) : 9228
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
main().then(() => {
|
|
68
|
+
logger.info(() => ({ msg: "Server started" }));
|
|
69
|
+
}).catch((err) => {
|
|
70
|
+
logger.error(() => ({ err }));
|
|
71
|
+
process.exit();
|
|
72
|
+
});
|
|
73
|
+
exports.getEnvFile = getEnvFile;
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const blake2b = require("@noble/hashes/blake2b");
|
|
4
|
+
const util = require("@polkadot/util");
|
|
5
|
+
const utilCrypto = require("@polkadot/util-crypto");
|
|
6
|
+
const common = require("@prosopo/common");
|
|
7
|
+
const keyring = require("@prosopo/keyring");
|
|
8
|
+
const server = require("@prosopo/server");
|
|
9
|
+
const types = require("@prosopo/types");
|
|
10
|
+
const util$1 = require("@prosopo/util");
|
|
11
|
+
const jwt = require("jsonwebtoken");
|
|
12
|
+
const zod = require("zod");
|
|
13
|
+
const SubscribeBodySpec = types.ProcaptchaResponse.merge(
|
|
14
|
+
zod.z.object({
|
|
15
|
+
email: zod.z.string().email(),
|
|
16
|
+
password: zod.z.string()
|
|
17
|
+
})
|
|
18
|
+
);
|
|
19
|
+
function hashPassword(password) {
|
|
20
|
+
return util.u8aToHex(blake2b.blake2b(password));
|
|
21
|
+
}
|
|
22
|
+
const verify = async (prosopoServer, verifyType, verifyEndpoint, token, secret) => {
|
|
23
|
+
if (verifyType === "api") {
|
|
24
|
+
console.log("Verifying using the API endpoint", verifyEndpoint);
|
|
25
|
+
const response = await fetch(verifyEndpoint, {
|
|
26
|
+
method: "POST",
|
|
27
|
+
body: JSON.stringify({
|
|
28
|
+
[types.ApiParams.token]: token,
|
|
29
|
+
[types.ApiParams.secret]: secret
|
|
30
|
+
})
|
|
31
|
+
});
|
|
32
|
+
const verifiedResponse = await response.json();
|
|
33
|
+
console.log(verifiedResponse);
|
|
34
|
+
return verifiedResponse.verified;
|
|
35
|
+
}
|
|
36
|
+
const verified = await prosopoServer.isVerified(token);
|
|
37
|
+
console.log(verified);
|
|
38
|
+
return verified;
|
|
39
|
+
};
|
|
40
|
+
const signup = async (mongoose, config, verifyEndpoint, verifyType, req, res, next) => {
|
|
41
|
+
try {
|
|
42
|
+
const User = mongoose.model("User");
|
|
43
|
+
const dbUser = await User.findOne({
|
|
44
|
+
email: { $eq: req.body.email }
|
|
45
|
+
});
|
|
46
|
+
const payload = SubscribeBodySpec.parse(req.body);
|
|
47
|
+
const pair = await keyring.getPair(config.account.secret);
|
|
48
|
+
const prosopoServer = new server.ProsopoServer(config, pair);
|
|
49
|
+
if (dbUser) {
|
|
50
|
+
return res.status(409).json({ message: "email already exists" });
|
|
51
|
+
}
|
|
52
|
+
const token = payload[types.ApiParams.procaptchaResponse];
|
|
53
|
+
if (!config.account.secret) {
|
|
54
|
+
throw new common.ProsopoEnvError("GENERAL.MNEMONIC_UNDEFINED", {
|
|
55
|
+
context: { missingParams: ["PROSOPO_SITE_PRIVATE_KEY"] }
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
const verified = await verify(
|
|
59
|
+
prosopoServer,
|
|
60
|
+
verifyType,
|
|
61
|
+
verifyEndpoint,
|
|
62
|
+
token,
|
|
63
|
+
config.account.secret
|
|
64
|
+
);
|
|
65
|
+
if (verified) {
|
|
66
|
+
const salt = utilCrypto.randomAsHex(32);
|
|
67
|
+
const passwordHash = hashPassword(`${req.body.password}${salt}`);
|
|
68
|
+
if (passwordHash) {
|
|
69
|
+
return User.create({
|
|
70
|
+
email: req.body.email,
|
|
71
|
+
name: req.body.name,
|
|
72
|
+
password: passwordHash,
|
|
73
|
+
salt
|
|
74
|
+
}).then(() => {
|
|
75
|
+
res.status(200).json({ message: "user created" });
|
|
76
|
+
}).catch((err) => {
|
|
77
|
+
console.log(err);
|
|
78
|
+
res.status(502).json({ message: "error while creating the user" });
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
} else {
|
|
82
|
+
res.status(401).json({ message: "user has not completed a captcha", verified });
|
|
83
|
+
}
|
|
84
|
+
} catch (err) {
|
|
85
|
+
console.error("error", err);
|
|
86
|
+
res.status(500).json({ message: err.message || "internal server error" });
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
const login = async (mongoose, config, verifyEndpoint, verifyType, req, res) => {
|
|
90
|
+
const User = mongoose.model("User");
|
|
91
|
+
const pair = await keyring.getPair(config.account.secret);
|
|
92
|
+
const prosopoServer = new server.ProsopoServer(config, pair);
|
|
93
|
+
await User.findOne({
|
|
94
|
+
email: { $eq: req.body.email }
|
|
95
|
+
}).then(async (dbUser) => {
|
|
96
|
+
if (dbUser) {
|
|
97
|
+
console.log(req.body);
|
|
98
|
+
const payload = SubscribeBodySpec.parse(req.body);
|
|
99
|
+
const token = payload[types.ApiParams.procaptchaResponse];
|
|
100
|
+
if (!config.account.secret) {
|
|
101
|
+
throw new common.ProsopoEnvError("GENERAL.MNEMONIC_UNDEFINED", {
|
|
102
|
+
context: { missingParams: ["PROSOPO_SITE_PRIVATE_KEY"] }
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
const verified = await verify(
|
|
106
|
+
prosopoServer,
|
|
107
|
+
verifyType,
|
|
108
|
+
verifyEndpoint,
|
|
109
|
+
token,
|
|
110
|
+
config.account.secret
|
|
111
|
+
);
|
|
112
|
+
console.log("verified", verified);
|
|
113
|
+
if (verified) {
|
|
114
|
+
const passwordHash = hashPassword(
|
|
115
|
+
`${req.body.password}${dbUser.salt}`
|
|
116
|
+
);
|
|
117
|
+
if (passwordHash !== dbUser.password) {
|
|
118
|
+
return res.status(401).json({ message: "invalid credentials" });
|
|
119
|
+
}
|
|
120
|
+
const token2 = jwt.sign({ email: req.body.email }, "secret", {
|
|
121
|
+
expiresIn: "1h"
|
|
122
|
+
});
|
|
123
|
+
return res.status(200).json({ message: "user logged in", token: token2 });
|
|
124
|
+
}
|
|
125
|
+
return res.status(401).json({ message: "user has not completed a captcha", verified });
|
|
126
|
+
}
|
|
127
|
+
return res.status(404).json({ message: "user not found" });
|
|
128
|
+
}).catch((err) => {
|
|
129
|
+
console.error("error", err);
|
|
130
|
+
res.status(500).json({ message: err.message || "internal server error" });
|
|
131
|
+
});
|
|
132
|
+
};
|
|
133
|
+
const isAuth = (req, res) => {
|
|
134
|
+
const authHeader = req.get("Authorization") || "";
|
|
135
|
+
if (!authHeader) {
|
|
136
|
+
res.status(401).json({ message: "not authenticated" });
|
|
137
|
+
}
|
|
138
|
+
const token = util$1.at(authHeader.split(" "), 1);
|
|
139
|
+
let decodedToken = "";
|
|
140
|
+
try {
|
|
141
|
+
decodedToken = jwt.verify(token, "secret");
|
|
142
|
+
} catch (err) {
|
|
143
|
+
res.status(500).json({
|
|
144
|
+
message: err.message || "could not decode the token"
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
if (!decodedToken) {
|
|
148
|
+
res.status(401).json({ message: "unauthorized" });
|
|
149
|
+
} else {
|
|
150
|
+
res.status(200).json({ message: "here is your resource" });
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
exports.isAuth = isAuth;
|
|
154
|
+
exports.login = login;
|
|
155
|
+
exports.signup = signup;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
const mongoose = require("mongoose");
|
|
3
|
+
const UserSchema = new mongoose.Schema({
|
|
4
|
+
email: {
|
|
5
|
+
type: mongoose.SchemaTypes.String,
|
|
6
|
+
required: true
|
|
7
|
+
},
|
|
8
|
+
name: {
|
|
9
|
+
type: mongoose.SchemaTypes.String
|
|
10
|
+
},
|
|
11
|
+
password: {
|
|
12
|
+
type: mongoose.SchemaTypes.String,
|
|
13
|
+
required: true
|
|
14
|
+
},
|
|
15
|
+
id: {
|
|
16
|
+
type: mongoose.SchemaTypes.Number
|
|
17
|
+
},
|
|
18
|
+
salt: {
|
|
19
|
+
type: mongoose.SchemaTypes.String,
|
|
20
|
+
required: true
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
module.exports = UserSchema;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
const express = require("express");
|
|
3
|
+
const auth = require("../controllers/auth.cjs");
|
|
4
|
+
const router = express.Router();
|
|
5
|
+
function getRoutes(mongoose, config, verifyEndpoint, verifyType) {
|
|
6
|
+
router.post(
|
|
7
|
+
"/login",
|
|
8
|
+
auth.login.bind(null, mongoose, config, verifyEndpoint, verifyType)
|
|
9
|
+
);
|
|
10
|
+
router.post(
|
|
11
|
+
"/signup",
|
|
12
|
+
auth.signup.bind(null, mongoose, config, verifyEndpoint, verifyType)
|
|
13
|
+
);
|
|
14
|
+
router.get("/private", auth.isAuth);
|
|
15
|
+
router.get("/public", (req, res) => {
|
|
16
|
+
res.status(200).json({ message: "here is your public resource" });
|
|
17
|
+
});
|
|
18
|
+
router.use("/", (req, res) => {
|
|
19
|
+
res.status(404).json({ error: "page not found" });
|
|
20
|
+
});
|
|
21
|
+
return router;
|
|
22
|
+
}
|
|
23
|
+
module.exports = getRoutes;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
const autoIncrement = require("@typegoose/auto-increment");
|
|
3
|
+
const mongoose = require("mongoose");
|
|
4
|
+
const user = require("../models/user.cjs");
|
|
5
|
+
function connectionFactory(uri) {
|
|
6
|
+
const conn = mongoose.createConnection(uri);
|
|
7
|
+
if (!conn.models.user) {
|
|
8
|
+
user.plugin(autoIncrement.AutoIncrementID, {
|
|
9
|
+
field: "id"
|
|
10
|
+
});
|
|
11
|
+
conn.model("User", user);
|
|
12
|
+
}
|
|
13
|
+
return conn;
|
|
14
|
+
}
|
|
15
|
+
module.exports = connectionFactory;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
|
|
3
|
+
const mongodbMemoryServer = require("mongodb-memory-server");
|
|
4
|
+
async function memoryServerSetup() {
|
|
5
|
+
const mongod = mongodbMemoryServer.MongoMemoryServer.create();
|
|
6
|
+
const memoryServer = await mongod;
|
|
7
|
+
return memoryServer.getUri();
|
|
8
|
+
}
|
|
9
|
+
exports.default = memoryServerSetup;
|
|
10
|
+
exports.memoryServerSetup = memoryServerSetup;
|
package/dist/controllers/auth.js
CHANGED
|
@@ -4,150 +4,152 @@ import { randomAsHex } from "@polkadot/util-crypto";
|
|
|
4
4
|
import { ProsopoEnvError } from "@prosopo/common";
|
|
5
5
|
import { getPair } from "@prosopo/keyring";
|
|
6
6
|
import { ProsopoServer } from "@prosopo/server";
|
|
7
|
-
import {
|
|
8
|
-
import { ProcaptchaResponse } from "@prosopo/types";
|
|
7
|
+
import { ProcaptchaResponse, ApiParams } from "@prosopo/types";
|
|
9
8
|
import { at } from "@prosopo/util";
|
|
10
9
|
import jwt from "jsonwebtoken";
|
|
11
10
|
import { z } from "zod";
|
|
12
|
-
const SubscribeBodySpec = ProcaptchaResponse.merge(
|
|
11
|
+
const SubscribeBodySpec = ProcaptchaResponse.merge(
|
|
12
|
+
z.object({
|
|
13
13
|
email: z.string().email(),
|
|
14
|
-
password: z.string()
|
|
15
|
-
})
|
|
14
|
+
password: z.string()
|
|
15
|
+
})
|
|
16
|
+
);
|
|
16
17
|
function hashPassword(password) {
|
|
17
|
-
|
|
18
|
+
return u8aToHex(blake2b(password));
|
|
18
19
|
}
|
|
19
20
|
const verify = async (prosopoServer, verifyType, verifyEndpoint, token, secret) => {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
21
|
+
if (verifyType === "api") {
|
|
22
|
+
console.log("Verifying using the API endpoint", verifyEndpoint);
|
|
23
|
+
const response = await fetch(verifyEndpoint, {
|
|
24
|
+
method: "POST",
|
|
25
|
+
body: JSON.stringify({
|
|
26
|
+
[ApiParams.token]: token,
|
|
27
|
+
[ApiParams.secret]: secret
|
|
28
|
+
})
|
|
29
|
+
});
|
|
30
|
+
const verifiedResponse = await response.json();
|
|
31
|
+
console.log(verifiedResponse);
|
|
32
|
+
return verifiedResponse.verified;
|
|
33
|
+
}
|
|
34
|
+
const verified = await prosopoServer.isVerified(token);
|
|
35
|
+
console.log(verified);
|
|
36
|
+
return verified;
|
|
36
37
|
};
|
|
37
38
|
const signup = async (mongoose, config, verifyEndpoint, verifyType, req, res, next) => {
|
|
38
|
-
|
|
39
|
-
const User = mongoose.model("User");
|
|
40
|
-
const dbUser = await User.findOne({
|
|
41
|
-
email: { $eq: req.body.email },
|
|
42
|
-
});
|
|
43
|
-
const payload = SubscribeBodySpec.parse(req.body);
|
|
44
|
-
const pair = await getPair(config.account.secret);
|
|
45
|
-
const prosopoServer = new ProsopoServer(config, pair);
|
|
46
|
-
if (dbUser) {
|
|
47
|
-
return res.status(409).json({ message: "email already exists" });
|
|
48
|
-
}
|
|
49
|
-
const token = payload[ApiParams.procaptchaResponse];
|
|
50
|
-
if (!config.account.secret) {
|
|
51
|
-
throw new ProsopoEnvError("GENERAL.MNEMONIC_UNDEFINED", {
|
|
52
|
-
context: { missingParams: ["PROSOPO_SITE_PRIVATE_KEY"] },
|
|
53
|
-
});
|
|
54
|
-
}
|
|
55
|
-
const verified = await verify(prosopoServer, verifyType, verifyEndpoint, token, config.account.secret);
|
|
56
|
-
if (verified) {
|
|
57
|
-
const salt = randomAsHex(32);
|
|
58
|
-
const passwordHash = hashPassword(`${req.body.password}${salt}`);
|
|
59
|
-
if (passwordHash) {
|
|
60
|
-
return User.create({
|
|
61
|
-
email: req.body.email,
|
|
62
|
-
name: req.body.name,
|
|
63
|
-
password: passwordHash,
|
|
64
|
-
salt: salt,
|
|
65
|
-
})
|
|
66
|
-
.then(() => {
|
|
67
|
-
res.status(200).json({ message: "user created" });
|
|
68
|
-
})
|
|
69
|
-
.catch((err) => {
|
|
70
|
-
console.log(err);
|
|
71
|
-
res.status(502).json({ message: "error while creating the user" });
|
|
72
|
-
});
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
else {
|
|
76
|
-
res
|
|
77
|
-
.status(401)
|
|
78
|
-
.json({ message: "user has not completed a captcha", verified });
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
catch (err) {
|
|
82
|
-
console.error("error", err);
|
|
83
|
-
res
|
|
84
|
-
.status(500)
|
|
85
|
-
.json({ message: err.message || "internal server error" });
|
|
86
|
-
}
|
|
87
|
-
};
|
|
88
|
-
const login = async (mongoose, config, verifyEndpoint, verifyType, req, res) => {
|
|
39
|
+
try {
|
|
89
40
|
const User = mongoose.model("User");
|
|
41
|
+
const dbUser = await User.findOne({
|
|
42
|
+
email: { $eq: req.body.email }
|
|
43
|
+
});
|
|
44
|
+
const payload = SubscribeBodySpec.parse(req.body);
|
|
90
45
|
const pair = await getPair(config.account.secret);
|
|
91
46
|
const prosopoServer = new ProsopoServer(config, pair);
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
})
|
|
95
|
-
.then(async (dbUser) => {
|
|
96
|
-
if (dbUser) {
|
|
97
|
-
console.log(req.body);
|
|
98
|
-
const payload = SubscribeBodySpec.parse(req.body);
|
|
99
|
-
const token = payload[ApiParams.procaptchaResponse];
|
|
100
|
-
if (!config.account.secret) {
|
|
101
|
-
throw new ProsopoEnvError("GENERAL.MNEMONIC_UNDEFINED", {
|
|
102
|
-
context: { missingParams: ["PROSOPO_SITE_PRIVATE_KEY"] },
|
|
103
|
-
});
|
|
104
|
-
}
|
|
105
|
-
const verified = await verify(prosopoServer, verifyType, verifyEndpoint, token, config.account.secret);
|
|
106
|
-
console.log("verified", verified);
|
|
107
|
-
if (verified) {
|
|
108
|
-
const passwordHash = hashPassword(`${req.body.password}${dbUser.salt}`);
|
|
109
|
-
if (passwordHash !== dbUser.password) {
|
|
110
|
-
return res.status(401).json({ message: "invalid credentials" });
|
|
111
|
-
}
|
|
112
|
-
const token = jwt.sign({ email: req.body.email }, "secret", {
|
|
113
|
-
expiresIn: "1h",
|
|
114
|
-
});
|
|
115
|
-
return res
|
|
116
|
-
.status(200)
|
|
117
|
-
.json({ message: "user logged in", token: token });
|
|
118
|
-
}
|
|
119
|
-
return res
|
|
120
|
-
.status(401)
|
|
121
|
-
.json({ message: "user has not completed a captcha", verified });
|
|
122
|
-
}
|
|
123
|
-
return res.status(404).json({ message: "user not found" });
|
|
124
|
-
})
|
|
125
|
-
.catch((err) => {
|
|
126
|
-
console.error("error", err);
|
|
127
|
-
res.status(500).json({ message: err.message || "internal server error" });
|
|
128
|
-
});
|
|
129
|
-
};
|
|
130
|
-
const isAuth = (req, res) => {
|
|
131
|
-
const authHeader = req.get("Authorization") || "";
|
|
132
|
-
if (!authHeader) {
|
|
133
|
-
res.status(401).json({ message: "not authenticated" });
|
|
47
|
+
if (dbUser) {
|
|
48
|
+
return res.status(409).json({ message: "email already exists" });
|
|
134
49
|
}
|
|
135
|
-
const token =
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
50
|
+
const token = payload[ApiParams.procaptchaResponse];
|
|
51
|
+
if (!config.account.secret) {
|
|
52
|
+
throw new ProsopoEnvError("GENERAL.MNEMONIC_UNDEFINED", {
|
|
53
|
+
context: { missingParams: ["PROSOPO_SITE_PRIVATE_KEY"] }
|
|
54
|
+
});
|
|
139
55
|
}
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
56
|
+
const verified = await verify(
|
|
57
|
+
prosopoServer,
|
|
58
|
+
verifyType,
|
|
59
|
+
verifyEndpoint,
|
|
60
|
+
token,
|
|
61
|
+
config.account.secret
|
|
62
|
+
);
|
|
63
|
+
if (verified) {
|
|
64
|
+
const salt = randomAsHex(32);
|
|
65
|
+
const passwordHash = hashPassword(`${req.body.password}${salt}`);
|
|
66
|
+
if (passwordHash) {
|
|
67
|
+
return User.create({
|
|
68
|
+
email: req.body.email,
|
|
69
|
+
name: req.body.name,
|
|
70
|
+
password: passwordHash,
|
|
71
|
+
salt
|
|
72
|
+
}).then(() => {
|
|
73
|
+
res.status(200).json({ message: "user created" });
|
|
74
|
+
}).catch((err) => {
|
|
75
|
+
console.log(err);
|
|
76
|
+
res.status(502).json({ message: "error while creating the user" });
|
|
143
77
|
});
|
|
78
|
+
}
|
|
79
|
+
} else {
|
|
80
|
+
res.status(401).json({ message: "user has not completed a captcha", verified });
|
|
144
81
|
}
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
|
|
82
|
+
} catch (err) {
|
|
83
|
+
console.error("error", err);
|
|
84
|
+
res.status(500).json({ message: err.message || "internal server error" });
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
const login = async (mongoose, config, verifyEndpoint, verifyType, req, res) => {
|
|
88
|
+
const User = mongoose.model("User");
|
|
89
|
+
const pair = await getPair(config.account.secret);
|
|
90
|
+
const prosopoServer = new ProsopoServer(config, pair);
|
|
91
|
+
await User.findOne({
|
|
92
|
+
email: { $eq: req.body.email }
|
|
93
|
+
}).then(async (dbUser) => {
|
|
94
|
+
if (dbUser) {
|
|
95
|
+
console.log(req.body);
|
|
96
|
+
const payload = SubscribeBodySpec.parse(req.body);
|
|
97
|
+
const token = payload[ApiParams.procaptchaResponse];
|
|
98
|
+
if (!config.account.secret) {
|
|
99
|
+
throw new ProsopoEnvError("GENERAL.MNEMONIC_UNDEFINED", {
|
|
100
|
+
context: { missingParams: ["PROSOPO_SITE_PRIVATE_KEY"] }
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
const verified = await verify(
|
|
104
|
+
prosopoServer,
|
|
105
|
+
verifyType,
|
|
106
|
+
verifyEndpoint,
|
|
107
|
+
token,
|
|
108
|
+
config.account.secret
|
|
109
|
+
);
|
|
110
|
+
console.log("verified", verified);
|
|
111
|
+
if (verified) {
|
|
112
|
+
const passwordHash = hashPassword(
|
|
113
|
+
`${req.body.password}${dbUser.salt}`
|
|
114
|
+
);
|
|
115
|
+
if (passwordHash !== dbUser.password) {
|
|
116
|
+
return res.status(401).json({ message: "invalid credentials" });
|
|
117
|
+
}
|
|
118
|
+
const token2 = jwt.sign({ email: req.body.email }, "secret", {
|
|
119
|
+
expiresIn: "1h"
|
|
120
|
+
});
|
|
121
|
+
return res.status(200).json({ message: "user logged in", token: token2 });
|
|
122
|
+
}
|
|
123
|
+
return res.status(401).json({ message: "user has not completed a captcha", verified });
|
|
150
124
|
}
|
|
125
|
+
return res.status(404).json({ message: "user not found" });
|
|
126
|
+
}).catch((err) => {
|
|
127
|
+
console.error("error", err);
|
|
128
|
+
res.status(500).json({ message: err.message || "internal server error" });
|
|
129
|
+
});
|
|
130
|
+
};
|
|
131
|
+
const isAuth = (req, res) => {
|
|
132
|
+
const authHeader = req.get("Authorization") || "";
|
|
133
|
+
if (!authHeader) {
|
|
134
|
+
res.status(401).json({ message: "not authenticated" });
|
|
135
|
+
}
|
|
136
|
+
const token = at(authHeader.split(" "), 1);
|
|
137
|
+
let decodedToken = "";
|
|
138
|
+
try {
|
|
139
|
+
decodedToken = jwt.verify(token, "secret");
|
|
140
|
+
} catch (err) {
|
|
141
|
+
res.status(500).json({
|
|
142
|
+
message: err.message || "could not decode the token"
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
if (!decodedToken) {
|
|
146
|
+
res.status(401).json({ message: "unauthorized" });
|
|
147
|
+
} else {
|
|
148
|
+
res.status(200).json({ message: "here is your resource" });
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
export {
|
|
152
|
+
isAuth,
|
|
153
|
+
login,
|
|
154
|
+
signup
|
|
151
155
|
};
|
|
152
|
-
export { signup, login, isAuth };
|
|
153
|
-
//# sourceMappingURL=auth.js.map
|
package/dist/models/user.js
CHANGED
|
@@ -1,23 +1,24 @@
|
|
|
1
1
|
import mongoose, { Schema } from "mongoose";
|
|
2
2
|
const UserSchema = new Schema({
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
3
|
+
email: {
|
|
4
|
+
type: mongoose.SchemaTypes.String,
|
|
5
|
+
required: true
|
|
6
|
+
},
|
|
7
|
+
name: {
|
|
8
|
+
type: mongoose.SchemaTypes.String
|
|
9
|
+
},
|
|
10
|
+
password: {
|
|
11
|
+
type: mongoose.SchemaTypes.String,
|
|
12
|
+
required: true
|
|
13
|
+
},
|
|
14
|
+
id: {
|
|
15
|
+
type: mongoose.SchemaTypes.Number
|
|
16
|
+
},
|
|
17
|
+
salt: {
|
|
18
|
+
type: mongoose.SchemaTypes.String,
|
|
19
|
+
required: true
|
|
20
|
+
}
|
|
21
21
|
});
|
|
22
|
-
export
|
|
23
|
-
|
|
22
|
+
export {
|
|
23
|
+
UserSchema as default
|
|
24
|
+
};
|
package/dist/routes/routes.js
CHANGED
|
@@ -1,17 +1,24 @@
|
|
|
1
1
|
import express from "express";
|
|
2
|
-
import {
|
|
2
|
+
import { login, signup, isAuth } from "../controllers/auth.js";
|
|
3
3
|
const router = express.Router();
|
|
4
4
|
function getRoutes(mongoose, config, verifyEndpoint, verifyType) {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
5
|
+
router.post(
|
|
6
|
+
"/login",
|
|
7
|
+
login.bind(null, mongoose, config, verifyEndpoint, verifyType)
|
|
8
|
+
);
|
|
9
|
+
router.post(
|
|
10
|
+
"/signup",
|
|
11
|
+
signup.bind(null, mongoose, config, verifyEndpoint, verifyType)
|
|
12
|
+
);
|
|
13
|
+
router.get("/private", isAuth);
|
|
14
|
+
router.get("/public", (req, res) => {
|
|
15
|
+
res.status(200).json({ message: "here is your public resource" });
|
|
16
|
+
});
|
|
17
|
+
router.use("/", (req, res) => {
|
|
18
|
+
res.status(404).json({ error: "page not found" });
|
|
19
|
+
});
|
|
20
|
+
return router;
|
|
15
21
|
}
|
|
16
|
-
export
|
|
17
|
-
|
|
22
|
+
export {
|
|
23
|
+
getRoutes as default
|
|
24
|
+
};
|