add ban and mute effective, can invite, set password, set private

This commit is contained in:
kinou-p 2023-06-17 19:11:40 +02:00
parent 5b1a1487e1
commit 49ddd86717
7 changed files with 535 additions and 409 deletions

View File

@ -19,6 +19,7 @@
"axios": "^1.4.0", "axios": "^1.4.0",
"base32-decode": "^1.0.0", "base32-decode": "^1.0.0",
"base32-encode": "^2.0.0", "base32-encode": "^2.0.0",
"bcrypt": "^5.1.0",
"express-session": "^1.17.3", "express-session": "^1.17.3",
"hi-base32": "^0.5.1", "hi-base32": "^0.5.1",
"nanoid": "^3.3.4", "nanoid": "^3.3.4",
@ -38,6 +39,7 @@
"@nestjs/cli": "^9.0.0", "@nestjs/cli": "^9.0.0",
"@nestjs/schematics": "^9.0.0", "@nestjs/schematics": "^9.0.0",
"@nestjs/testing": "^9.0.0", "@nestjs/testing": "^9.0.0",
"@types/bcrypt": "^5.0.0",
"@types/express": "^4.17.13", "@types/express": "^4.17.13",
"@types/jest": "29.5.0", "@types/jest": "29.5.0",
"@types/node": "18.15.11", "@types/node": "18.15.11",
@ -1425,6 +1427,39 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/@mapbox/node-pre-gyp": {
"version": "1.0.10",
"resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.10.tgz",
"integrity": "sha512-4ySo4CjzStuprMwk35H5pPbkymjv1SF3jGLj6rAHp/xT/RF7TL7bd9CTm1xDY49K2qF7jmR/g7k+SkLETP6opA==",
"dependencies": {
"detect-libc": "^2.0.0",
"https-proxy-agent": "^5.0.0",
"make-dir": "^3.1.0",
"node-fetch": "^2.6.7",
"nopt": "^5.0.0",
"npmlog": "^5.0.1",
"rimraf": "^3.0.2",
"semver": "^7.3.5",
"tar": "^6.1.11"
},
"bin": {
"node-pre-gyp": "bin/node-pre-gyp"
}
},
"node_modules/@mapbox/node-pre-gyp/node_modules/rimraf": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
"integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
"dependencies": {
"glob": "^7.1.3"
},
"bin": {
"rimraf": "bin.js"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/@nestjs/cli": { "node_modules/@nestjs/cli": {
"version": "9.4.2", "version": "9.4.2",
"resolved": "https://registry.npmjs.org/@nestjs/cli/-/cli-9.4.2.tgz", "resolved": "https://registry.npmjs.org/@nestjs/cli/-/cli-9.4.2.tgz",
@ -2131,6 +2166,15 @@
"@babel/types": "^7.3.0" "@babel/types": "^7.3.0"
} }
}, },
"node_modules/@types/bcrypt": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/@types/bcrypt/-/bcrypt-5.0.0.tgz",
"integrity": "sha512-agtcFKaruL8TmcvqbndlqHPSJgsolhf/qPWchFlgnW1gECTN/nKbFcoFnvKAQRFfKbh+BO6A3SWdJu9t+xF3Lw==",
"dev": true,
"dependencies": {
"@types/node": "*"
}
},
"node_modules/@types/body-parser": { "node_modules/@types/body-parser": {
"version": "1.19.2", "version": "1.19.2",
"resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz",
@ -2734,6 +2778,11 @@
"resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz",
"integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==" "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ=="
}, },
"node_modules/abbrev": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
"integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q=="
},
"node_modules/accepts": { "node_modules/accepts": {
"version": "1.3.8", "version": "1.3.8",
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
@ -2783,6 +2832,17 @@
"node": ">=0.4.0" "node": ">=0.4.0"
} }
}, },
"node_modules/agent-base": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
"integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
"dependencies": {
"debug": "4"
},
"engines": {
"node": ">= 6.0.0"
}
},
"node_modules/ajv": { "node_modules/ajv": {
"version": "6.12.6", "version": "6.12.6",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
@ -2934,6 +2994,36 @@
"resolved": "https://registry.npmjs.org/append-field/-/append-field-1.0.0.tgz", "resolved": "https://registry.npmjs.org/append-field/-/append-field-1.0.0.tgz",
"integrity": "sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw==" "integrity": "sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw=="
}, },
"node_modules/aproba": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz",
"integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ=="
},
"node_modules/are-we-there-yet": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz",
"integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==",
"dependencies": {
"delegates": "^1.0.0",
"readable-stream": "^3.6.0"
},
"engines": {
"node": ">=10"
}
},
"node_modules/are-we-there-yet/node_modules/readable-stream": {
"version": "3.6.2",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
"integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
"dependencies": {
"inherits": "^2.0.3",
"string_decoder": "^1.1.1",
"util-deprecate": "^1.0.1"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/arg": { "node_modules/arg": {
"version": "4.1.3", "version": "4.1.3",
"resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
@ -3112,6 +3202,19 @@
} }
] ]
}, },
"node_modules/bcrypt": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-5.1.0.tgz",
"integrity": "sha512-RHBS7HI5N5tEnGTmtR/pppX0mmDSBpQ4aCBsj7CEQfYXDcO74A8sIBYcJMuCsis2E81zDxeENYhv66oZwLiA+Q==",
"hasInstallScript": true,
"dependencies": {
"@mapbox/node-pre-gyp": "^1.0.10",
"node-addon-api": "^5.0.0"
},
"engines": {
"node": ">= 10.0.0"
}
},
"node_modules/binary-extensions": { "node_modules/binary-extensions": {
"version": "2.2.0", "version": "2.2.0",
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
@ -3186,7 +3289,6 @@
"version": "1.1.11", "version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"dev": true,
"dependencies": { "dependencies": {
"balanced-match": "^1.0.0", "balanced-match": "^1.0.0",
"concat-map": "0.0.1" "concat-map": "0.0.1"
@ -3418,6 +3520,14 @@
"fsevents": "~2.3.2" "fsevents": "~2.3.2"
} }
}, },
"node_modules/chownr": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
"integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==",
"engines": {
"node": ">=10"
}
},
"node_modules/chrome-trace-event": { "node_modules/chrome-trace-event": {
"version": "1.0.3", "version": "1.0.3",
"resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz",
@ -3604,6 +3714,14 @@
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
}, },
"node_modules/color-support": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz",
"integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==",
"bin": {
"color-support": "bin.js"
}
},
"node_modules/combined-stream": { "node_modules/combined-stream": {
"version": "1.0.8", "version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
@ -3633,8 +3751,7 @@
"node_modules/concat-map": { "node_modules/concat-map": {
"version": "0.0.1", "version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
"dev": true
}, },
"node_modules/concat-stream": { "node_modules/concat-stream": {
"version": "1.6.2", "version": "1.6.2",
@ -3655,6 +3772,11 @@
"resolved": "https://registry.npmjs.org/consola/-/consola-2.15.3.tgz", "resolved": "https://registry.npmjs.org/consola/-/consola-2.15.3.tgz",
"integrity": "sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw==" "integrity": "sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw=="
}, },
"node_modules/console-control-strings": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
"integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ=="
},
"node_modules/content-disposition": { "node_modules/content-disposition": {
"version": "0.5.4", "version": "0.5.4",
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
@ -3817,6 +3939,11 @@
"node": ">=0.4.0" "node": ">=0.4.0"
} }
}, },
"node_modules/delegates": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
"integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ=="
},
"node_modules/depd": { "node_modules/depd": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
@ -3834,6 +3961,14 @@
"npm": "1.2.8000 || >= 1.4.16" "npm": "1.2.8000 || >= 1.4.16"
} }
}, },
"node_modules/detect-libc": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.1.tgz",
"integrity": "sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==",
"engines": {
"node": ">=8"
}
},
"node_modules/detect-newline": { "node_modules/detect-newline": {
"version": "3.1.0", "version": "3.1.0",
"resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz",
@ -4761,6 +4896,33 @@
"node": ">=12" "node": ">=12"
} }
}, },
"node_modules/fs-minipass": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
"integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
"dependencies": {
"minipass": "^3.0.0"
},
"engines": {
"node": ">= 8"
}
},
"node_modules/fs-minipass/node_modules/minipass": {
"version": "3.3.6",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
"integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
"dependencies": {
"yallist": "^4.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/fs-minipass/node_modules/yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
},
"node_modules/fs-monkey": { "node_modules/fs-monkey": {
"version": "1.0.3", "version": "1.0.3",
"resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.3.tgz", "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.3.tgz",
@ -4791,6 +4953,25 @@
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
}, },
"node_modules/gauge": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz",
"integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==",
"dependencies": {
"aproba": "^1.0.3 || ^2.0.0",
"color-support": "^1.1.2",
"console-control-strings": "^1.0.0",
"has-unicode": "^2.0.1",
"object-assign": "^4.1.1",
"signal-exit": "^3.0.0",
"string-width": "^4.2.3",
"strip-ansi": "^6.0.1",
"wide-align": "^1.1.2"
},
"engines": {
"node": ">=10"
}
},
"node_modules/gensync": { "node_modules/gensync": {
"version": "1.0.0-beta.2", "version": "1.0.0-beta.2",
"resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
@ -4846,7 +5027,6 @@
"version": "7.2.3", "version": "7.2.3",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
"integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
"dev": true,
"dependencies": { "dependencies": {
"fs.realpath": "^1.0.0", "fs.realpath": "^1.0.0",
"inflight": "^1.0.4", "inflight": "^1.0.4",
@ -4955,6 +5135,11 @@
"url": "https://github.com/sponsors/ljharb" "url": "https://github.com/sponsors/ljharb"
} }
}, },
"node_modules/has-unicode": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
"integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ=="
},
"node_modules/hexoid": { "node_modules/hexoid": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/hexoid/-/hexoid-1.0.0.tgz", "resolved": "https://registry.npmjs.org/hexoid/-/hexoid-1.0.0.tgz",
@ -4998,6 +5183,18 @@
"node": ">= 0.8" "node": ">= 0.8"
} }
}, },
"node_modules/https-proxy-agent": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
"integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
"dependencies": {
"agent-base": "6",
"debug": "4"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/human-signals": { "node_modules/human-signals": {
"version": "2.1.0", "version": "2.1.0",
"resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz",
@ -6267,7 +6464,6 @@
"version": "3.1.0", "version": "3.1.0",
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
"integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==",
"dev": true,
"dependencies": { "dependencies": {
"semver": "^6.0.0" "semver": "^6.0.0"
}, },
@ -6282,7 +6478,6 @@
"version": "6.3.0", "version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
"dev": true,
"bin": { "bin": {
"semver": "bin/semver.js" "semver": "bin/semver.js"
} }
@ -6405,7 +6600,6 @@
"version": "3.1.2", "version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
"dev": true,
"dependencies": { "dependencies": {
"brace-expansion": "^1.1.7" "brace-expansion": "^1.1.7"
}, },
@ -6430,6 +6624,34 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/minizlib": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz",
"integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==",
"dependencies": {
"minipass": "^3.0.0",
"yallist": "^4.0.0"
},
"engines": {
"node": ">= 8"
}
},
"node_modules/minizlib/node_modules/minipass": {
"version": "3.3.6",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
"integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
"dependencies": {
"yallist": "^4.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/minizlib/node_modules/yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
},
"node_modules/mkdirp": { "node_modules/mkdirp": {
"version": "0.5.6", "version": "0.5.6",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz",
@ -6521,6 +6743,11 @@
"integrity": "sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==", "integrity": "sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==",
"dev": true "dev": true
}, },
"node_modules/node-addon-api": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.1.0.tgz",
"integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA=="
},
"node_modules/node-emoji": { "node_modules/node-emoji": {
"version": "1.11.0", "version": "1.11.0",
"resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.11.0.tgz", "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.11.0.tgz",
@ -6560,6 +6787,20 @@
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.10.tgz", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.10.tgz",
"integrity": "sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==" "integrity": "sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w=="
}, },
"node_modules/nopt": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz",
"integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==",
"dependencies": {
"abbrev": "1"
},
"bin": {
"nopt": "bin/nopt.js"
},
"engines": {
"node": ">=6"
}
},
"node_modules/normalize-path": { "node_modules/normalize-path": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
@ -6581,6 +6822,17 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/npmlog": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz",
"integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==",
"dependencies": {
"are-we-there-yet": "^2.0.0",
"console-control-strings": "^1.1.0",
"gauge": "^3.0.0",
"set-blocking": "^2.0.0"
}
},
"node_modules/object-assign": { "node_modules/object-assign": {
"version": "4.1.1", "version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
@ -6871,7 +7123,6 @@
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
"integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
"dev": true,
"engines": { "engines": {
"node": ">=0.10.0" "node": ">=0.10.0"
} }
@ -7962,8 +8213,7 @@
"node_modules/signal-exit": { "node_modules/signal-exit": {
"version": "3.0.7", "version": "3.0.7",
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
"integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="
"dev": true
}, },
"node_modules/sisteransi": { "node_modules/sisteransi": {
"version": "1.0.5", "version": "1.0.5",
@ -8061,7 +8311,6 @@
"version": "1.3.0", "version": "1.3.0",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
"integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
"dev": true,
"dependencies": { "dependencies": {
"safe-buffer": "~5.2.0" "safe-buffer": "~5.2.0"
} }
@ -8219,6 +8468,46 @@
"node": ">=6" "node": ">=6"
} }
}, },
"node_modules/tar": {
"version": "6.1.15",
"resolved": "https://registry.npmjs.org/tar/-/tar-6.1.15.tgz",
"integrity": "sha512-/zKt9UyngnxIT/EAGYuxaMYgOIJiP81ab9ZfkILq4oNLPFX50qyYmu7jRj9qeXoxmJHjGlbH0+cm2uy1WCs10A==",
"dependencies": {
"chownr": "^2.0.0",
"fs-minipass": "^2.0.0",
"minipass": "^5.0.0",
"minizlib": "^2.1.1",
"mkdirp": "^1.0.3",
"yallist": "^4.0.0"
},
"engines": {
"node": ">=10"
}
},
"node_modules/tar/node_modules/minipass": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz",
"integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==",
"engines": {
"node": ">=8"
}
},
"node_modules/tar/node_modules/mkdirp": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
"integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
"bin": {
"mkdirp": "bin/cmd.js"
},
"engines": {
"node": ">=10"
}
},
"node_modules/tar/node_modules/yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
},
"node_modules/terser": { "node_modules/terser": {
"version": "5.17.1", "version": "5.17.1",
"resolved": "https://registry.npmjs.org/terser/-/terser-5.17.1.tgz", "resolved": "https://registry.npmjs.org/terser/-/terser-5.17.1.tgz",
@ -9098,6 +9387,14 @@
"resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz",
"integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==" "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ=="
}, },
"node_modules/wide-align": {
"version": "1.1.5",
"resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz",
"integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==",
"dependencies": {
"string-width": "^1.0.2 || 2 || 3 || 4"
}
},
"node_modules/windows-release": { "node_modules/windows-release": {
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/windows-release/-/windows-release-4.0.0.tgz", "resolved": "https://registry.npmjs.org/windows-release/-/windows-release-4.0.0.tgz",

View File

@ -30,6 +30,7 @@
"axios": "^1.4.0", "axios": "^1.4.0",
"base32-decode": "^1.0.0", "base32-decode": "^1.0.0",
"base32-encode": "^2.0.0", "base32-encode": "^2.0.0",
"bcrypt": "^5.1.0",
"express-session": "^1.17.3", "express-session": "^1.17.3",
"hi-base32": "^0.5.1", "hi-base32": "^0.5.1",
"nanoid": "^3.3.4", "nanoid": "^3.3.4",
@ -49,6 +50,7 @@
"@nestjs/cli": "^9.0.0", "@nestjs/cli": "^9.0.0",
"@nestjs/schematics": "^9.0.0", "@nestjs/schematics": "^9.0.0",
"@nestjs/testing": "^9.0.0", "@nestjs/testing": "^9.0.0",
"@types/bcrypt": "^5.0.0",
"@types/express": "^4.17.13", "@types/express": "^4.17.13",
"@types/jest": "29.5.0", "@types/jest": "29.5.0",
"@types/node": "18.15.11", "@types/node": "18.15.11",

View File

@ -6,7 +6,7 @@
/* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */ /* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2023/06/17 01:00:00 by apommier #+# #+# */ /* Created: 2023/06/17 01:00:00 by apommier #+# #+# */
/* Updated: 2023/06/17 01:47:43 by apommier ### ########.fr */ /* Updated: 2023/06/17 17:29:05 by apommier ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@ -419,7 +419,13 @@ export class AppController {
return await this.chatService.getConv(req.user.username); return await this.chatService.getConv(req.user.username);
} }
// @UseGuards(JwtAuthGuard) @UseGuards(JwtAuthGuard)
@Get('/convs')
async getConvs() {
return await this.chatService.findAll();
}
@UseGuards(JwtAuthGuard)
@Post('/message') @Post('/message')
async postMessage(@Request() req, @Body() data: any) { async postMessage(@Request() req, @Body() data: any) {
//if i can post post ? //if i can post post ?
@ -432,9 +438,10 @@ export class AppController {
id: null, id: null,
} }
console.log(data); console.log(data);
return await this.chatService.createMessage(message); return await this.chatService.createMessage(message, req.user.username);
} }
@UseGuards(JwtAuthGuard)
@Post('/member') @Post('/member')
async getMember(@Body() data: any) { async getMember(@Body() data: any) {
console.log(data); console.log(data);
@ -442,6 +449,7 @@ export class AppController {
return await this.chatService.findConv(data.convId); return await this.chatService.findConv(data.convId);
} }
@UseGuards(JwtAuthGuard)
@Post('/getMessage') @Post('/getMessage')
async getMessage(@Body() data: any) { async getMessage(@Body() data: any) {
console.log(data); console.log(data);
@ -457,11 +465,13 @@ export class AppController {
// res.json(messages); // res.json(messages);
} }
@UseGuards(JwtAuthGuard)
@Post('/ban') @Post('/ban')
async banUser(@Body() data: any) { async banUser(@Body() data: any) {
return await this.chatService.banUser(data.convId, data.username) return await this.chatService.banUser(data.convId, data.username)
} }
@UseGuards(JwtAuthGuard)
@Post('/name') @Post('/name')
async setName(@Body() data: any) { async setName(@Body() data: any) {
//find conv //find conv
@ -469,30 +479,59 @@ export class AppController {
return await this.chatService.setName(data.convId, data.name) return await this.chatService.setName(data.convId, data.name)
} }
@UseGuards(JwtAuthGuard)
@Post('/invite') @Post('/invite')
async inviteUser(@Body() data: any) { async inviteUser(@Body() data: any) {
return await this.chatService.inviteUser(data.convId, data.username) return await this.chatService.inviteUser(data.convId, data.username)
} }
@UseGuards(JwtAuthGuard)
@Post('/password') @Post('/password')
async setPassword(@Body() data: any) { async setPassword(@Body() data: any) {
return await this.chatService.setPassword(data.convId, data.password) return await this.chatService.setPassword(data.convId, data.password)
} }
@UseGuards(JwtAuthGuard)
@Post('/verifyPassword')
async verifyPassword(@Body() data: any) {
return await this.chatService.verifyPassword(data.convId, data.password)
}
@UseGuards(JwtAuthGuard)
@Post('/admin') @Post('/admin')
async setAdmin(@Body() data: any) { async setAdmin(@Body() data: any) {
return await this.chatService.setAdmin(data.convId, data.username) return await this.chatService.setAdmin(data.convId, data.username)
} }
@UseGuards(JwtAuthGuard)
@Post('/isAdmin')
async isAdmin(@Request() req, @Body() data: any) {
console.log("isdamin= ", req.user.username, " id=", data.convId)
return await this.chatService.isAdmin(data.convId, req.user.username)
}
@UseGuards(JwtAuthGuard)
@Post('/mute') @Post('/mute')
async muteUser(@Body() data: any) { async muteUser(@Body() data: any) {
return await this.chatService.muteUser(data.convId, data.username) return await this.chatService.muteUser(data.convId, data.username)
} }
@UseGuards(JwtAuthGuard)
@Post('/private') @Post('/private')
async setPrivate(@Body() data: any) { async setPrivate(@Body() data: any) {
return await this.chatService.setPrivate(data.convId) return await this.chatService.setPrivate(data.convId)
} }
@UseGuards(JwtAuthGuard)
@Post('/allowed')
async isAllowed(@Request() req, @Body() data: any) {
return await this.chatService.isAllowed(data.convId, req.user.username)
}
@UseGuards(JwtAuthGuard)
@Post('/join')
async joinChannel(@Request() req, @Body() data: any) {
return await this.chatService.joinChannel(data.convId, req.user.username)
}
} }

View File

@ -6,7 +6,7 @@
/* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */ /* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2023/06/17 01:00:25 by apommier #+# #+# */ /* Created: 2023/06/17 01:00:25 by apommier #+# #+# */
/* Updated: 2023/06/17 01:48:15 by apommier ### ########.fr */ /* Updated: 2023/06/17 17:31:11 by apommier ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@ -16,6 +16,8 @@ import { Repository } from 'typeorm';
import { Conv } from '../model/chat.entity'; import { Conv } from '../model/chat.entity';
import { Message } from '../model/chat.entity'; import { Message } from '../model/chat.entity';
import * as bcrypt from 'bcrypt';
import { ArrayContains } from "typeorm" import { ArrayContains } from "typeorm"
import { query } from 'express'; import { query } from 'express';
import { InitializeOnPreviewAllowlist } from '@nestjs/core'; import { InitializeOnPreviewAllowlist } from '@nestjs/core';
@ -31,6 +33,10 @@ export class ChatService {
return await this.chatRepository.save(conv); return await this.chatRepository.save(conv);
} }
async findAll(): Promise<Conv[]> {
return await this.chatRepository.find();
}
async createConv(conv: Conv): Promise<Conv> { async createConv(conv: Conv): Promise<Conv> {
return await this.chatRepository.save(conv); return await this.chatRepository.save(conv);
} }
@ -49,8 +55,22 @@ async findConv(number: number){
return conv; return conv;
} }
async createMessage(message: Message): Promise<Message> { async createMessage(message: Message, username: string): Promise<Message> {
return await this.messageRepository.save(message); const conv = await this.findConv(message.convid);
if (conv.banned.find(item => item === username))
return ;
if (conv.muted.find(item => item === username))
return ;
return await this.messageRepository.save(message);
}
async isAllowed(convId: number, username: string) {
const conv = await this.findConv(convId);
if (conv.banned.find(item => item === username))
return (0);
if (conv.muted.find(item => item === username))
return (0);
return (1);
} }
async getMessages(convId: number): Promise<Message[]> { async getMessages(convId: number): Promise<Message[]> {
@ -79,13 +99,26 @@ async inviteUser(convId: number, username: string) {
//save user //save user
} }
async setPassword(convId: number, password: string) { async setPassword(convId: number, password: string) {
//verify is user is admin ? //verify is user is admin ?
const conv = await this.findConv(convId); const conv = await this.findConv(convId);
conv.password = password const saltRounds = 10;
const hashedPassword = await bcrypt.hash(password, saltRounds);
// return hashedPassword;
conv.password = hashedPassword
this.save(conv); this.save(conv);
} }
async verifyPassword(convId: number, password: string) {
//verify is user is admin ?
const conv = await this.findConv(convId);
return await bcrypt.compare(password, conv.password);
// conv.password = password
}
async muteUser(convId: number, username: string) { async muteUser(convId: number, username: string) {
const conv = await this.findConv(convId); const conv = await this.findConv(convId);
@ -106,6 +139,16 @@ async setAdmin(convId: number, username: string) {
this.save(conv); this.save(conv);
} }
async isAdmin(convId: number, username: string) {
const conv = await this.findConv(convId);
conv.admin = conv.admin || [];
if (conv.admin.find(item => item === username))
return (1);
console.log("nope");
return (0);
}
async setPrivate(convId: number) { async setPrivate(convId: number) {
const conv = await this.findConv(convId); const conv = await this.findConv(convId);
if (conv.private === true) if (conv.private === true)
@ -121,4 +164,14 @@ async setName(convId: number, name: string) {
this.save(conv); this.save(conv);
} }
async joinChannel(convId: number, username: string) {
const conv = await this.findConv(convId);
conv.members = conv.members || [];
if (conv.members.find(item => item === username))
return ;
conv.members.push(username);
// conv.name = name;
this.save(conv);
}
} }

View File

@ -1,362 +0,0 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* Chats.jsx :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2023/06/17 00:59:57 by apommier #+# #+# */
/* Updated: 2023/06/17 01:24:24 by apommier ### ########.fr */
/* */
/* ************************************************************************** */
import React, { useState, useEffect, useRef } from "react";
import io from 'socket.io-client';
import '../../styles/Messages.css'
import styled from "styled-components";
import DefaultPic from '../../assets/profile.jpg'
import api from '../../script/axiosApi';
import { motion , AnimatePresence} from "framer-motion";
import Modal from "./Modal";
import Message from "./Message"
// import Input from "./Input";
//react icons
import { TbSend } from 'react-icons/tb';
import { ImBlocked } from 'react-icons/im';
import { MdOutlineGroupAdd } from 'react-icons/md';
import { GrAdd } from 'react-icons/gr';
import { RiListSettingsLine } from 'react-icons/ri'
import { Rank } from "../../DataBase/DataRank";
import GreenAlert from "../Alert/GreenAlert";
import RedAlert from "../Alert/RedAlert";
import YellowAlert from "../Alert/YellowAlert";
import ModalSetting from "./ModalSetting";
const TouchDiv = styled.div`
margin-left: 10px;
margin-right: 4px;
margin-bottom: 21px;
margin-top: 21px;
cursor: pointer;
justify-content: space-around;
&:hover {
color: #F4F3EF;
}
`
const UserChat = styled.div `
padding: 5px;
display: flex;
align-items: center;
gap: 5px;
color: white;
cursor: pointer;
&:hover{
background-color: #3e3c61;
}
&:active {
filter: black;
}
`
// const SideSpan = styled.span`
// font-size: 18px;
// font-weight: 500;
// `
const SideP = styled.p`
font-size: 14px;
color: lightgray;
margin-left: 15px;
`
//========================================================================================================
//========================================================================================================
// Logical part
//========================================================================================================
//========================================================================================================
function Chats(){
const [isLoading, setIsLoading] = useState(true);
const [conversations, setConversation] = useState([]);
const [user, setUser] = useState(null);
const [currentChat, setCurrentChat] = useState(false); // false is good?
const [messages, setMessage] = useState([]);
const [newMessages, setNewMessage] = useState("");
const [incomingMessage, setIncomingMessage] = useState("");
const socket = useRef();
useEffect(()=> {
const getConv = async ()=>{
try{
const convs = await api.get("/conv")
const tmpUser = await api.get("/profile")
console.log(convs);
setUser(tmpUser.data);
setConversation(convs.data);
// return tmpUser;
// console.log(`user= ${tmpUser.data.username}`);
// console.log(`user= ${tmpUser.data.nickname}`);
// console.log(`user= ${tmpUser.data}`);
socket.current = io("ws://localhost:4001");
console.log(`connection....`);
socket.current.emit('connection', {username: tmpUser.data.username})
// const socket = io("http://localhost:4001", {
// query: {
// username: user.username,
// },});
socket.current.on('message', (data) => { //data should be a message ?
console.log(`message received data= ${data.sender}`)
console.log(`message received data= ${data.convId}`)
console.log(`message received data= ${data.sender}`)
console.log(`current chat = ${currentChat}`)
setIncomingMessage(data);
});
setIsLoading(false)
}
catch(err){
console.log(err);
}
};
getConv();
}, [])
useEffect(()=> {
if (currentChat)
console.log(currentChat.id)
// console.log(`result1 = ${currentChat.id !== incomingMessage.convId}`)
if (currentChat !== null && currentChat.id === incomingMessage.convId)
setMessage((prev) => [...prev, incomingMessage]);
}, [incomingMessage, currentChat])
useEffect(()=> {
const getMessage = async ()=>
{
const data = {convId: currentChat.id};
try {
const res = await api.post('/getMessage', data);
setMessage(res.data);
} catch(err) {
}
}
getMessage();
}, [currentChat]);
const handleSubmit = async (e)=>{
e.preventDefault();
// console.log(`e= ${e.key}`)
// console.log(`name= ${user.username}`)
const message = {
sender: user.username,
text: newMessages,
convId: currentChat.id,
members: null
};
try{
console.log(`id= ${currentChat.id}`)
const res = await api.post('/message', message);
const convMember = await api.post('/member', message);
message.members = convMember.data.members;
console.log(convMember);
// console.log(`currentChat= ${currentChat.id}`)
setMessage([...messages, res.data]);
setNewMessage("");
socket.current.emit('sendMessage', message);
}
catch(err){
console.log(err)
}
}
const handleKeyPress = async (e)=>{
// console.log(`e in press= ${e.key}`)
if (e.key !== "Enter")
return ;
// console.log(`name= ${user.username}`)
const message = {
sender: user.username,
text: newMessages,
convId: currentChat.id,
members: null
};
try{
console.log(`id= ${currentChat.id}`)
const res = await api.post('/message', message);
const convMember = await api.post('/member', message);
message.members = convMember.data.members;
console.log(convMember);
// console.log(`currentChat= ${currentChat.id}`)
setMessage([...messages, res.data]);
setNewMessage("");
socket.current.emit('sendMessage', message);
}
catch(err){
console.log(err)
}
}
const [friend, setFriend] = useState("");
const [modalOpen, setModalOpen] = useState(false);
const [addFriend, setAddFriend] = useState(false);
const [block, setBlock] = useState(false);
const [setting, setSetting] = useState(false);
const close = () => setModalOpen(false);
const open = () => setModalOpen(true);
const closeAddFriend = () => setAddFriend(false);
const closeBlock = () => setBlock(false);
const closeSetting = () => setSetting(false);
const handleFriend = e => {
setFriend(e.target.value)
};
//========================================================================================================
//========================================================================================================
// HTML
//========================================================================================================
//========================================================================================================
return (
<div className="chat">
<div className='navbar'>
<img src={DefaultPic} alt="profile" className="pic"/>
<span>
{isLoading ? (
<h4>Loading...</h4>
) : (
<h4>{user.nickname}</h4>
)}
</span>
<div className="end">
<input className="lookForFriends" type="text" value={friend} onChange={handleFriend}/>
<TouchDiv>
<motion.div
onClick={() => (addFriend ? setAddFriend(false) : setAddFriend(true))}>
<MdOutlineGroupAdd/>
{/* {console.log("find = ",find) && setFind(true)} */}
</motion.div>
<AnimatePresence
initial={false}
onExitComplete={() => null}
>
{addFriend && <GreenAlert handleClose={closeAddFriend} text={friend + " was successfuly added"}/>}
</AnimatePresence>
{/* {console.log("find2 = ", find) && find && <BasicAlert modalOpen={find} handleClose={setFind(false)}/>} */}
</TouchDiv>
<TouchDiv>
<motion.div
onClick={() => (block ? setBlock(false) : setBlock(true))}
>
<ImBlocked/>
<AnimatePresence
initial={false}
onExitComplete={() => null}
>
{block && <RedAlert handleClose={closeBlock} text={friend + " was successfuly blocked"}/>}
</AnimatePresence>
</motion.div>
</TouchDiv>
{currentChat ? (
<TouchDiv>
<motion.div
onClick={() => (setting ? setSetting(false) : setSetting(true))}
>
<RiListSettingsLine/>
<AnimatePresence
initial={false}
onExitComplete={() => null}
>
{setting && <ModalSetting handleClose={closeSetting} convId={currentChat.id}/>}
</AnimatePresence>
</motion.div>
</TouchDiv>
):("")}
</div>
</div>
<div className="messages_box">
<div className="contact">
<UserChat>
<motion.div className="newMessage"
onClick={() => (modalOpen ? close() : open())}
>
<GrAdd/>
<span>New Conversation</span>
</motion.div>
{modalOpen && <Modal modalOpen={modalOpen} handleClose={close}/>}
</UserChat>
{conversations.map((c, index ) => {
return (
<div key={index}
onClick={() => setCurrentChat(c)}>
<UserChat>
<img className="pic-user" src={DefaultPic} alt="User" />
<div className="infoSideBar">
<span>{c.name}</span>
<SideP>Desc?</SideP>
</div>
</UserChat>
</div>
)})}
</div>
{
currentChat ? (
<>
<div className="messages">
<div className="scroll">
{messages.map(m=>(
<Message message = {m} own={m.sender === user.username} user={m}/>
))}
</div>
{/* <Input/> */}
<div className="input">
<input
onKeyDown={handleKeyPress}
type="text"
placeholder="What do you want to say"
onChange={(e) => setNewMessage(e.target.value)}
value={newMessages}
/>
<div className="send">
<TbSend onClick={handleSubmit}></TbSend>
</div>
</div>
</div>
</>
) : (
<div className="messages">
<span className="noConv">Open a conversation</span>
</div>
)}
</div>
</div>
// </div>
);
}
export default Chats

View File

@ -77,6 +77,8 @@ function Chats(){
const [conversations, setConversation] = useState([]); const [conversations, setConversation] = useState([]);
const [user, setUser] = useState(null); const [user, setUser] = useState(null);
const [currentChat, setCurrentChat] = useState(false); // false is good? const [currentChat, setCurrentChat] = useState(false); // false is good?
const [isAdmin, setIsAdmin] = useState(false); // false is good?
// const [currentChat, setCurrentChat] = useState(false); // false is good?
const [messages, setMessage] = useState([]); const [messages, setMessage] = useState([]);
const [newMessages, setNewMessage] = useState(""); const [newMessages, setNewMessage] = useState("");
const [incomingMessage, setIncomingMessage] = useState(""); const [incomingMessage, setIncomingMessage] = useState("");
@ -115,11 +117,30 @@ function Chats(){
}, []) }, [])
useEffect(()=> { useEffect(()=> {
if (currentChat)
console.log(currentChat.id) const updateChat = async ()=> {
// console.log(`result1 = ${currentChat.id !== incomingMessage.convId}`) // if (currentChat)
if (currentChat !== null && currentChat.id === incomingMessage.convId) // console.log(currentChat.id)
setMessage((prev) => [...prev, incomingMessage]); if (currentChat)
{
try {
const res = await api.post("/isAdmin", {convId: currentChat.id})
console.log("isadmin= ", res.data)
setIsAdmin(res.data);
} catch (err) {
console.log(err);
}
}
// console.log(`result1 = ${currentChat.id !== incomingMessage.convId}`)
if (currentChat !== null && currentChat.id === incomingMessage.convId)
{
setMessage((prev) => [...prev, incomingMessage]);
}
}
updateChat();
}, [incomingMessage, currentChat]) }, [incomingMessage, currentChat])
useEffect(()=> { useEffect(()=> {
@ -149,6 +170,10 @@ function Chats(){
}; };
try{ try{
console.log(`id= ${currentChat.id}`) console.log(`id= ${currentChat.id}`)
const allowed = await api.post('/allowed', {convId: message.convId, username: user.username});
console.log("allowed= ", allowed.data)
if (!allowed.data)
return ;
const res = await api.post('/message', message); const res = await api.post('/message', message);
const convMember = await api.post('/member', message); const convMember = await api.post('/member', message);
message.members = convMember.data.members; message.members = convMember.data.members;
@ -358,6 +383,21 @@ function Chats(){
)} )}
</AnimatePresence> </AnimatePresence>
</TouchDiv> </TouchDiv>
{currentChat && isAdmin ? (
<TouchDiv>
<motion.div
onClick={() => (setting ? setSetting(false) : setSetting(true))}
>
<RiListSettingsLine/>
<AnimatePresence
initial={false}
onExitComplete={() => null}
>
{setting && <ModalSetting handleClose={closeSetting} convId={currentChat.id}/>}
</AnimatePresence>
</motion.div>
</TouchDiv>
):("")}
</div> </div>

View File

@ -28,14 +28,23 @@ const Modal = ({handleClose}) => {
const [selectTags, setSelectTag] = useState([{ id: 1, selectedOption: ''}]); const [selectTags, setSelectTag] = useState([{ id: 1, selectedOption: ''}]);
const [selectedOptionArray, setSelectedOptionArray] = useState([]); const [selectedOptionArray, setSelectedOptionArray] = useState([]);
const [users, setUsers] = useState([]); const [users, setUsers] = useState([]);
const [user, setUser] = useState();
const [convs, setConvs] = useState([]);
const [channel, setChannel] = useState('');
useEffect(()=> { useEffect(()=> {
const getConv = async ()=>{ const getConv = async ()=>{
try { try {
const tmpUsers = await api.get("/users"); const tmpUsers = await api.get("/users");
const tmpUser = await api.get("/profile");
const tmpConvs = await api.get("/convs");
console.log("users=", tmpUsers.data); console.log("users=", tmpUsers.data);
console.log("convs=", tmpConvs.data);
setUsers(tmpUsers.data); setUsers(tmpUsers.data);
setUser(tmpUser.data);
setConvs(tmpConvs.data);
} catch(err){ } catch(err){
console.log(err) console.log(err)
} }
@ -58,6 +67,15 @@ const Modal = ({handleClose}) => {
console.log(selectTags) console.log(selectTags)
}; };
const joinChannel = async () => {
try {
console.log("channel= ", channel)
await api.post("/join", {convId: channel})
} catch(err) {
console.log(err);
}
};
const saveSelectedOptions = () => { const saveSelectedOptions = () => {
// const selectedOptions = selectTags.map((tag) => tag.selectedOption); // const selectedOptions = selectTags.map((tag) => tag.selectedOption);
const selectedOptions = selectTags.map((tag) => tag.selectedOption).filter((option) => option !== ''); const selectedOptions = selectTags.map((tag) => tag.selectedOption).filter((option) => option !== '');
@ -108,24 +126,63 @@ const Modal = ({handleClose}) => {
</select> </select>
</div> </div>
))} ))}
<div> <div>
<GrAdd onClick={addNewSelectedTag}/> <GrAdd onClick={addNewSelectedTag}/>
</div> </div>
<div> <div className="div_submit">
<h3>Selected Option:</h3> <Link to='#' className="submit" onClick={ saveSelectedOptions}>Submit</Link>
<ul>
{selectedOptionArray.map((option, index) => ( <Link to="#" className="submit" onClick={handleClose}>Cancel</Link>
<li key={index}>{option}</li> </div>
))}
</ul>
</div>
<div className="div_submit"> {convs.length > 0 && (
<Link to='#' className="submit" onClick={ saveSelectedOptions}>Submit</Link> <select
value={channel}
onChange={(event) => setChannel(event.target.value)}
>
<option value="">Select an option</option>
{convs.map((conv) => (
!(!conv.group || conv.private || (conv.banned && conv.banned.includes(channel)) || (conv.members && conv.members.includes(user.username))) && (
<option key={conv.id} value={conv.id}>
{conv.name}
</option>
)
))}
</select>
)}
<div className="div_submit">
<Link to='#' className="submit" onClick={ joinChannel }>Join</Link>
</div>
{/* {selectTags.map((selectTag) => (
<div key={selectTag.id}>
<select
value={selectTag.selectedOption}
onChange={(a) => handleOptionChange(selectTag.id, a.target.value)}
>
<option value="">{
selectTag.selectedOption ? selectTag.selectedOption : "Select an option"
}</option>
{convs.filter((item) => !selectTags.some((tag) => tag.selectedOption === item.name)).map((item, index) => (
<option key={index} value={item.name}>
{item.name}
</option>
))}
</select>
</div>
))} */}
{/* <div>
<GrAdd onClick={addNewSelectedTag}/>
</div> */}
<Link to="#" className="submit" onClick={handleClose}>Cancel</Link>
</div>
</motion.div> </motion.div>
</Backdrop> </Backdrop>