Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
dzencot committed Sep 18, 2024
1 parent ad69a2b commit c56cae9
Show file tree
Hide file tree
Showing 9 changed files with 114 additions and 92 deletions.
6 changes: 6 additions & 0 deletions __fixtures__/tokens.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[
{
"userId": "a788f3fc-0d47-4d55-b18b-09bae52dac7b",
"token": "r4AR4Fo0j29s9mFk4IUVA2rGTQmIrHWlioifaJLSQQYHbTXHxtSLFUVp8PANrRoAb7fgkSsbN7lt4a86pcJ07ivUpxBLyyCHaY4Pp9I7hRPphCHM7xpZ1om1"
}
]
30 changes: 20 additions & 10 deletions __fixtures__/users.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,60 +3,70 @@
"id": "a788f3fc-0d47-4d55-b18b-09bae52dac7b",
"email": "[email protected]",
"firstName": "Allison",
"lastName": "Bernier"
"lastName": "Bernier",
"password": "password"
},
{
"id": "11507784-a401-469d-a3a4-01917a5e4ef6",
"email": "[email protected]",
"firstName": "Mylene",
"lastName": "Schroeder-Quigley"
"lastName": "Schroeder-Quigley",
"password": "password"
},
{
"id": "398ce50c-3337-4833-bb0a-41fc70bf6bdd",
"email": "[email protected]",
"firstName": "Rossie",
"lastName": "Carter"
"lastName": "Carter",
"password": "password"
},
{
"id": "d678ab29-861f-421c-9c5b-c2b7645a2c97",
"email": "[email protected]",
"firstName": "Izabella",
"lastName": "Beier"
"lastName": "Beier",
"password": "password"
},
{
"id": "e3785264-ab22-46b8-b5ab-dbeb96499752",
"email": "[email protected]",
"firstName": "Delilah",
"lastName": "Littel"
"lastName": "Littel",
"password": "password"
},
{
"id": "2ef1d550-6394-444b-9e4b-225caa70c456",
"email": "[email protected]",
"firstName": "Jermain",
"lastName": "Gottlieb"
"lastName": "Gottlieb",
"password": "password"
},
{
"id": "dbcec1b4-5104-4fa8-a41b-40978189cb89",
"email": "[email protected]",
"firstName": "Rex",
"lastName": "Feeney"
"lastName": "Feeney",
"password": "password"
},
{
"id": "f59d75ae-9062-4d4a-bedc-4e3e6c0b7801",
"email": "[email protected]",
"firstName": "Bianka",
"lastName": "Bauch"
"lastName": "Bauch",
"password": "password"
},
{
"id": "eb6c9e76-24e8-432b-bb03-e831dc99ef7e",
"email": "[email protected]",
"firstName": "Darien",
"lastName": "Toy"
"lastName": "Toy",
"password": "password"
},
{
"id": "e7e3a2ce-18ca-4b51-b661-49f46202ed5c",
"email": "[email protected]",
"firstName": "Tatyana",
"lastName": "White"
"lastName": "White",
"password": "password"
}
]
7 changes: 6 additions & 1 deletion hooks.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
const hooks = require('hooks');

