Browse Source

* Global pipe added + typed data sent from front to back with DTOs

master
vvandenb 2 years ago
parent
commit
2647588f16
  1. 2
      .env_sample
  2. 44
      back/package-lock.json
  3. 4
      back/src/chat/dto/create-channel.dto.ts
  4. 1
      back/src/main.ts
  5. 6
      front/src/Auth.ts
  6. 34
      front/src/components/Channels.svelte
  7. 65
      front/src/components/Chat.svelte
  8. 12
      front/src/components/Profile.svelte
  9. 5
      front/src/components/dtos/connection.dto.ts
  10. 8
      front/src/components/dtos/create-channel.dto.ts
  11. 5
      front/src/components/dtos/create-message.dto.ts
  12. 5
      front/src/components/dtos/kickUser.dto.ts
  13. 9
      front/src/components/dtos/update-channel.dto.ts
  14. 15
      front/src/components/dtos/updateUser.dto.ts
  15. 8
      front/src/components/dtos/user.dto.ts

2
.env_sample

@ -19,7 +19,7 @@ MAIL_PASSWORD=
FT_OAUTH_CLIENT_ID=
FT_OAUTH_CLIENT_SECRET=
FT_OAUTH_CALLBACK_URL=http://localhost:3001/log/inReturn
JWT_SECRET=test
JWT_SECRET=
JWT_EXPIRATION_TIME=900
### DB ###

44
back/package-lock.json

