enforces an allowed host

This commit is contained in:
@wwwjim 2020-10-29 11:39:40 -07:00
parent 8889a82560
commit 3ba1f518c9
13 changed files with 51 additions and 120 deletions

View File

@ -72,6 +72,7 @@ LOCAL_PASSWORD_ROUNDS=14
TEXTILE_HUB_KEY=XXX TEXTILE_HUB_KEY=XXX
TEXTILE_HUB_SECRET=XXX TEXTILE_HUB_SECRET=XXX
JWT_SECRET=XXX JWT_SECRET=XXX
ALLOWED_HOST=localhost:1337
PUBSUB_SECRET=pKLO4lbzdMrhAFKwPo9bnmq03bxQrtu3 PUBSUB_SECRET=pKLO4lbzdMrhAFKwPo9bnmq03bxQrtu3
RESOURCE_URI_UPLOAD=http://localhost:4242 RESOURCE_URI_UPLOAD=http://localhost:4242
RESOURCE_URI_STORAGE_UPLOAD=http://localhost:4242 RESOURCE_URI_STORAGE_UPLOAD=http://localhost:4242

View File

@ -17,6 +17,7 @@ export const POSTGRES_HOSTNAME = process.env.POSTGRES_HOSTNAME;
export const POSTGRES_DATABASE = process.env.POSTGRES_DATABASE; export const POSTGRES_DATABASE = process.env.POSTGRES_DATABASE;
export const JWT_SECRET = process.env.JWT_SECRET; export const JWT_SECRET = process.env.JWT_SECRET;
export const PUBSUB_SECRET = process.env.PUBSUB_SECRET; export const PUBSUB_SECRET = process.env.PUBSUB_SECRET;
export const ALLOWED_HOST = process.env.ALLOWED_HOST;
export const LOCAL_PASSWORD_ROUNDS_MANUAL = process.env.LOCAL_PASSWORD_ROUNDS_MANUAL; export const LOCAL_PASSWORD_ROUNDS_MANUAL = process.env.LOCAL_PASSWORD_ROUNDS_MANUAL;
export const LOCAL_PASSWORD_ROUNDS = process.env.LOCAL_PASSWORD_ROUNDS; export const LOCAL_PASSWORD_ROUNDS = process.env.LOCAL_PASSWORD_ROUNDS;
export const LOCAL_PASSWORD_SECRET = `$2b$${LOCAL_PASSWORD_ROUNDS}$${ export const LOCAL_PASSWORD_SECRET = `$2b$${LOCAL_PASSWORD_ROUNDS}$${

View File

@ -4,20 +4,14 @@ import * as Utilities from "~/node_common/utilities";
export default async (req, res) => { export default async (req, res) => {
const id = Utilities.getIdFromCookie(req); const id = Utilities.getIdFromCookie(req);
if (!id) { if (!id) {
return res return res.status(500).send({ decorator: "SERVER_HYDRATE_FAILURE", error: true });
.status(500)
.send({ decorator: "SERVER_HYDRATE_FAILURE", error: true });
} }
const data = await ViewerManager.getById({ id }); const data = await ViewerManager.getById({ id });
if (!data) { if (!data) {
return res return res.status(500).send({ decorator: "SERVER_VIEWER_DATA_ERROR", error: true, data: null });
.status(500)
.send({ decorator: "SERVER_VIEWER_DATA_ERROR", error: true, data: null });
} }
return res return res.status(200).send({ decorator: "SERVER_HYDRATE", success: true, data });
.status(200)
.send({ decorator: "SERVER_HYDRATE", success: true, data });
}; };

View File

@ -6,6 +6,10 @@ import * as Strings from "~/common/strings";
import JWT from "jsonwebtoken"; import JWT from "jsonwebtoken";
export default async (req, res) => { export default async (req, res) => {
if (!Strings.isEmpty(Environment.ALLOWED_HOST) && req.headers.host !== Environment.ALLOWED_HOST) {
return res.status(403).send({ decorator: "YOU_ARE_NOT_ALLOWED", error: true });
}
// NOTE(jim): We don't need to validate here. // NOTE(jim): We don't need to validate here.
if (Strings.isEmpty(req.body.data.username)) { if (Strings.isEmpty(req.body.data.username)) {
return res.status(500).send({ decorator: "SERVER_SIGN_IN", error: true }); return res.status(500).send({ decorator: "SERVER_SIGN_IN", error: true });
@ -25,26 +29,17 @@ export default async (req, res) => {
} }
if (!user) { if (!user) {
return res return res.status(404).send({ decorator: "SERVER_SIGN_IN_USER_NOT_FOUND", error: true });
.status(404)
.send({ decorator: "SERVER_SIGN_IN_USER_NOT_FOUND", error: true });
} }
if (user.error) { if (user.error) {
return res return res.status(500).send({ decorator: "SERVER_SIGN_IN_ERROR", error: true });
.status(500)
.send({ decorator: "SERVER_SIGN_IN_ERROR", error: true });
} }
const hash = await Utilities.encryptPassword( const hash = await Utilities.encryptPassword(req.body.data.password, user.salt);
req.body.data.password,
user.salt
);
if (hash !== user.password) { if (hash !== user.password) {
return res return res.status(403).send({ decorator: "SERVER_SIGN_IN_AUTH", error: true });
.status(403)
.send({ decorator: "SERVER_SIGN_IN_AUTH", error: true });
} }
const authorization = Utilities.parseAuthHeader(req.headers.authorization); const authorization = Utilities.parseAuthHeader(req.headers.authorization);
@ -59,12 +54,7 @@ export default async (req, res) => {
} }
} }
const token = JWT.sign( const token = JWT.sign({ id: user.id, username: user.username }, Environment.JWT_SECRET);
{ id: user.id, username: user.username },
Environment.JWT_SECRET
);
return res return res.status(200).send({ decorator: "SERVER_SIGN_IN", success: true, token });
.status(200)
.send({ decorator: "SERVER_SIGN_IN", success: true, token });
}; };