hooks.beforeAll(async (ransactions, done) => {
const utils = await import('./server/utils.mjs');
const state = utils.getInitData();
for (const transaction of ransactions) {
if (transaction.request.method !== 'DELETE') {
transaction.expected.headers['Content-Type'] = 'application/json; charset=utf-8';
}
transaction.request.headers['Authorization'] = 'Bearer some-token';
if (transaction.id === 'POST (200) /login') {
transaction.request.body = JSON.stringify({ email: state.users[0].email, password: state.users[0].password });
}
transaction.request.headers['Authorization'] = `Bearer ${state.tokens[0].token}`;
}

done();
Expand Down
70 changes: 65 additions & 5 deletions server/index.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,17 @@ const version = '1.0';
const openapiFilePath = path.join(dirname, '..', `tsp-output/@typespec/openapi3/openapi.${version}.yaml`);
const swaggerRoute = '/swagger';

const getUserByToken = (context, state) => {
const authHeader = context.request.headers['authorization'];
const token = authHeader.replace('Bearer ', '');
const authData = state.tokens.find((item) => item.token === token);
if (!authData) {
return null;
}
const user = state.users.find((item) => item.id === authData.userId);
return user;
};

const app = async (host, port) => {
const state = getInitData();

Expand All @@ -19,8 +30,17 @@ const app = async (host, port) => {
handlers: {
// Login handlers
AuthService_create: (c, req, res) => {
const {
email,
password,
} = c.request.body;
const user = state.users.find((u) => u.email === email);
if (!user || user.password !== password) {
return res.status(401)
.send({ code: 401, message: 'Wrong email or password' });
}
const token = getToken();
state.tokens.push(token);
state.tokens.push({ userId: user.id, token });
return res.status(200).send({ token });
},

Expand All @@ -30,12 +50,14 @@ const app = async (host, port) => {
firstName,
lastName,
email,
password,
} = c.request.body;
const user = {
id: getId(),
firstName,
lastName,
email,
password,
};

state.users.push(user);
Expand Down Expand Up @@ -67,6 +89,12 @@ const app = async (host, port) => {
if (index === -1) {
return res.status(404).send({ code: 404, message: 'Not found' });
}
const currentUser = getUserByToken(c, state);
if (currentUser.id !== id) {
return res
.status(403)
.send({ code: 403, message: 'Forbidden action' })
}
state.users[index] = {
...state.users[index],
...c.request.body,
Expand All @@ -75,6 +103,12 @@ const app = async (host, port) => {
},
UserService_delete: (c, req, res) => {
const { id } = c.request.params;
const currentUser = getUserByToken(c, state);
if (currentUser.id !== id) {
return res
.status(403)
.send({ code: 403, message: 'Forbidden action' })
}
const users = state.users.filter((item) => item.id !== id);
state.users = users;
return res.status(204).send();
Expand All @@ -83,13 +117,13 @@ const app = async (host, port) => {
// Posts handlers
PostService_create: (c, req, res) => {
const {
authorId,
title,
body,
} = c.request.body;
const currentUser = getUserByToken(c, state);
const post = {
id: getId(),
authorId,
authorId: currentUser.id,
title,
body,
};
Expand Down Expand Up @@ -118,6 +152,12 @@ const app = async (host, port) => {
if (index === -1) {
return res.status(404).send({ code: 404, message: 'Not found' });
}
const currentUser = getUserByToken(c, state);
if (currentUser.id !== state.posts[index].authorId) {
return res
.status(403)
.send({ code: 403, message: 'Forbidden action' })
}
state.posts[index] = {
...state.posts[index],
...c.request.body,
Expand All @@ -126,6 +166,13 @@ const app = async (host, port) => {
},
PostService_delete: (c, req, res) => {
const { id } = c.request.params;
const index = state.posts.findIndex((item) => item.id === id);
const currentUser = getUserByToken(c, state);
if (currentUser.id !== state.posts[index].authorId) {
return res
.status(403)
.send({ code: 403, message: 'Forbidden action' })
}
const posts = state.posts.filter((item) => item.id !== id);
state.posts = posts;
return res.status(204).send();
Expand All @@ -135,13 +182,13 @@ const app = async (host, port) => {
CommentService_create: (c, req, res) => {
const {
postId,
authorId,
body,
} = c.request.body;
const currentUser = getUserByToken(c, state);
const comment = {
id: getId(),
postId,
authorId,
authorId: currentUser.id,
body
};

Expand All @@ -164,6 +211,12 @@ const app = async (host, port) => {
if (index === -1) {
return res.status(404).send({ code: 404, message: 'Not found' });
}
const currentUser = getUserByToken(c, state);
if (currentUser.id !== state.comments[index].authorId) {
return res
.status(403)
.send({ code: 403, message: 'Forbidden action' })
}
state.comments[index] = {
...state.comments[index],
...c.request.body,
Expand All @@ -172,6 +225,13 @@ const app = async (host, port) => {
},
CommentService_delete: (c, req, res) => {
const { id } = c.request.params;
const index = state.comments.findIndex((item) => item.id === id);
const currentUser = getUserByToken(c, state);
if (currentUser.id !== state.comments[index].authorId) {
return res
.status(403)
.send({ code: 403, message: 'Forbidden action' })
}
const comments = state.comments.filter((item) => item.id !== id);
state.comments = comments;
return res.status(204).send();
Expand Down
73 changes: 10 additions & 63 deletions server/utils.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -3,83 +3,30 @@ import _ from 'lodash';
import users from '../__fixtures__/users.json' with { type: 'json' };
import posts from '../__fixtures__/posts.json' with { type: 'json' };
import comments from '../__fixtures__/comments.json' with { type: 'json' };
import tokens from '../__fixtures__/tokens.json' with { type: 'json' };

const listSize = 10;
const defaultLimit = 30;

const createUser = () => ({
id: faker.string.uuid(),
email: faker.internet.email(),
firstName: faker.person.firstName(),
lastName: faker.person.lastName(),
});

const createPost = (user) => ({
id: faker.string.uuid(),
authorId: user.id,
title: faker.lorem.words(),
body: faker.lorem.paragraphs(),
});

const createComment = (post) => ({
id: faker.string.uuid(),
authorId: post.authorId,
postId: post.id,
body: faker.lorem.paragraphs(),
});

export const getToken = () => faker.string.alphanumeric(120);

export const getInitData = () => {
// const users = [];

// for(let i = 1; i <= listSize; i++) {
// users.push(createUser());
// }

// const posts = users.map((user) => {
// const userPosts = [];
// for(let i = 1; i <= listSize; i++) {
// userPosts.push(createPost(user));
// }
// return userPosts;
// }).flat();

// const comments = posts.map((post) => {
// const postComments = [];
// for(let i = 1; i <= listSize; i++) {
// postComments.push(createComment(post));
// }
// return postComments;
// }).flat();

return {
users,
posts,
comments,
tokens: [],
};
};
export const getInitData = () => ({
users,
posts,
comments,
tokens,
});

export const prepareItem = (item, selectors = []) => {
if (selectors.length) {
return {
id: item.id,
..._.pick(item, selectors),
};
}
return item;
const data = selectors.length ? { id: item.id, ..._.pick(item, selectors)} : item;
return _.omit(data, 'password');
};

export const prepareListData = (name, state, context, callbackFilter = () => true) => {
const skip = parseInt(context.request.query.skip ?? 0, 10)
const limit = parseInt(context.request.query.limit ?? defaultLimit, 10);
const { select } = context.request.query ?? {};
const totalList = state[name].filter(callbackFilter);
let list = totalList.slice(skip, skip + limit);
if (select) {
list = list.map((item) => prepareItem(item, select));
}
let list = totalList.slice(skip, skip + limit).map((item) => prepareItem(item, select));
return {
[name]: list,
total: totalList.length,
Expand Down
4 changes: 2 additions & 2 deletions typescpec/models/auth.tsp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
@example(#{ login: "Max", password: "password" }, #{ title: "Authentication data", description: "Login and password for authentication" })
@example(#{ email: "[email protected]", password: "password" }, #{ title: "Authentication data", description: "Login and password for authentication" })
model AuthData {
@minLength(1)
login: string;
email: string;

@minLength(1)
password: string;
Expand Down
Loading

0 comments on commit c56cae9

Please sign in to comment.