@ -36,7 +36,6 @@
"cookie-parser": "^1.4.6",
"express": "^4.18.2",
"express-session": "^1.17.3",
"joi": "^17.8.3",
"multer": "^1.4.5-lts.1",
"nestjs-paginate": "^4.13.0",
"nodemailer": "^6.9.1",
@ -795,19 +794,6 @@
"fast-json-stringify": "^5.0.0"
}
},
"node_modules/@hapi/hoek": {
"version": "9.3.0",
"resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz",
"integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ=="
},
"node_modules/@hapi/topo": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz",
"integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==",
"dependencies": {
"@hapi/hoek": "^9.0.0"
}
},
"node_modules/@humanwhocodes/config-array": {
"version": "0.11.8",
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz",
@ -1731,24 +1717,6 @@
"url": "https://ko-fi.com/killymxi"
}
},
"node_modules/@sideway/address": {
"version": "4.1.4",
"resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.4.tgz",
"integrity": "sha512-7vwq+rOHVWjyXxVlR76Agnvhy8I9rpzjosTESvmhNeXOXdZZB15Fl+TI9x1SiHZH5Jv2wTGduSxFDIaq0m3DUw==",
"dependencies": {
"@hapi/hoek": "^9.0.0"
}
},
"node_modules/@sideway/formula": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.1.tgz",
"integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg=="
},
"node_modules/@sideway/pinpoint": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz",
"integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ=="
},
"node_modules/@sinclair/typebox": {
"version": "0.24.51",
"resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.51.tgz",
@ -6987,18 +6955,6 @@
"url": "https://github.com/chalk/supports-color?sponsor=1"
}
},
"node_modules/joi": {
"version": "17.8.3",
"resolved": "https://registry.npmjs.org/joi/-/joi-17.8.3.tgz",
"integrity": "sha512-q5Fn6Tj/jR8PfrLrx4fpGH4v9qM6o+vDUfD4/3vxxyg34OmKcNqYZ1qn2mpLza96S8tL0p0rIw2gOZX+/cTg9w==",
"dependencies": {
"@hapi/hoek": "^9.0.0",
"@hapi/topo": "^5.0.0",
"@sideway/address": "^4.1.3",
"@sideway/formula": "^3.0.1",
"@sideway/pinpoint": "^2.0.0"
}
},
"node_modules/js-beautify": {
"version": "1.14.7",
"resolved": "https://registry.npmjs.org/js-beautify/-/js-beautify-1.14.7.tgz",

4
back/src/chat/dto/create-channel.dto.ts

@ -8,10 +8,6 @@ import {
} from 'class-validator'
export class CreateChannelDto {
@IsOptional()
@IsPositive()
id: number
@IsString()
name: string

1
back/src/main.ts

@ -40,6 +40,7 @@ async function bootstrap (): Promise<void> {
app.use(passport.session())
app.enableCors(cors)
app.useWebSocketAdapter(new IoAdapter(app))
app.useGlobalPipes(new ValidationPipe())
await app.listen(port)
logger.log(`Application listening on port ${port}`)
}

6
front/src/Auth.ts

@ -1,6 +1,7 @@
import { writable } from "svelte/store";
import { content, show_popup } from "./components/Alert/content";
import {get} from 'svelte/store'
import type { EmailDto } from "./components/dtos/updateUser.dto";
let _user = localStorage.getItem("user");
export const store = writable(_user ? JSON.parse(_user) : null);
store.subscribe((value) => {
@ -35,13 +36,14 @@ export async function verify() {
let email : string;
await show_popup("Enter your preferred email adress:\n(defaults to 42 email)")
email = get(content);
if (email !== undefined && email !== '' && email !== 'ok') {
if (email !== undefined && email !== '' && email !== 'ok') {
const body: EmailDto = { email }
const response = await fetch(API_URL + "/log/email", {
method: "POST",
mode: "cors",
headers: {"Content-Type": "application/json",},
credentials: "include",
body: JSON.stringify({email: email})
body: JSON.stringify(body)
})
if (response.ok) {await show_popup("Email set",false)}
else {await show_popup("Couldn't set Email",false); return }

34
front/src/components/Channels.svelte

@ -3,7 +3,9 @@
import { onMount } from "svelte";
import { API_URL, store } from "../Auth";
import type User from "./Profile.svelte";
import { APPSTATE } from "../App.svelte";
import type { APPSTATE } from "../App.svelte";
import type { CreateChannelDto } from './dtos/create-channel.dto';
import type { IdDto, PasswordDto } from './dtos/updateUser.dto';
export let appState: string;
export let setAppState: (newState: APPSTATE | string) => void;
@ -119,6 +121,14 @@
}
}
name = "🚪 " + name;
const body: CreateChannelDto = {
name: name,
owner: $store.ftId,
password: password,
isPrivate: channelMode === "private",
isDM: false,
otherDMedUsername: "",
};
const response = await fetch(API_URL + "/channels", {
credentials: "include",
method: "POST",
@ -126,12 +136,7 @@
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
name: name,
owner: $store.ftId,
password: password,
isPrivate: channelMode === "private",
}),
body: JSON.stringify(body),
});
if (!response.ok) {
const error = await response.json();
@ -172,6 +177,9 @@
if (response.ok) {
const user = await response.json();
console.log(user)
const body: IdDto = {
id: user.ftId
}
const response2 = await fetch(API_URL + "/channels/" + id + "/invite", {
credentials: "include",
method: "POST",
@ -179,9 +187,7 @@
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
id: user.ftId
}),
body: JSON.stringify(body),
});
if (response2.ok) {
await show_popup("User invited", false)
@ -199,7 +205,9 @@
const changePassword = async (id: number) => {
await show_popup("Enter the new password for this channel (leave empty to remove password) :", true, true);
let string = $content
const body: PasswordDto = {
password: $content
}
const response = await fetch(API_URL + "/channels/" + id + "/password", {
credentials: "include",
method: "POST",
@ -207,9 +215,7 @@
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
password: string,
}),
body: JSON.stringify(body),
});
if (!response.ok) {
const error = await response.json();

65
front/src/components/Chat.svelte

@ -6,6 +6,11 @@
import { APPSTATE } from "../App.svelte";
import { formatChannelNames, type ChannelsType, type chatMessagesType } from "./Channels.svelte";
import type User from "./Profile.svelte";
import type { CreateChannelDto } from "./dtos/create-channel.dto";
import type { IdDto, MuteDto } from "./dtos/updateUser.dto";
import type { ConnectionDto } from "./dtos/connection.dto";
import type { CreateMessageDto } from "./dtos/create-message.dto";
import type { kickUserDto } from "./dtos/kickUser.dto";
</script>
@ -47,17 +52,20 @@
await getCurrentChannel();
if (!channel) setAppState(APPSTATE.CHANNELS);
if (!channel.password) {
socket.emit("joinChannel", {
const data: ConnectionDto = {
UserId: $store.ftId,
ChannelId: channel.id,
});
pwd: "",
};
socket.emit("joinChannel", data);
} else {
await show_popup("Channel is protected, enter password:", true, true);
socket.emit("joinChannel", {
const data: ConnectionDto = {
UserId: $store.ftId,
ChannelId: channel.id,
pwd: $content,
});
};
socket.emit("joinChannel", data);
}
socket.on("newMessage", (msg: chatMessagesType) => {
console.log(msg);
@ -116,11 +124,12 @@
const sendMessage = () => {
if (newText !== "") {
socket.emit("addMessage", {
const data: CreateMessageDto = {
text: newText,
UserId: $store.ftId,
ChannelId: channel.id,
});
};
socket.emit("addMessage", data);
newText = "";
const messagesDiv = document.querySelector(".messages");
if (messagesDiv) {
@ -175,6 +184,14 @@
setAppState(APPSTATE.CHANNELS + "#" + DMChannel[0].name)
} else {
console.log("Creating DMChannel: " + $store.username + "&" + DMUsername)
const body: CreateChannelDto = {
name: "none",
owner: $store.ftId,
password: "",
isPrivate: true,
isDM: true,
otherDMedUsername: DMUsername
}
fetch(API_URL + "/channels", {
credentials: "include",
method: "POST",
@ -182,14 +199,7 @@
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
name: "none",
owner: $store.ftId,
password: "",
isPrivate: true,
isDM: true,
otherDMedUsername: DMUsername
}),
body: JSON.stringify(body),
}).then(async () => {
const response = await getDMs(DMUsername)
if (response && response.ok) {
@ -266,6 +276,9 @@
const duration = $content;
if (duration == "")
return;
const body: MuteDto = {
data: [target.ftId, duration]
}
response = await fetch(API_URL + "/channels/" + channel.id + "/ban", {
credentials: "include",
method: "POST",
@ -273,11 +286,16 @@
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ data: [target.ftId, duration] }),
body: JSON.stringify(body),
});
if (response.ok) {
await show_popup(`User banned for: ${duration} seconds`, false);
socket.emit("kickUser", channel.id, $store.ftId, target.ftId);
const data: kickUserDto = {
chan: channel.id,
from: $store.ftId,
to: target.ftId,
};
socket.emit("kickUser", data);
} else {
const error = await response.json();
await show_popup(error.message, false)
@ -320,11 +338,12 @@
});
if (response.ok) {
const target = await response.json();
socket.emit("kickUser", {
const data: kickUserDto = {
chan: channel.id,
from: $store.ftId,
to: target.ftId,
});
};
socket.emit("kickUser", data);
} else {
const error = await response.json();
await show_popup(error.message, false);
@ -341,6 +360,9 @@
});
const target = await response.json();
if (response.ok) {
const body: MuteDto = {
data: [target.ftId, +$content]
}
response = await fetch(API_URL + "/channels/" + channel.id + "/mute", {
credentials: "include",
method: "POST",
@ -348,7 +370,7 @@
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ data: [target.ftId, +$content] }),
body: JSON.stringify(body),
});
}
if (response.ok) await show_popup("User muted", false);
@ -367,6 +389,9 @@
});
if (response.ok) {
const target = await response.json();
const body: IdDto = {
id: target.ftId
}
response = await fetch(API_URL + "/channels/" + channel.id + "/admin", {
credentials: "include",
method: "POST",
@ -374,7 +399,7 @@
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ id: target.ftId }),
body: JSON.stringify(body),
});
}
if (response.ok) {

12
front/src/components/Profile.svelte

@ -17,6 +17,7 @@
import { API_URL, store, logout } from "../Auth";
import Alert from "./Alert/Alert.svelte";
import { popup } from "./Alert/content";
import type { UserDto } from "./dtos/user.dto";
export let username: string = $store.username;
export let gamePlaying: boolean;
@ -53,7 +54,16 @@
return;
}
let response = await fetch(API_URL + "/users", {
const body: UserDto = {
username: newUsername,
ftId: $store.ftId,
status: $store.status,
authToken: $store.authToken,
avatar: $store.avatar,
isVerified: $store.isVerified
};
console.log("body:", body);
const response = await fetch(API_URL + "/users", {
headers: { "content-type": "application/json" },
method: "POST",
body: JSON.stringify({ username: newUsername }),

5
front/src/components/dtos/connection.dto.ts

@ -0,0 +1,5 @@
export class ConnectionDto {
UserId: number
ChannelId: number
pwd: string
}

8
front/src/components/dtos/create-channel.dto.ts

@ -0,0 +1,8 @@
export class CreateChannelDto {
name: string
owner: number
password: string
isPrivate: boolean
isDM: boolean
otherDMedUsername: string
}

5
front/src/components/dtos/create-message.dto.ts

@ -0,0 +1,5 @@
export class CreateMessageDto {
text: string
UserId: number
ChannelId: number
}

5
front/src/components/dtos/kickUser.dto.ts

@ -0,0 +1,5 @@
export class kickUserDto {
chan: number
from: number
to: number
}

9
front/src/components/dtos/update-channel.dto.ts

@ -0,0 +1,9 @@
import { CreateChannelDto } from './create-channel.dto'
export class UpdateChannelDto extends CreateChannelDto {
users: [number]
messages: [number]
owners: [number] // user id
banned: [number] // user id
muted: [number] // user id
}

15
front/src/components/dtos/updateUser.dto.ts

@ -0,0 +1,15 @@
export class IdDto {
id: number
}
export class PasswordDto {
password: string
}
export class MuteDto {
data: number[]
}
export class EmailDto {
email: string
}

8
front/src/components/dtos/user.dto.ts

@ -0,0 +1,8 @@
export class UserDto {
ftId: number
username: string
status: string
avatar: string
authToken: string
isVerified: boolean
}
Loading…
Cancel
Save