View File

@ -8,9 +8,7 @@ const SLATE_LIMIT = 50;
export default async (req, res) => { export default async (req, res) => {
const id = Utilities.getIdFromCookie(req); const id = Utilities.getIdFromCookie(req);
if (!id) { if (!id) {
return res return res.status(500).send({ decorator: "SERVER_FIND_USER_CREATE_SLATE", error: true });
.status(500)
.send({ decorator: "SERVER_FIND_USER_CREATE_SLATE", error: true });
} }
const user = await Data.getUserById({ const user = await Data.getUserById({
@ -39,16 +37,12 @@ export default async (req, res) => {
}); });
if (found) { if (found) {
return res return res.status(500).send({ decorator: "SERVER_EXISTING_SLATE", error: true });
.status(500)
.send({ decorator: "SERVER_EXISTING_SLATE", error: true });
} }
const slates = await Data.getSlatesByUserId({ userId: id }); const slates = await Data.getSlatesByUserId({ userId: id });
if (slates.length >= SLATE_LIMIT) { if (slates.length >= SLATE_LIMIT) {
return res return res.status(500).send({ decorator: "SERVER_SLATE_LIMIT", error: true });
.status(500)
.send({ decorator: "SERVER_SLATE_LIMIT", error: true });
} }
const slate = await Data.createSlate({ const slate = await Data.createSlate({
@ -63,15 +57,11 @@ export default async (req, res) => {
}); });
if (!slate) { if (!slate) {
return res return res.status(500).send({ decorator: "SERVER_CREATE_SLATE", error: true });
.status(500)
.send({ decorator: "SERVER_CREATE_SLATE", error: true });
} }
if (slate.error) { if (slate.error) {
return res return res.status(500).send({ decorator: "SERVER_CREATE_SLATE", error: true });
.status(500)
.send({ decorator: "SERVER_CREATE_SLATE", error: true });
} }
const userProfileURL = `https://slate.host/${user.username}`; const userProfileURL = `https://slate.host/${user.username}`;

View File

@ -5,9 +5,7 @@ import * as Strings from "~/common/strings";
export default async (req, res) => { export default async (req, res) => {
const id = Utilities.getIdFromCookie(req); const id = Utilities.getIdFromCookie(req);
if (!id) { if (!id) {
return res return res.status(500).send({ decorator: "SERVER_DELETE_SLATE", error: true });
.status(500)
.send({ decorator: "SERVER_DELETE_SLATE", error: true });
} }
const user = await Data.getUserById({ const user = await Data.getUserById({
@ -31,32 +29,22 @@ export default async (req, res) => {
const slate = await Data.getSlateById({ id: req.body.data.id }); const slate = await Data.getSlateById({ id: req.body.data.id });
if (!slate) { if (!slate) {
return res return res.status(404).send({ decorator: "SERVER_DELETE_SLATE_SLATE_NOT_FOUND", error: true });
.status(404)
.send({ decorator: "SERVER_DELETE_SLATE_SLATE_NOT_FOUND", error: true });
} }
if (slate.error) { if (slate.error) {
return res return res.status(500).send({ decorator: "SERVER_DELETE_SLATE_SLATE_NOT_FOUND", error: true });
.status(500)
.send({ decorator: "SERVER_DELETE_SLATE_SLATE_NOT_FOUND", error: true });
} }
const deleteResponse = await Data.deleteSlateById({ id: slate.id }); const deleteResponse = await Data.deleteSlateById({ id: slate.id });
if (!deleteResponse) { if (!deleteResponse) {
return res return res.status(404).send({ decorator: "SERVER_DELETE_SLATE", error: true });
.status(404)
.send({ decorator: "SERVER_DELETE_SLATE", error: true });
} }
if (deleteResponse.error) { if (deleteResponse.error) {
return res return res.status(500).send({ decorator: "SERVER_DELETE_SLATE", error: true });
.status(500)
.send({ decorator: "SERVER_DELETE_SLATE", error: true });
} }
return res return res.status(200).send({ decorator: "SERVER_DELETE_SLATE", error: false });
.status(200)
.send({ decorator: "SERVER_DELETE_SLATE", error: false });
}; };

View File

@ -1,4 +1,3 @@
import * as Environment from "~/node_common/environment";
import * as Data from "~/node_common/data"; import * as Data from "~/node_common/data";
import * as Utilities from "~/node_common/utilities"; import * as Utilities from "~/node_common/utilities";
import * as Serializers from "~/node_common/serializers"; import * as Serializers from "~/node_common/serializers";
@ -15,15 +14,11 @@ export default async (req, res) => {
}); });
if (!user) { if (!user) {
return res return res.status(404).send({ decorator: "SERVER_SUBSCRIBE_USER_NOT_FOUND", error: true });
.status(404)
.send({ decorator: "SERVER_SUBSCRIBE_USER_NOT_FOUND", error: true });
} }
if (user.error) { if (user.error) {
return res return res.status(500).send({ decorator: "SERVER_SUBSCRIBE_USER_NOT_FOUND", error: true });
.status(500)
.send({ decorator: "SERVER_SUBSCRIBE_USER_NOT_FOUND", error: true });
} }
if (!req.body.data || (!req.body.data.userId && !req.body.data.slateId)) { if (!req.body.data || (!req.body.data.userId && !req.body.data.slateId)) {
@ -100,20 +95,14 @@ export default async (req, res) => {
}); });
if (!unsubscribeResponse) { if (!unsubscribeResponse) {
return res return res.status(404).send({ decorator: "SERVER_UNSUBSCRIBE_NOT_FOUND", error: true });
.status(404)
.send({ decorator: "SERVER_UNSUBSCRIBE_NOT_FOUND", error: true });
} }
if (unsubscribeResponse.error) { if (unsubscribeResponse.error) {
return res return res.status(500).send({ decorator: "SERVER_UNSUBSCRIBE_ERROR", error: true });
.status(500)
.send({ decorator: "SERVER_UNSUBSCRIBE_ERROR", error: true });
} }
return res return res.status(200).send({ decorator: "SERVER_UNSUBSCRIBE", data: unsubscribeResponse });
.status(200)
.send({ decorator: "SERVER_UNSUBSCRIBE", data: unsubscribeResponse });
} }
const subscribeResponse = await Data.createSubscription({ const subscribeResponse = await Data.createSubscription({
@ -123,15 +112,11 @@ export default async (req, res) => {
}); });
if (!subscribeResponse) { if (!subscribeResponse) {
return res return res.status(404).send({ decorator: "SERVER_SUBSCRIBE_NOT_FOUND", error: true });
.status(404)
.send({ decorator: "SERVER_SUBSCRIBE_NOT_FOUND", error: true });
} }
if (subscribeResponse.error) { if (subscribeResponse.error) {
return res return res.status(500).send({ decorator: "SERVER_SUBSCRIBE_ERROR", error: true });
.status(500)
.send({ decorator: "SERVER_SUBSCRIBE_ERROR", error: true });
} }
return res.status(200).send({ return res.status(200).send({

View File

@ -1,4 +1,3 @@
import * as Environment from "~/node_common/environment";
import * as Data from "~/node_common/data"; import * as Data from "~/node_common/data";
import * as Utilities from "~/node_common/utilities"; import * as Utilities from "~/node_common/utilities";
import * as Serializers from "~/node_common/serializers"; import * as Serializers from "~/node_common/serializers";
@ -15,15 +14,11 @@ export default async (req, res) => {
}); });
if (!user) { if (!user) {
return res return res.status(404).send({ decorator: "SERVER_SUPPORT_USER_NOT_FOUND", error: true });
.status(404)
.send({ decorator: "SERVER_SUPPORT_USER_NOT_FOUND", error: true });
} }
if (user.error) { if (user.error) {
return res return res.status(500).send({ decorator: "SERVER_SUPPORT_USER_NOT_FOUND", error: true });
.status(500)
.send({ decorator: "SERVER_SUPPORT_USER_NOT_FOUND", error: true });
} }
if (!req.body.data) { if (!req.body.data) {

View File

@ -5,12 +5,17 @@ import * as SlateManager from "~/node_common/managers/slate";
import * as LibraryManager from "~/node_common/managers/library"; import * as LibraryManager from "~/node_common/managers/library";
import * as Social from "~/node_common/social"; import * as Social from "~/node_common/social";
import * as Validations from "~/common/validations"; import * as Validations from "~/common/validations";
import * as Common from "~/common/strings";
import BCrypt from "bcrypt"; import BCrypt from "bcrypt";
import { PrivateKey } from "@textile/hub"; import { PrivateKey } from "@textile/hub";
export default async (req, res) => { export default async (req, res) => {
if (!Strings.isEmpty(Environment.ALLOWED_HOST) && req.headers.host !== Environment.ALLOWED_HOST) {
return res.status(403).send({ decorator: "YOU_ARE_NOT_ALLOWED", error: true });
}
const existing = await Data.getUserByUsername({ const existing = await Data.getUserByUsername({
username: req.body.data.username, username: req.body.data.username,
}); });

View File

@ -15,9 +15,7 @@ const TEXTILE_KEY_INFO = {
export default async (req, res) => { export default async (req, res) => {
const id = Utilities.getIdFromCookie(req); const id = Utilities.getIdFromCookie(req);
if (!id) { if (!id) {
return res return res.status(500).send({ decorator: "SERVER_USER_DELETE", error: true });
.status(500)
.send({ decorator: "SERVER_USER_DELETE", error: true });
} }
const user = await Data.getUserById({ const user = await Data.getUserById({
@ -25,15 +23,11 @@ export default async (req, res) => {
}); });
if (!user) { if (!user) {
return res return res.status(404).send({ decorator: "SERVER_USER_DELETE_USER_NOT_FOUND", error: true });
.status(404)
.send({ decorator: "SERVER_USER_DELETE_USER_NOT_FOUND", error: true });
} }
if (user.error) { if (user.error) {
return res return res.status(500).send({ decorator: "SERVER_USER_DELETE_USER_NOT_FOUND", error: true });
.status(500)
.send({ decorator: "SERVER_USER_DELETE_USER_NOT_FOUND", error: true });
} }
await Data.deleteAPIKeysForUserId({ userId: user.id }); await Data.deleteAPIKeysForUserId({ userId: user.id });
@ -65,9 +59,7 @@ export default async (req, res) => {
}); });
if (!deleted) { if (!deleted) {
return res return res.status(500).send({ decorator: "SERVER_USER_DELETE", error: true });
.status(500)
.send({ decorator: "SERVER_USER_DELETE", error: true });
} }
return res.status(200).send({ decorator: "SERVER_USER_DELETE", deleted }); return res.status(200).send({ decorator: "SERVER_USER_DELETE", deleted });

View File

@ -6,9 +6,7 @@ import * as Validations from "~/common/validations";
export default async (req, res) => { export default async (req, res) => {
const id = Utilities.getIdFromCookie(req); const id = Utilities.getIdFromCookie(req);
if (!id) { if (!id) {
return res return res.status(500).send({ decorator: "SERVER_TRUST_DELETE", error: true });
.status(500)
.send({ decorator: "SERVER_TRUST_DELETE", error: true });
} }
const user = await Data.getUserById({ const user = await Data.getUserById({
@ -40,7 +38,5 @@ export default async (req, res) => {
id: req.body.data.id, id: req.body.data.id,
}); });
return res return res.status(200).send({ decorator: "SERVER_TRUST_UPDATE", data: response });
.status(200)
.send({ decorator: "SERVER_TRUST_UPDATE", data: response });
}; };

View File

@ -7,9 +7,7 @@ import * as Validations from "~/common/validations";
export default async (req, res) => { export default async (req, res) => {
const id = Utilities.getIdFromCookie(req); const id = Utilities.getIdFromCookie(req);
if (!id) { if (!id) {
return res return res.status(500).send({ decorator: "SERVER_TRUST_UPDATE", error: true });
.status(500)
.send({ decorator: "SERVER_TRUST_UPDATE", error: true });
} }
const user = await Data.getUserById({ const user = await Data.getUserById({

View File

@ -87,11 +87,9 @@ export default async (req, res) => {
// NOTE(jim) // NOTE(jim)
// Treat trust as an API method you can call again to remove a trusted relationship. // Treat trust as an API method you can call again to remove a trusted relationship.
if (existingResponse) { if (existingResponse) {
const deleteRelationshipResponse = await Data.deleteTrustedRelationshipById( const deleteRelationshipResponse = await Data.deleteTrustedRelationshipById({
{
id: existingResponse.id, id: existingResponse.id,
} });
);
if (!deleteRelationshipResponse) { if (!deleteRelationshipResponse) {
return res.status(404).send({ return res.status(404).send({
@ -126,9 +124,7 @@ export default async (req, res) => {
} }
if (trustResponse.error) { if (trustResponse.error) {
return res return res.status(500).send({ decorator: "SERVER_TRUSTED_RELATIONSHIP_ERROR", error: true });
.status(500)
.send({ decorator: "SERVER_TRUSTED_RELATIONSHIP_ERROR", error: true });
} }
return res.status(200).send({ return res.status(200).send({