Compare commits
65 Commits
Mqtt_Next_
...
master
Before Width: | Height: | Size: 366 KiB After Width: | Height: | Size: 368 KiB |
Before Width: | Height: | Size: 54 KiB |
After Width: | Height: | Size: 867 KiB |
Before Width: | Height: | Size: 729 KiB |
Before Width: | Height: | Size: 1.3 MiB |
Before Width: | Height: | Size: 2.6 MiB |
Before Width: | Height: | Size: 208 KiB |
Before Width: | Height: | Size: 1.1 MiB |
Before Width: | Height: | Size: 892 KiB |
Before Width: | Height: | Size: 1.3 MiB |
Before Width: | Height: | Size: 96 KiB |
Before Width: | Height: | Size: 1.6 MiB |
After Width: | Height: | Size: 247 KiB |
After Width: | Height: | Size: 26 KiB |
@ -1,15 +0,0 @@
|
|||||||
> Why do I have a folder named ".expo" in my project?
|
|
||||||
|
|
||||||
The ".expo" folder is created when an Expo project is started using "expo start" command.
|
|
||||||
|
|
||||||
> What do the files contain?
|
|
||||||
|
|
||||||
- "devices.json": contains information about devices that have recently opened this project. This is used to populate the "Development sessions" list in your development builds.
|
|
||||||
- "packager-info.json": contains port numbers and process PIDs that are used to serve the application to the mobile device/simulator.
|
|
||||||
- "settings.json": contains the server configuration that is used to serve the application manifest.
|
|
||||||
|
|
||||||
> Should I commit the ".expo" folder?
|
|
||||||
|
|
||||||
No, you should not share the ".expo" folder. It does not contain any information that is relevant for other developers working on the project, it is specific to your machine.
|
|
||||||
|
|
||||||
Upon project creation, the ".expo" folder is already added to your ".gitignore" file.
|
|
@ -1,8 +0,0 @@
|
|||||||
{
|
|
||||||
"hostType": "lan",
|
|
||||||
"lanType": "ip",
|
|
||||||
"dev": true,
|
|
||||||
"minify": false,
|
|
||||||
"urlRandomness": null,
|
|
||||||
"https": false
|
|
||||||
}
|
|
@ -1 +0,0 @@
|
|||||||
PORT=8080
|
|
@ -1,62 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
||||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
||||||
};
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
const express_1 = __importDefault(require("express"));
|
|
||||||
// import compression from 'compression';
|
|
||||||
const cors_1 = __importDefault(require("cors"));
|
|
||||||
// import ErrorMiddleware from './middleware/error.middleware';
|
|
||||||
const body_parser_1 = __importDefault(require("body-parser"));
|
|
||||||
const mongoose_1 = __importDefault(require("mongoose"));
|
|
||||||
const cookie_parser_1 = __importDefault(require("cookie-parser"));
|
|
||||||
class App {
|
|
||||||
constructor(controllers, port) {
|
|
||||||
this.express = (0, express_1.default)();
|
|
||||||
this.port = port;
|
|
||||||
this.dataBase = null;
|
|
||||||
this.initialiseDatabase();
|
|
||||||
this.initialiseMiddleware();
|
|
||||||
this.initialiseControllers(controllers);
|
|
||||||
// this.initialiseErrorHandling();
|
|
||||||
}
|
|
||||||
initialiseMiddleware() {
|
|
||||||
// this.express.use(helmet());
|
|
||||||
this.express.use((0, cors_1.default)());
|
|
||||||
this.express.use((0, cookie_parser_1.default)());
|
|
||||||
// this.express.use(morgan('dev'));
|
|
||||||
this.express.use(express_1.default.json());
|
|
||||||
this.express.use(express_1.default.urlencoded({ extended: false }));
|
|
||||||
// this.express.use(compression());
|
|
||||||
// mine
|
|
||||||
this.express.use(body_parser_1.default.json());
|
|
||||||
this.express.use(body_parser_1.default.urlencoded({
|
|
||||||
extended: true
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
initialiseControllers(controllers) {
|
|
||||||
controllers.forEach((controller) => {
|
|
||||||
this.express.use('/api', controller.router);
|
|
||||||
this.express.get('/toto', (req, res) => {
|
|
||||||
res.send('Hello World!');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
// private initialiseErrorHandling(): void {
|
|
||||||
// this.express.use(ErrorMiddleware);
|
|
||||||
// }
|
|
||||||
listen() {
|
|
||||||
const server = this.express.listen(this.port, () => {
|
|
||||||
console.log(`⚡️[server] : App listening on the port ${this.port}`);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
initialiseDatabase() {
|
|
||||||
const { MONGO_USER, MONGO_PASSWORD, MONGO_PATH } = process.env;
|
|
||||||
const uri = "mongodb+srv://fladDevDb:ZslYlNRWIOUU7i6o@fladcluster.b29tytu.mongodb.net/?retryWrites=true&w=majority";
|
|
||||||
mongoose_1.default.connect(uri)
|
|
||||||
.then(() => console.log("Connect to MongoDB database successfully"))
|
|
||||||
.catch(err => console.log("Error connecting : " + err));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
exports.default = App;
|
|
||||||
//# sourceMappingURL=app.js.map
|
|
@ -1 +0,0 @@
|
|||||||
{"version":3,"file":"app.js","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":";;;;;AAAA,sDAA+C;AAC/C,yCAAyC;AACzC,gDAAwB;AAIxB,+DAA+D;AAC/D,8DAAqC;AACrC,wDAAgC;AAMhC,kEAAyC;AAEzC,MAAM,GAAG;IAOL,YAAY,WAAyB,EAAE,IAAY;QAC/C,IAAI,CAAC,OAAO,GAAG,IAAA,iBAAO,GAAE,CAAC;QACzB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QAErB,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC1B,IAAI,CAAC,oBAAoB,EAAE,CAAC;QAC5B,IAAI,CAAC,qBAAqB,CAAC,WAAW,CAAC,CAAC;QAExC,kCAAkC;IACtC,CAAC;IAEO,oBAAoB;QACxB,8BAA8B;QAC9B,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAA,cAAI,GAAE,CAAC,CAAC;QACzB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAA,uBAAY,GAAE,CAAC,CAAC;QAGjC,mCAAmC;QACnC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAO,CAAC,IAAI,EAAE,CAAC,CAAC;QACjC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAO,CAAC,UAAU,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;QAC1D,mCAAmC;QACnC,OAAO;QACP,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,qBAAU,CAAC,IAAI,EAAE,CAAC,CAAC;QACpC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,qBAAU,CAAC,UAAU,CAAC;YACnC,QAAQ,EAAE,IAAI;SACf,CAAC,CAAC,CAAC;IAEV,CAAC;IAEO,qBAAqB,CAAC,WAAyB;QACnD,WAAW,CAAC,OAAO,CAAC,CAAC,UAAsB,EAAE,EAAE;YAC3C,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC;YAC5C,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;gBACnC,GAAG,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;YAC3B,CAAC,CAAC,CAAA;QACR,CAAC,CAAC,CAAC;IACP,CAAC;IAED,4CAA4C;IAC5C,yCAAyC;IACzC,IAAI;IAEG,MAAM;QACT,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,EAAE;YAC/C,OAAO,CAAC,GAAG,CAAC,0CAA0C,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QACvE,CAAC,CAAC,CAAC;IACP,CAAC;IAEO,kBAAkB;QACtB,MAAM,EAAE,UAAU,EAAE,cAAc,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC;QAC/D,MAAM,GAAG,GAAG,uGAAuG,CAAA;QACnH,kBAAQ,CAAC,OAAO,CAAC,GAAG,CAAC;aACpB,IAAI,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,0CAA0C,CAAC,CAAC;aACnE,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,qBAAqB,GAAE,GAAG,CAAE,CAAC,CAAC;IAC5D,CAAC;CAEJ;AAED,kBAAe,GAAG,CAAC"}
|
|
@ -1,3 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
//# sourceMappingURL=Icontroller.js.map
|
|
@ -1 +0,0 @@
|
|||||||
{"version":3,"file":"Icontroller.js","sourceRoot":"","sources":["../../src/controller/Icontroller.ts"],"names":[],"mappings":""}
|
|
@ -1,34 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
||||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
||||||
return new (P || (P = Promise))(function (resolve, reject) {
|
|
||||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
||||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
||||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
||||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
||||||
});
|
|
||||||
};
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
const express_1 = require("express");
|
|
||||||
class PingController {
|
|
||||||
constructor() {
|
|
||||||
this.path = '/ping';
|
|
||||||
this.router = (0, express_1.Router)();
|
|
||||||
this.initialiseRoutes();
|
|
||||||
}
|
|
||||||
initialiseRoutes() {
|
|
||||||
this.router.get("/ping", (_req, res) => __awaiter(this, void 0, void 0, function* () {
|
|
||||||
const response = yield this.getMessage();
|
|
||||||
return res.send(response);
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
getMessage() {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
return {
|
|
||||||
message: "pong",
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
exports.default = PingController;
|
|
||||||
//# sourceMappingURL=TestCtrl.js.map
|
|
@ -1 +0,0 @@
|
|||||||
{"version":3,"file":"TestCtrl.js","sourceRoot":"","sources":["../../src/controller/TestCtrl.ts"],"names":[],"mappings":";;;;;;;;;;;AAAA,qCAAiC;AAOjC,MAAqB,cAAc;IAI/B;QAHO,SAAI,GAAG,OAAO,CAAC;QACf,WAAM,GAAG,IAAA,gBAAM,GAAE,CAAC;QAGrB,IAAI,CAAC,gBAAgB,EAAE,CAAC;IAC5B,CAAC;IAEO,gBAAgB;QACpB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,CAAO,IAAI,EAAE,GAAG,EAAE,EAAE;YACzC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,UAAU,EAAE,CAAC;YACzC,OAAO,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC5B,CAAC,CAAA,CAAC,CAAC;IACT,CAAC;IACK,UAAU;;YACZ,OAAO;gBACP,OAAO,EAAE,MAAM;aACd,CAAC;QACN,CAAC;KAAA;CACJ;AAnBD,iCAmBC"}
|
|
@ -1,17 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
class CryptString {
|
|
||||||
constructor(length) {
|
|
||||||
this.stringCrypt = this.generateRandomString(length);
|
|
||||||
}
|
|
||||||
generateRandomString(length) {
|
|
||||||
var text = '';
|
|
||||||
var possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
|
||||||
for (var i = 0; i < length; i++) {
|
|
||||||
text += possible.charAt(Math.floor(Math.random() * possible.length));
|
|
||||||
}
|
|
||||||
return text;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
exports.default = CryptString;
|
|
||||||
//# sourceMappingURL=crypt.js.map
|
|
@ -1 +0,0 @@
|
|||||||
{"version":3,"file":"crypt.js","sourceRoot":"","sources":["../../../src/controller/spotify-controller/crypt.ts"],"names":[],"mappings":";;AAAA,MAAqB,WAAW;IAI5B,YAAY,MAAe;QACvB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC;IACzD,CAAC;IACD,oBAAoB,CAAE,MAAe;QACjC,IAAI,IAAI,GAAG,EAAE,CAAC;QACd,IAAI,QAAQ,GAAG,gEAAgE,CAAC;QAEhF,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,EAAE;YAC/B,IAAI,IAAI,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;SACtE;QACD,OAAO,IAAI,CAAC;IAChB,CAAC;CACJ;AAhBD,8BAgBC"}
|
|
@ -1,3 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
//# sourceMappingURL=authReqBody.js.map
|
|
@ -1 +0,0 @@
|
|||||||
{"version":3,"file":"authReqBody.js","sourceRoot":"","sources":["../../../../src/controller/spotify-controller/request/authReqBody.ts"],"names":[],"mappings":""}
|
|
@ -1,218 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
||||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
||||||
return new (P || (P = Promise))(function (resolve, reject) {
|
|
||||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
||||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
||||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
||||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
||||||
});
|
|
||||||
};
|
|
||||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
||||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
||||||
};
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
const express_1 = require("express");
|
|
||||||
const httpExeption_1 = __importDefault(require("../../middleware/exeption/httpExeption"));
|
|
||||||
const axios_1 = __importDefault(require("axios"));
|
|
||||||
const crypt_1 = __importDefault(require("./crypt"));
|
|
||||||
const qs_1 = __importDefault(require("qs"));
|
|
||||||
class SpotifyController {
|
|
||||||
constructor() {
|
|
||||||
this.path = '/spotify';
|
|
||||||
this.router = (0, express_1.Router)();
|
|
||||||
// need to put in ENvironement file
|
|
||||||
// private readonly CLIENT_CALLBACK_URL = "http://localhost:8080/callback";
|
|
||||||
this.API_URL = "https://accounts.spotify.com/api/token";
|
|
||||||
this.CLIENT_ID = "1f1e34e4b6ba48b388469dba80202b10";
|
|
||||||
this.CLIENT_SECRET = "779371c6d4994a68b8dd6e84b0873c82";
|
|
||||||
// private readonly CLIENT_CALLBACK_URL = "https://auth.expo.io/@thed47/FLAD//callback";
|
|
||||||
this.CALLBACK_2 = 'https://flad-api-production.up.railway.app/api/spotify/callback';
|
|
||||||
this.SCOPES = 'user-read-private user-read-email user-read-playback-state user-read-currently-playing user-read-recently-played playlist-modify-public ugc-image-upload user-modify-playback-state';
|
|
||||||
this.ENCRYPTION_SECRET = new crypt_1.default(16);
|
|
||||||
this.clientRedirect = 'spotify_final_redirect-uri-key';
|
|
||||||
this.login = (req, res, next) => __awaiter(this, void 0, void 0, function* () {
|
|
||||||
console.log("useeeee== login");
|
|
||||||
try {
|
|
||||||
// const params = req.body;
|
|
||||||
// if (!params.refresh_token) {
|
|
||||||
// return res.json({
|
|
||||||
// "error": "Parameter missing"
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
// this.spotifyRequest({
|
|
||||||
// grant_type: "authorization_code",
|
|
||||||
// redirect_uri: this.CLIENT_CALLBACK_2,
|
|
||||||
// // code: params.code
|
|
||||||
// })
|
|
||||||
const redirectResponse = req.query.redirectUrl ? req.query.redirectUrl : req.headers.referer;
|
|
||||||
res.cookie(this.clientRedirect, redirectResponse);
|
|
||||||
console.log("aloorrr si c'est niquuuuuuuuuuuueeee" + this.CALLBACK_2 + "gennnnnnnnnrree vraiiiiiiiment ");
|
|
||||||
res.redirect('https://accounts.spotify.com/authorize?' +
|
|
||||||
qs_1.default.stringify({
|
|
||||||
response_type: 'code',
|
|
||||||
client_id: this.CLIENT_ID,
|
|
||||||
scope: this.SCOPES,
|
|
||||||
redirect_uri: this.CALLBACK_2,
|
|
||||||
// state: this.ENCRYPTION_SECRET.stringCrypt
|
|
||||||
}));
|
|
||||||
// '?response_type=code' +
|
|
||||||
// '&client_id=' +
|
|
||||||
// "1f1e34e4b6ba48b388469dba80202b10" +
|
|
||||||
// (this.SCOPES ? '&scope=' + encodeURIComponent(this.SCOPES) : '') +
|
|
||||||
// '&redirect_uri=' +
|
|
||||||
// encodeURIComponent(this.CALLBACK_2)
|
|
||||||
// );
|
|
||||||
// .then(session => {
|
|
||||||
// let result = {
|
|
||||||
// "access_token": session.access_token,
|
|
||||||
// "expires_in": session.expires_in,
|
|
||||||
// "refresh_token": this.encrypt(session.refresh_token)
|
|
||||||
// };
|
|
||||||
// return res.send(result);
|
|
||||||
// })
|
|
||||||
// .catch(response => {
|
|
||||||
// return res.json(response);
|
|
||||||
// });
|
|
||||||
}
|
|
||||||
catch (error) {
|
|
||||||
next(new httpExeption_1.default(400, 'Cannot create spot'));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
this.getRefreshToken = (req, res, next) => __awaiter(this, void 0, void 0, function* () {
|
|
||||||
console.log('UUse2');
|
|
||||||
try {
|
|
||||||
const params = req.query.refresh_token;
|
|
||||||
if (!req.query.refresh_token) {
|
|
||||||
return res.json({
|
|
||||||
"error": "Parameter refresh_token missing"
|
|
||||||
});
|
|
||||||
}
|
|
||||||
var authOptions = {
|
|
||||||
method: 'POST',
|
|
||||||
url: 'https://accounts.spotify.com/api/token',
|
|
||||||
data: qs_1.default.stringify({
|
|
||||||
grant_type: 'refresh_token',
|
|
||||||
refresh_token: params
|
|
||||||
}),
|
|
||||||
headers: {
|
|
||||||
'Authorization': 'Basic ' + (Buffer.from(this.CLIENT_ID + ':' + this.CLIENT_SECRET).toString('base64')),
|
|
||||||
'Content-Type': 'application/x-www-form-urlencoded'
|
|
||||||
},
|
|
||||||
json: true
|
|
||||||
};
|
|
||||||
// request.post(authOptions, function(error, response, body) {
|
|
||||||
// if (!error && response.statusCode === 200) {
|
|
||||||
// var access_token = body.access_token;
|
|
||||||
// res.send({
|
|
||||||
// 'access_token': access_token
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
(0, axios_1.default)(authOptions)
|
|
||||||
.then(session => {
|
|
||||||
if (session.status === 200) {
|
|
||||||
console.log('### Information : responce ###' + JSON.stringify(session.data));
|
|
||||||
console.log('### Information : refresh_token ###' + session.data.refresh_token);
|
|
||||||
res.send({
|
|
||||||
"access_token": session.data.access_token,
|
|
||||||
"refresh_token": session.data.refresh_token,
|
|
||||||
"expires_in": session.data.expires_in
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
console.log("goood");
|
|
||||||
}
|
|
||||||
catch (error) {
|
|
||||||
console.log("errur");
|
|
||||||
next(new httpExeption_1.default(400, 'Cannot create post'));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
this.getSpot = (req, res, next) => __awaiter(this, void 0, void 0, function* () {
|
|
||||||
const spots = [
|
|
||||||
{
|
|
||||||
name: "blue",
|
|
||||||
sourceUrl: "https://cdns-images.dzcdn.net/images/artist/399e7e760d8fedf3cc2891e9c0c41658/200x200-000000-80-0-0.jpg",
|
|
||||||
index: 3
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "strange history",
|
|
||||||
sourceUrl: "https://images.genius.com/339dfe2a7c0adf9a5d08febf29a845f4.1000x1000x1.jpg",
|
|
||||||
index: 7
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "oboy album",
|
|
||||||
sourceUrl: "https://i.pinimg.com/originals/ad/cc/d5/adccd58a0d0ff516a6114703cd05810e.jpg",
|
|
||||||
index: 1
|
|
||||||
}
|
|
||||||
];
|
|
||||||
try {
|
|
||||||
res.send(spots);
|
|
||||||
}
|
|
||||||
catch (error) {
|
|
||||||
console.log('heuuuuuuuuuuuuuuuuuuuuubizzzaaarrreeee');
|
|
||||||
console.log(error);
|
|
||||||
next(new httpExeption_1.default(400, 'On peut pas avoir darray mec'));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
this.getAccessToken = (req, res, next) => __awaiter(this, void 0, void 0, function* () {
|
|
||||||
console.log("useeeee== accesToken");
|
|
||||||
var code = req.query.code;
|
|
||||||
var state = req.query.state || null;
|
|
||||||
var storedredirectUri = req.cookies ? req.cookies[this.clientRedirect] : null;
|
|
||||||
// var storedState = req.cookies ? req.cookies[stateKey] : null;
|
|
||||||
var authOptions = {
|
|
||||||
method: 'POST',
|
|
||||||
url: 'https://accounts.spotify.com/api/token',
|
|
||||||
data: qs_1.default.stringify({
|
|
||||||
code: code,
|
|
||||||
redirect_uri: this.CALLBACK_2,
|
|
||||||
grant_type: 'authorization_code'
|
|
||||||
}),
|
|
||||||
headers: {
|
|
||||||
'Authorization': 'Basic ' + (Buffer.from(this.CLIENT_ID + ':' + this.CLIENT_SECRET).toString('base64')),
|
|
||||||
'Content-Type': 'application/x-www-form-urlencoded'
|
|
||||||
},
|
|
||||||
json: true
|
|
||||||
};
|
|
||||||
try {
|
|
||||||
var resp = yield (0, axios_1.default)(authOptions);
|
|
||||||
if (resp.status === 200) {
|
|
||||||
console.log('oon esttt laaa');
|
|
||||||
var access_token = resp.data.access_token;
|
|
||||||
var expiration = resp.data.expires_in;
|
|
||||||
var refresh = resp.data.refresh_token;
|
|
||||||
console.log(access_token);
|
|
||||||
// res.send({
|
|
||||||
// "access_token": access_token,
|
|
||||||
// "expires_in": expiration,
|
|
||||||
// "refresh" : refresh
|
|
||||||
// });
|
|
||||||
res.clearCookie(this.clientRedirect);
|
|
||||||
res.redirect(`${storedredirectUri}?` +
|
|
||||||
qs_1.default.stringify({
|
|
||||||
"access_token": access_token,
|
|
||||||
"expires_in": expiration,
|
|
||||||
"refresh_token": refresh
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (error) {
|
|
||||||
console.log('heuuuuuuuuuuuuuuuuuuuuubizzzaaarrreeee');
|
|
||||||
console.log(error);
|
|
||||||
next(new httpExeption_1.default(400, 'On peut pas te connecter mec' + error.message));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
console.log("useeeee");
|
|
||||||
this.initialiseRoutes();
|
|
||||||
}
|
|
||||||
initialiseRoutes() {
|
|
||||||
// this.router.post(`${this.path}`,this.createTask);
|
|
||||||
this.router.get(`${this.path}/exchange`, this.login);
|
|
||||||
this.router.get(`${this.path}/callback`, this.getAccessToken);
|
|
||||||
this.router.get(`${this.path}/refresh`, this.getRefreshToken);
|
|
||||||
this.router.get(`${this.path}/spot`, this.getSpot);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
exports.default = SpotifyController;
|
|
||||||
//# sourceMappingURL=spotifyCtrl.js.map
|
|
@ -1,193 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
||||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
||||||
return new (P || (P = Promise))(function (resolve, reject) {
|
|
||||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
||||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
||||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
||||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
||||||
});
|
|
||||||
};
|
|
||||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
||||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
||||||
};
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
const express_1 = require("express");
|
|
||||||
const httpExeption_1 = __importDefault(require("../../middleware/exeption/httpExeption"));
|
|
||||||
const UserService_1 = __importDefault(require("../../service/UserService"));
|
|
||||||
const UserValidation_1 = __importDefault(require("../../database/schema/User/UserValidation"));
|
|
||||||
const ValidatorMiddleware_1 = __importDefault(require("../../middleware/validation/ValidatorMiddleware"));
|
|
||||||
const authMiddleware_1 = __importDefault(require("../../middleware/authMiddleware"));
|
|
||||||
const LocationService_1 = __importDefault(require("../../service/LocationService"));
|
|
||||||
class UserController {
|
|
||||||
constructor() {
|
|
||||||
this.path = '/users';
|
|
||||||
this.router = (0, express_1.Router)();
|
|
||||||
this.userService = new UserService_1.default();
|
|
||||||
this.locationService = new LocationService_1.default();
|
|
||||||
// private createUser = async (
|
|
||||||
// req: Request,
|
|
||||||
// res: Response,
|
|
||||||
// next: NextFunction
|
|
||||||
// ): Promise<Response | void> => {
|
|
||||||
// try {
|
|
||||||
// console.log(req.body);
|
|
||||||
// const reqBody:CreateTaskReqBody = Object.assign({}, req.body);
|
|
||||||
// checkIfIsValidCreateTaskReqBody(reqBody);
|
|
||||||
// await this.userService.createUserById(reqBody.fin
|
|
||||||
// );
|
|
||||||
// res.status(200).send({ status: "Success", msg: "Success add" });
|
|
||||||
// } catch (error) {
|
|
||||||
// next(new HttpException(400, 'Cannot create post'));
|
|
||||||
// }
|
|
||||||
// };
|
|
||||||
// private readonly getUserById: RequestHandler = async (
|
|
||||||
// req: Request,
|
|
||||||
// res: Response,
|
|
||||||
// next: NextFunction
|
|
||||||
// ): Promise<Response | void> => {
|
|
||||||
// try {
|
|
||||||
// const id = req.params.taskId;
|
|
||||||
// const userId = req.params.userId;
|
|
||||||
// const data = await this.userService.getUserById(id, userId);
|
|
||||||
// res.status(201).send(data);
|
|
||||||
// }
|
|
||||||
// catch(error){
|
|
||||||
// next(new HttpException(400, 'Cannot create post'));
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// private readonly getAllUsers: RequestHandler = async (
|
|
||||||
// req: Request,
|
|
||||||
// res: Response,
|
|
||||||
// next: NextFunction
|
|
||||||
// ): Promise<Response | void> => {
|
|
||||||
// try {
|
|
||||||
// const userId = req.params.userId;
|
|
||||||
// const tasks = await this.userService.getUsers(userId);
|
|
||||||
// const responseList = tasks.map(task => new TaskResumedRes(task));
|
|
||||||
// res.status(201).send(responseList);
|
|
||||||
// }
|
|
||||||
// catch(error){
|
|
||||||
// next(new HttpException(400, 'Cannot get user task'));
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// private deleteUser = async (
|
|
||||||
// req: Request,
|
|
||||||
// res: Response,
|
|
||||||
// next: NextFunction
|
|
||||||
// ): Promise<Response | void> => {
|
|
||||||
// try {
|
|
||||||
// const id = req.params.taskId;
|
|
||||||
// const userId = req.params.userId;
|
|
||||||
// await this.userService.DeleteUser(id, userId);
|
|
||||||
// return res.status(200).send({ status: "Success", msg: "Data Removed" });
|
|
||||||
// } catch (error) {
|
|
||||||
// next(new HttpException(400, 'Cannot create post'));
|
|
||||||
// }
|
|
||||||
// };
|
|
||||||
// private updateUser = async (
|
|
||||||
// req: Request,
|
|
||||||
// res: Response,
|
|
||||||
// next: NextFunction
|
|
||||||
// ): Promise<Response | void> => {
|
|
||||||
// try {
|
|
||||||
// const taskId = req.params.taskId;
|
|
||||||
// const userId = req.params.userId;
|
|
||||||
// const reqBody:CreateTaskReqBody = Object.assign({}, req.body);
|
|
||||||
// const updatedTask = await this.userService.UpdateTask(
|
|
||||||
// // req.auth!.uid,
|
|
||||||
// taskId,
|
|
||||||
// userId,
|
|
||||||
// // firebase.auth().currentUser.getIdToken()
|
|
||||||
// reqBody.nom,
|
|
||||||
// reqBody.description,
|
|
||||||
// reqBody.logo,
|
|
||||||
// reqBody.duration,
|
|
||||||
// reqBody.done,
|
|
||||||
// // reqBody.tags,
|
|
||||||
// reqBody.repepat,
|
|
||||||
// reqBody.deb,
|
|
||||||
// reqBody.fin
|
|
||||||
// );
|
|
||||||
// // res.send('Success add');
|
|
||||||
// // res.status(201).json({ task });
|
|
||||||
// res.status(204).send(`Update a new contact: ${updatedTask}`);
|
|
||||||
// } catch (error) {
|
|
||||||
// console.log(error);
|
|
||||||
// next(new HttpException(403, 'Cannot create post'));
|
|
||||||
// }
|
|
||||||
// };
|
|
||||||
this.register = (req, res, next) => __awaiter(this, void 0, void 0, function* () {
|
|
||||||
try {
|
|
||||||
// the FladId should be created by the Userservice
|
|
||||||
const { name, email, password, idFlad, idSpotify } = req.body;
|
|
||||||
console.log(name, email, password, idFlad, idSpotify);
|
|
||||||
const token = yield this.userService.register(name, email, password, idFlad, idSpotify);
|
|
||||||
res.status(201).json({ token });
|
|
||||||
}
|
|
||||||
catch (error) {
|
|
||||||
next(new httpExeption_1.default(400, error.message));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
this.login = (req, res, next) => __awaiter(this, void 0, void 0, function* () {
|
|
||||||
try {
|
|
||||||
const { email, password } = req.body;
|
|
||||||
const token = yield this.userService.login(email, password);
|
|
||||||
res.status(200).json({ token });
|
|
||||||
}
|
|
||||||
catch (error) {
|
|
||||||
next(new httpExeption_1.default(400, error.message));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
this.getUser = (req, res, next) => {
|
|
||||||
if (!req.user) {
|
|
||||||
return next(new httpExeption_1.default(404, 'No logged in user'));
|
|
||||||
}
|
|
||||||
res.status(200).send({ data: req.user });
|
|
||||||
};
|
|
||||||
this.getUserNext = (req, res, next) => __awaiter(this, void 0, void 0, function* () {
|
|
||||||
try {
|
|
||||||
const longitude = Number(req.query.longitude);
|
|
||||||
const latitude = Number(req.query.latitude);
|
|
||||||
//verify::val_int(){
|
|
||||||
console.log('woooooooooooooo' + req);
|
|
||||||
if (isNaN(longitude) || isNaN(latitude)) {
|
|
||||||
console.log('============' + longitude);
|
|
||||||
console.log('============' + latitude);
|
|
||||||
console.log('Impossible de convertir la chaîne en nombre');
|
|
||||||
}
|
|
||||||
//}
|
|
||||||
const userId = req.user.idFlad;
|
|
||||||
const musicId = String(req.query.currentMusic);
|
|
||||||
console.log('============' + longitude);
|
|
||||||
console.log('============' + latitude);
|
|
||||||
console.log('daaaaaaaaaaaaaaaaaaaaaa' + musicId);
|
|
||||||
const data = yield this.locationService.getNearUser(userId, musicId, latitude, longitude);
|
|
||||||
console.log(data);
|
|
||||||
res.status(201).send(data);
|
|
||||||
}
|
|
||||||
catch (error) {
|
|
||||||
next(new httpExeption_1.default(400, 'Cannot create get netUser'));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
this.initialiseRoutes();
|
|
||||||
}
|
|
||||||
initialiseRoutes() {
|
|
||||||
this.router.post(`${this.path}/register`, (0, ValidatorMiddleware_1.default)(UserValidation_1.default.register), this.register);
|
|
||||||
this.router.post(`${this.path}/login`, (0, ValidatorMiddleware_1.default)(UserValidation_1.default.login), this.login);
|
|
||||||
this.router.get(`${this.path}`, authMiddleware_1.default, this.getUser);
|
|
||||||
this.router.get(`${this.path}/nextTo`, authMiddleware_1.default, this.getUserNext);
|
|
||||||
// //create
|
|
||||||
// this.router.post(`${this.path}`,this.createUser);
|
|
||||||
// // // get One
|
|
||||||
// this.router.get (`${this.path}/:userId`, this.getUserById);
|
|
||||||
// // // get All
|
|
||||||
// this.router.get (`${this.path}`, this.getAllUsers);
|
|
||||||
// //update One
|
|
||||||
// this.router.put (`${this.path}/:userId`, this.updateUser);
|
|
||||||
// //Delete One
|
|
||||||
// this.router.delete (`${this.path}/:userId`, this.deleteUser);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
exports.default = UserController;
|
|
||||||
//# sourceMappingURL=userCtrl.js.map
|
|
@ -1 +0,0 @@
|
|||||||
{"version":3,"file":"userCtrl.js","sourceRoot":"","sources":["../../../src/controller/user-controller/userCtrl.ts"],"names":[],"mappings":"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"}
|
|
@ -1,2 +0,0 @@
|
|||||||
// export default db = new MongoClient(uri);
|
|
||||||
//# sourceMappingURL=MongoDataBase.js.map
|
|
@ -1 +0,0 @@
|
|||||||
{"version":3,"file":"MongoDataBase.js","sourceRoot":"","sources":["../../src/database/MongoDataBase.ts"],"names":[],"mappings":"AACA,4CAA4C"}
|
|
@ -1 +0,0 @@
|
|||||||
//# sourceMappingURL=StrategyDatabase.js.map
|
|
@ -1 +0,0 @@
|
|||||||
{"version":3,"file":"StrategyDatabase.js","sourceRoot":"","sources":["../../src/database/StrategyDatabase.ts"],"names":[],"mappings":""}
|
|
@ -1,26 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
const mongoose_1 = require("mongoose");
|
|
||||||
const locationSchema = new mongoose_1.Schema({
|
|
||||||
idFlad: {
|
|
||||||
type: String,
|
|
||||||
required: true,
|
|
||||||
unique: true,
|
|
||||||
},
|
|
||||||
musicId: {
|
|
||||||
type: String,
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
latitude: {
|
|
||||||
type: Number,
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
longitude: {
|
|
||||||
type: Number,
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
}, { timestamps: true });
|
|
||||||
// fladDevDb
|
|
||||||
// ZslYlNRWIOUU7i6o
|
|
||||||
exports.default = (0, mongoose_1.model)('Location', locationSchema);
|
|
||||||
//# sourceMappingURL=LocationSchema.js.map
|
|
@ -1 +0,0 @@
|
|||||||
{"version":3,"file":"LocationSchema.js","sourceRoot":"","sources":["../../../src/database/schema/LocationSchema.ts"],"names":[],"mappings":";;AAAA,uCAAkD;AAGlD,MAAM,cAAc,GAAG,IAAI,iBAAM,CAC7B;IAEI,MAAM,EAAE;QACJ,IAAI,EAAE,MAAM;QACZ,QAAQ,EAAE,IAAI;QACd,MAAM,EAAE,IAAI;KACf;IACD,OAAO,EAAE;QACL,IAAI,EAAE,MAAM;QACZ,QAAQ,EAAE,IAAI;KACjB;IACD,QAAQ,EAAE;QACN,IAAI,EAAE,MAAM;QACZ,QAAQ,EAAE,IAAI;KACjB;IACD,SAAS,EAAE;QACP,IAAI,EAAE,MAAM;QACZ,QAAQ,EAAE,IAAI;KACjB;CAGJ,EACD,EAAE,UAAU,EAAE,IAAI,EAAE,CACvB,CAAC;AAEF,YAAY;AACZ,mBAAmB;AACnB,kBAAe,IAAA,gBAAK,EAAY,UAAU,EAAE,cAAc,CAAC,CAAC"}
|
|
@ -1,9 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
const mongoose_1 = require("mongoose");
|
|
||||||
const notificationSchema = new mongoose_1.Schema({
|
|
||||||
type: { type: String, required: true },
|
|
||||||
content: { type: String, required: true }
|
|
||||||
});
|
|
||||||
exports.default = { Notification: (0, mongoose_1.model)("nofitication", notificationSchema) };
|
|
||||||
//# sourceMappingURL=NotificationSchema.js.map
|
|
@ -1 +0,0 @@
|
|||||||
{"version":3,"file":"NotificationSchema.js","sourceRoot":"","sources":["../../../src/database/schema/NotificationSchema.ts"],"names":[],"mappings":";;AAAA,uCAAyC;AAEzC,MAAM,kBAAkB,GAAG,IAAI,iBAAM,CAAC;IAClC,IAAI,EAAE,EAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAC;IACpC,OAAO,EAAE,EAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAC;CAC1C,CAAC,CAAC;AAEH,kBAAe,EAAC,YAAY,EAAE,IAAA,gBAAK,EAAC,cAAc,EAAE,kBAAkB,CAAC,EAAC,CAAA"}
|
|
@ -1,3 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
//# sourceMappingURL=IToken.js.map
|
|
@ -1 +0,0 @@
|
|||||||
{"version":3,"file":"IToken.js","sourceRoot":"","sources":["../../../../src/database/schema/Token/IToken.ts"],"names":[],"mappings":""}
|
|
@ -1,3 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
//# sourceMappingURL=UserInterface.js.map
|
|
@ -1 +0,0 @@
|
|||||||
{"version":3,"file":"UserInterface.js","sourceRoot":"","sources":["../../../../src/database/schema/User/UserInterface.ts"],"names":[],"mappings":""}
|
|
@ -1,82 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
||||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
||||||
return new (P || (P = Promise))(function (resolve, reject) {
|
|
||||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
||||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
||||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
||||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
||||||
});
|
|
||||||
};
|
|
||||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
||||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
||||||
};
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
const mongoose_1 = require("mongoose");
|
|
||||||
const bcrypt_1 = __importDefault(require("bcrypt"));
|
|
||||||
// const userSchema: Schema = new Schema<IUser>({
|
|
||||||
// pseudo: {type: String, index: { unique: true }},
|
|
||||||
// email: {type: String},
|
|
||||||
// idDafl: {type: String, index: { unique: true }},
|
|
||||||
// idSpotify: {type: String},
|
|
||||||
// password: {type: String},
|
|
||||||
// prenom: {type: String, default: ""},
|
|
||||||
// description: {type: String, default: ""},
|
|
||||||
// nom: {type: String, default: ""},
|
|
||||||
// ville: {type: String, default: ""},
|
|
||||||
// profilPic: {type: String},
|
|
||||||
// noteList: [],
|
|
||||||
// notifications: [],
|
|
||||||
// friends: {type: [String] },
|
|
||||||
// favoris: [],
|
|
||||||
// conversations: {type: [String] }
|
|
||||||
// });
|
|
||||||
const userSchema = new mongoose_1.Schema({
|
|
||||||
idFlad: {
|
|
||||||
type: String,
|
|
||||||
required: true,
|
|
||||||
unique: true,
|
|
||||||
},
|
|
||||||
idSpotify: {
|
|
||||||
type: String,
|
|
||||||
required: true,
|
|
||||||
unique: true,
|
|
||||||
},
|
|
||||||
name: {
|
|
||||||
type: String,
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
email: {
|
|
||||||
type: String,
|
|
||||||
required: true,
|
|
||||||
// this mean that we identify user by email
|
|
||||||
unique: true,
|
|
||||||
// delete the whitespace
|
|
||||||
trim: true,
|
|
||||||
},
|
|
||||||
password: {
|
|
||||||
type: String,
|
|
||||||
},
|
|
||||||
}, { timestamps: true });
|
|
||||||
// this means that we hash the user password before saving it to the database
|
|
||||||
userSchema.pre('save', function (next) {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
if (!this.isModified('password')) {
|
|
||||||
//just had that to be sure that the api still going
|
|
||||||
return next();
|
|
||||||
}
|
|
||||||
const hash = yield bcrypt_1.default.hash(this.password, 8);
|
|
||||||
this.password = hash;
|
|
||||||
next();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
userSchema.methods.isValidPassword = function (password) {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
return yield bcrypt_1.default.compare(password, this.password);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
// fladDevDb
|
|
||||||
// ZslYlNRWIOUU7i6o
|
|
||||||
exports.default = (0, mongoose_1.model)('User', userSchema);
|
|
||||||
// export const User: Model<IUser> = model('User', userSchema);
|
|
||||||
//# sourceMappingURL=UserSchema.js.map
|
|
@ -1 +0,0 @@
|
|||||||
{"version":3,"file":"UserSchema.js","sourceRoot":"","sources":["../../../../src/database/schema/User/UserSchema.ts"],"names":[],"mappings":";;;;;;;;;;;;;;AAEA,uCAAyC;AACzC,oDAA4B;AAC5B,iDAAiD;AACjD,uDAAuD;AACvD,6BAA6B;AAC7B,uDAAuD;AACvD,iCAAiC;AACjC,gCAAgC;AAChC,2CAA2C;AAC3C,gDAAgD;AAChD,wCAAwC;AACxC,0CAA0C;AAC1C,iCAAiC;AACjC,oBAAoB;AACpB,yBAAyB;AACzB,kCAAkC;AAClC,mBAAmB;AACnB,uCAAuC;AACvC,MAAM;AAEN,MAAM,UAAU,GAAG,IAAI,iBAAM,CACzB;IAEI,MAAM,EAAE;QACJ,IAAI,EAAE,MAAM;QACZ,QAAQ,EAAE,IAAI;QACd,MAAM,EAAE,IAAI;KACf;IACD,SAAS,EAAE;QACP,IAAI,EAAE,MAAM;QACZ,QAAQ,EAAE,IAAI;QACd,MAAM,EAAE,IAAI;KACf;IACD,IAAI,EAAE;QACF,IAAI,EAAE,MAAM;QACZ,QAAQ,EAAE,IAAI;KACjB;IACD,KAAK,EAAE;QACH,IAAI,EAAE,MAAM;QACZ,QAAQ,EAAE,IAAI;QACd,2CAA2C;QAC3C,MAAM,EAAE,IAAI;QACZ,wBAAwB;QACxB,IAAI,EAAE,IAAI;KACb;IACD,QAAQ,EAAE;QACN,IAAI,EAAE,MAAM;KACf;CAEJ,EACD,EAAE,UAAU,EAAE,IAAI,EAAE,CACvB,CAAC;AAEF,6EAA6E;AAC7E,UAAU,CAAC,GAAG,CAAQ,MAAM,EAAE,UAAgB,IAAI;;QAC9C,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE;YAC9B,mDAAmD;YACnD,OAAO,IAAI,EAAE,CAAC;SACjB;QAED,MAAM,IAAI,GAAG,MAAM,gBAAM,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;QAEjD,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QAErB,IAAI,EAAE,CAAC;IACX,CAAC;CAAA,CAAC,CAAC;AAEH,UAAU,CAAC,OAAO,CAAC,eAAe,GAAG,UACjC,QAAgB;;QAEhB,OAAO,MAAM,gBAAM,CAAC,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;IACzD,CAAC;CAAA,CAAC;AAEF,YAAY;AACZ,mBAAmB;AACnB,kBAAe,IAAA,gBAAK,EAAQ,MAAM,EAAE,UAAU,CAAC,CAAC;AAChD,+DAA+D"}
|
|
@ -1,20 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
||||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
||||||
};
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
const joi_1 = __importDefault(require("joi"));
|
|
||||||
const register = joi_1.default.object({
|
|
||||||
name: joi_1.default.string().max(30).required(),
|
|
||||||
email: joi_1.default.string().email().required(),
|
|
||||||
password: joi_1.default.string().min(6).required(),
|
|
||||||
// can add an field like confimPassword and cheked that the password is equal to the confirmPassword
|
|
||||||
idSpotify: joi_1.default.string(),
|
|
||||||
idFlad: joi_1.default.string(),
|
|
||||||
});
|
|
||||||
const login = joi_1.default.object({
|
|
||||||
email: joi_1.default.string().email().required(),
|
|
||||||
password: joi_1.default.string().required(),
|
|
||||||
});
|
|
||||||
exports.default = { register, login };
|
|
||||||
//# sourceMappingURL=UserValidation.js.map
|
|
@ -1 +0,0 @@
|
|||||||
{"version":3,"file":"UserValidation.js","sourceRoot":"","sources":["../../../../src/database/schema/User/UserValidation.ts"],"names":[],"mappings":";;;;;AAAA,8CAAsB;AAEtB,MAAM,QAAQ,GAAG,aAAG,CAAC,MAAM,CAAC;IACxB,IAAI,EAAE,aAAG,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE;IAErC,KAAK,EAAE,aAAG,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC,QAAQ,EAAE;IAEtC,QAAQ,EAAE,aAAG,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;IACxC,oGAAoG;IACpG,SAAS,EAAE,aAAG,CAAC,MAAM,EAAE;IACvB,MAAM,EAAG,aAAG,CAAC,MAAM,EAAE;CACxB,CAAC,CAAC;AAEH,MAAM,KAAK,GAAG,aAAG,CAAC,MAAM,CAAC;IACrB,KAAK,EAAE,aAAG,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC,QAAQ,EAAE;IACtC,QAAQ,EAAE,aAAG,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CACpC,CAAC,CAAC;AAEH,kBAAe,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC"}
|
|
@ -1,14 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
||||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
||||||
};
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
const app_1 = __importDefault(require("./app"));
|
|
||||||
const spotifyCtrl_1 = __importDefault(require("./controller/spotify-controller/spotifyCtrl"));
|
|
||||||
const TestCtrl_1 = __importDefault(require("./controller/TestCtrl"));
|
|
||||||
const userCtrl_1 = __importDefault(require("./controller/user-controller/userCtrl"));
|
|
||||||
const dotenv_1 = __importDefault(require("dotenv"));
|
|
||||||
dotenv_1.default.config();
|
|
||||||
const app = new app_1.default([new TestCtrl_1.default(), new spotifyCtrl_1.default(), new userCtrl_1.default()], Number(process.env.PORT));
|
|
||||||
app.listen();
|
|
||||||
//# sourceMappingURL=index.js.map
|
|
@ -1 +0,0 @@
|
|||||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;AAAA,gDAAwB;AACxB,8FAA4E;AAC5E,qEAAmD;AACnD,qFAAmE;AACnE,oDAA2B;AAC3B,gBAAM,CAAC,MAAM,EAAE,CAAC;AAChB,MAAM,GAAG,GAAG,IAAI,aAAG,CACf,CAAC,IAAI,kBAAc,EAAE,EAAE,IAAI,qBAAiB,EAAE,EAAE,IAAI,kBAAc,EAAE,CAAC,EACrE,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAE3B,CAAC;AAEF,GAAG,CAAC,MAAM,EAAE,CAAC"}
|
|
@ -1,46 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
||||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
||||||
return new (P || (P = Promise))(function (resolve, reject) {
|
|
||||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
||||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
||||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
||||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
||||||
});
|
|
||||||
};
|
|
||||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
||||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
||||||
};
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
const jsonwebtoken_1 = __importDefault(require("jsonwebtoken"));
|
|
||||||
const UserSchema_1 = __importDefault(require("../database/schema/User/UserSchema"));
|
|
||||||
const token_1 = __importDefault(require("../model/token"));
|
|
||||||
const httpExeption_1 = __importDefault(require("./exeption/httpExeption"));
|
|
||||||
function authenticatedMiddleware(req, res, next) {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
const bearer = req.headers.authorization;
|
|
||||||
if (!bearer || !bearer.startsWith('Bearer ')) {
|
|
||||||
return next(new httpExeption_1.default(401, 'Unauthorised'));
|
|
||||||
}
|
|
||||||
const accessToken = bearer.split('Bearer ')[1].trim();
|
|
||||||
try {
|
|
||||||
const payload = yield token_1.default.verifyToken(accessToken);
|
|
||||||
if (payload instanceof jsonwebtoken_1.default.JsonWebTokenError) {
|
|
||||||
return next(new httpExeption_1.default(401, 'Unauthorised'));
|
|
||||||
}
|
|
||||||
const user = yield UserSchema_1.default.findById(payload.id)
|
|
||||||
.select('-password')
|
|
||||||
.exec();
|
|
||||||
if (!user) {
|
|
||||||
return next(new httpExeption_1.default(401, 'Unauthorised'));
|
|
||||||
}
|
|
||||||
req.user = user;
|
|
||||||
return next();
|
|
||||||
}
|
|
||||||
catch (error) {
|
|
||||||
return next(new httpExeption_1.default(401, 'Unauthorised'));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
exports.default = authenticatedMiddleware;
|
|
||||||
//# sourceMappingURL=authMiddleware.js.map
|
|
@ -1 +0,0 @@
|
|||||||
{"version":3,"file":"authMiddleware.js","sourceRoot":"","sources":["../../src/middleware/authMiddleware.ts"],"names":[],"mappings":";;;;;;;;;;;;;;AACA,gEAA+B;AAE/B,oFAA4D;AAC5D,2DAAmC;AACnC,2EAAoD;AAEpD,SAAe,uBAAuB,CAClC,GAAY,EACZ,GAAa,EACb,IAAkB;;QAElB,MAAM,MAAM,GAAG,GAAG,CAAC,OAAO,CAAC,aAAa,CAAC;QAEzC,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE;YAC1C,OAAO,IAAI,CAAC,IAAI,sBAAa,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC,CAAC;SACvD;QAED,MAAM,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACtD,IAAI;YACA,MAAM,OAAO,GAAmC,MAAM,eAAK,CAAC,WAAW,CACnE,WAAW,CACd,CAAC;YAEF,IAAI,OAAO,YAAY,sBAAG,CAAC,iBAAiB,EAAE;gBAC1C,OAAO,IAAI,CAAC,IAAI,sBAAa,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC,CAAC;aACvD;YAED,MAAM,IAAI,GAAG,MAAM,oBAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;iBAC7C,MAAM,CAAC,WAAW,CAAC;iBACnB,IAAI,EAAE,CAAC;YAEZ,IAAI,CAAC,IAAI,EAAE;gBACP,OAAO,IAAI,CAAC,IAAI,sBAAa,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC,CAAC;aACvD;YAED,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC;YAEhB,OAAO,IAAI,EAAE,CAAC;SACjB;QAAC,OAAO,KAAK,EAAE;YACZ,OAAO,IAAI,CAAC,IAAI,sBAAa,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC,CAAC;SACvD;IACL,CAAC;CAAA;AAED,kBAAe,uBAAuB,CAAC"}
|
|
@ -1,12 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
class HttpException extends Error {
|
|
||||||
constructor(status, message) {
|
|
||||||
super(message);
|
|
||||||
this.status = status;
|
|
||||||
this.message = message;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// en fontion de l'exeption firebas,etc une bonne exeption
|
|
||||||
exports.default = HttpException;
|
|
||||||
//# sourceMappingURL=httpExeption.js.map
|
|
@ -1 +0,0 @@
|
|||||||
{"version":3,"file":"httpExeption.js","sourceRoot":"","sources":["../../../src/middleware/exeption/httpExeption.ts"],"names":[],"mappings":";;AAAA,MAAM,aAAc,SAAQ,KAAK;IAI7B,YAAY,MAAc,EAAE,OAAe;QACvC,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IAC3B,CAAC;CACJ;AACD,0DAA0D;AAE1D,kBAAe,aAAa,CAAC"}
|
|
@ -1,34 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
||||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
||||||
return new (P || (P = Promise))(function (resolve, reject) {
|
|
||||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
||||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
||||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
||||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
||||||
});
|
|
||||||
};
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
function validationMiddleware(schema) {
|
|
||||||
return (req, res, next) => __awaiter(this, void 0, void 0, function* () {
|
|
||||||
const validationOptions = {
|
|
||||||
abortEarly: false,
|
|
||||||
allowUnknown: true,
|
|
||||||
stripUnknown: true,
|
|
||||||
};
|
|
||||||
try {
|
|
||||||
const value = yield schema.validateAsync(req.body, validationOptions);
|
|
||||||
req.body = value;
|
|
||||||
next();
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
const errors = [];
|
|
||||||
e.details.forEach((error) => {
|
|
||||||
errors.push(error.message);
|
|
||||||
});
|
|
||||||
res.status(400).send({ errors: errors });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
exports.default = validationMiddleware;
|
|
||||||
//# sourceMappingURL=ValidatorMiddleware.js.map
|
|
@ -1 +0,0 @@
|
|||||||
{"version":3,"file":"ValidatorMiddleware.js","sourceRoot":"","sources":["../../../src/middleware/validation/ValidatorMiddleware.ts"],"names":[],"mappings":";;;;;;;;;;;AAGA,SAAS,oBAAoB,CAAC,MAAkB;IAC5C,OAAO,CACH,GAAY,EACZ,GAAa,EACb,IAAkB,EACL,EAAE;QACf,MAAM,iBAAiB,GAAG;YACtB,UAAU,EAAE,KAAK;YACjB,YAAY,EAAE,IAAI;YAClB,YAAY,EAAE,IAAI;SACrB,CAAC;QAEF,IAAI;YACA,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC,aAAa,CACpC,GAAG,CAAC,IAAI,EACR,iBAAiB,CACpB,CAAC;YACF,GAAG,CAAC,IAAI,GAAG,KAAK,CAAC;YACjB,IAAI,EAAE,CAAC;SACV;QAAC,OAAO,CAAM,EAAE;YACb,MAAM,MAAM,GAAa,EAAE,CAAC;YAC5B,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,KAA8B,EAAE,EAAE;gBACjD,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YAC/B,CAAC,CAAC,CAAC;YACH,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;SAC5C;IACL,CAAC,CAAA,CAAC;AACN,CAAC;AAED,kBAAe,oBAAoB,CAAC"}
|
|
@ -1,9 +0,0 @@
|
|||||||
// export const loggerOptions: expressWinston.LoggerOptions = {
|
|
||||||
// transports: [new winston.transports.Console()],
|
|
||||||
// format: winston.format.combine(
|
|
||||||
// winston.format.json(),
|
|
||||||
// winston.format.prettyPrint(),
|
|
||||||
// winston.format.colorize({ all: true })
|
|
||||||
// ),
|
|
||||||
// };
|
|
||||||
//# sourceMappingURL=winston.js.map
|
|
@ -1 +0,0 @@
|
|||||||
{"version":3,"file":"winston.js","sourceRoot":"","sources":["../../src/middleware/winston.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,sDAAsD;AACtD,sCAAsC;AACtC,iCAAiC;AACjC,wCAAwC;AACxC,iDAAiD;AACjD,SAAS;AACT,KAAK"}
|
|
@ -1,3 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
//# sourceMappingURL=IUser.js.map
|
|
@ -1 +0,0 @@
|
|||||||
{"version":3,"file":"IUser.js","sourceRoot":"","sources":["../../src/model/IUser.ts"],"names":[],"mappings":""}
|
|
@ -1,27 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
exports.Place = exports.UserLocation = exports.PlacePosition = void 0;
|
|
||||||
class PlacePosition {
|
|
||||||
constructor(timestamp, latitude, longitude) {
|
|
||||||
this.timestamp = timestamp;
|
|
||||||
this.coords = { latitude, longitude };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
exports.PlacePosition = PlacePosition;
|
|
||||||
class UserLocation {
|
|
||||||
constructor(uuid, musicId, latitude, longitude) {
|
|
||||||
this.uuid = uuid;
|
|
||||||
this.musicId = musicId;
|
|
||||||
this.latitude = latitude;
|
|
||||||
this.longitude = longitude;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
exports.UserLocation = UserLocation;
|
|
||||||
class Place {
|
|
||||||
constructor(address, position) {
|
|
||||||
this.position = position;
|
|
||||||
this.address = address;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
exports.Place = Place;
|
|
||||||
//# sourceMappingURL=locationModel.js.map
|
|
@ -1 +0,0 @@
|
|||||||
{"version":3,"file":"locationModel.js","sourceRoot":"","sources":["../../src/model/locationModel.ts"],"names":[],"mappings":";;;AAmBA,MAAa,aAAa;IAMtB,YAAY,SAAiB,EAAC,QAAiB,EAAE,SAAiB;QAC9D,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,MAAM,GAAG,EAAC,QAAQ,EAAE,SAAS,EAAC,CAAC;IACxC,CAAC;CACJ;AAVD,sCAUC;AACD,MAAa,YAAY;IAKrB,YAAY,IAAY,EAAE,OAAgB,EAAC,QAAgB,EAAE,SAAiB;QAC1E,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC/B,CAAC;CACJ;AAXD,oCAWC;AAED,MAAa,KAAK;IAGlB,YAAY,OAAgB,EAAC,QAAkB;QAC3C,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IAC3B,CAAC;CACA;AAPD,sBAOC"}
|
|
@ -1,34 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
||||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
||||||
return new (P || (P = Promise))(function (resolve, reject) {
|
|
||||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
||||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
||||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
||||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
||||||
});
|
|
||||||
};
|
|
||||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
||||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
||||||
};
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
exports.verifyToken = exports.createToken = void 0;
|
|
||||||
const jsonwebtoken_1 = __importDefault(require("jsonwebtoken"));
|
|
||||||
const createToken = (user) => {
|
|
||||||
return jsonwebtoken_1.default.sign({ id: user._id }, "foo", {
|
|
||||||
expiresIn: '100d',
|
|
||||||
});
|
|
||||||
};
|
|
||||||
exports.createToken = createToken;
|
|
||||||
const verifyToken = (token) => __awaiter(void 0, void 0, void 0, function* () {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
jsonwebtoken_1.default.verify(token, "foo", (err, payload) => {
|
|
||||||
if (err)
|
|
||||||
return reject(err);
|
|
||||||
resolve(payload);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
exports.verifyToken = verifyToken;
|
|
||||||
exports.default = { createToken: exports.createToken, verifyToken: exports.verifyToken };
|
|
||||||
//# sourceMappingURL=token.js.map
|
|
@ -1 +0,0 @@
|
|||||||
{"version":3,"file":"token.js","sourceRoot":"","sources":["../../src/model/token.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,gEAA+B;AAIxB,MAAM,WAAW,GAAG,CAAC,IAAW,EAAU,EAAE;IAC/C,OAAO,sBAAG,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,KAAmB,EAAE;QACnD,SAAS,EAAE,MAAM;KACpB,CAAC,CAAC;AACP,CAAC,CAAC;AAJW,QAAA,WAAW,eAItB;AAEK,MAAM,WAAW,GAAG,CACvB,KAAa,EACqB,EAAE;IACpC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACnC,sBAAG,CAAC,MAAM,CACN,KAAK,EACL,KAAmB,EACnB,CAAC,GAAG,EAAE,OAAO,EAAE,EAAE;YACb,IAAI,GAAG;gBAAE,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;YAE5B,OAAO,CAAC,OAAiB,CAAC,CAAC;QAC/B,CAAC,CACJ,CAAC;IACN,CAAC,CAAC,CAAC;AACP,CAAC,CAAA,CAAC;AAdW,QAAA,WAAW,eActB;AAEF,kBAAe,EAAE,WAAW,EAAX,mBAAW,EAAE,WAAW,EAAX,mBAAW,EAAE,CAAC"}
|
|
@ -1,116 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
||||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
||||||
return new (P || (P = Promise))(function (resolve, reject) {
|
|
||||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
||||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
||||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
||||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
||||||
});
|
|
||||||
};
|
|
||||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
||||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
||||||
};
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
// import db from '../database';
|
|
||||||
const locationModel_1 = require("../model/locationModel");
|
|
||||||
const LocationSchema_1 = __importDefault(require("../database/schema/LocationSchema"));
|
|
||||||
class LocationService {
|
|
||||||
constructor() {
|
|
||||||
this.locationCollection = LocationSchema_1.default;
|
|
||||||
this.toRad = (value) => (value * Math.PI) / 180;
|
|
||||||
this.toDeg = (value) => (value * 180) / Math.PI;
|
|
||||||
// getCenter(coords)
|
|
||||||
}
|
|
||||||
// private API_KEY : string = "AIzaSyBFCEAtmhZ8jvw84UTQvX3Aqpr66GVqB_A";
|
|
||||||
getNearUser(idFlad, musicId, latitude, longitude) {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
yield this.locationCollection.findOneAndUpdate({ idFlad }, { idFlad, musicId, latitude, longitude }, { upsert: true });
|
|
||||||
const snapshot = yield this.locationCollection.find({ idFlad: { $ne: idFlad } });
|
|
||||||
if (snapshot.length === 0) {
|
|
||||||
console.log('No matching documents.');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let dbUsersList = [];
|
|
||||||
snapshot.forEach(doc => {
|
|
||||||
dbUsersList.push(new locationModel_1.UserLocation(doc.idFlad, doc.musicId, doc.latitude, doc.longitude));
|
|
||||||
console.log(doc.idFlad, '=>', doc);
|
|
||||||
});
|
|
||||||
// missing the curent music
|
|
||||||
let listUser = [];
|
|
||||||
const listUser2 = {};
|
|
||||||
dbUsersList.forEach(user => {
|
|
||||||
console.log(user);
|
|
||||||
const dist = this.distanceBetween(latitude, longitude, user.latitude, user.longitude);
|
|
||||||
console.log(user.uuid, dist);
|
|
||||||
if (dist <= 100) {
|
|
||||||
listUser.push(user.uuid);
|
|
||||||
listUser2[user.uuid] = user.musicId;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return { listUser, listUser2 };
|
|
||||||
// $listUser[] = {userID,idMusic};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
getCenter(points) {
|
|
||||||
if (Array.isArray(points) === false || points.length === 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
const numberOfPoints = points.length;
|
|
||||||
const sum = points.reduce((acc, point) => {
|
|
||||||
const pointLat = this.toRad(point.coords.latitude);
|
|
||||||
const pointLon = this.toRad(point.coords.longitude);
|
|
||||||
return {
|
|
||||||
X: acc.X + Math.cos(pointLat) * Math.cos(pointLon),
|
|
||||||
Y: acc.Y + Math.cos(pointLat) * Math.sin(pointLon),
|
|
||||||
Z: acc.Z + Math.sin(pointLat),
|
|
||||||
};
|
|
||||||
}, { X: 0, Y: 0, Z: 0 });
|
|
||||||
const X = sum.X / numberOfPoints;
|
|
||||||
const Y = sum.Y / numberOfPoints;
|
|
||||||
const Z = sum.Z / numberOfPoints;
|
|
||||||
return {
|
|
||||||
longitude: this.toDeg(Math.atan2(Y, X)),
|
|
||||||
latitude: this.toDeg(Math.atan2(Z, Math.sqrt(X * X + Y * Y))),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
;
|
|
||||||
// sa c'est un utils du coup mettre dans une calss utils
|
|
||||||
// resulta en km
|
|
||||||
distanceBetween(lat1, lon1, lat2, lon2) {
|
|
||||||
if ((lat1 == lat2) && (lon1 == lon2)) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
var radlat1 = Math.PI * lat1 / 180;
|
|
||||||
var radlat2 = Math.PI * lat2 / 180;
|
|
||||||
var theta = lon1 - lon2;
|
|
||||||
var radtheta = Math.PI * theta / 180;
|
|
||||||
var dist = Math.sin(radlat1) * Math.sin(radlat2) + Math.cos(radlat1) * Math.cos(radlat2) * Math.cos(radtheta);
|
|
||||||
if (dist > 1) {
|
|
||||||
dist = 1;
|
|
||||||
}
|
|
||||||
dist = Math.acos(dist);
|
|
||||||
dist = dist * 180 / Math.PI;
|
|
||||||
dist = dist * 60 * 1.1515;
|
|
||||||
dist = dist * 1.609344;
|
|
||||||
return dist;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
distanceBetweenPosition(first, second) {
|
|
||||||
return this.distanceBetween(first.coords.latitude, first.coords.longitude, second.coords.latitude, second.coords.longitude);
|
|
||||||
}
|
|
||||||
// give a array of position sorted by distance and return the first
|
|
||||||
findNearest(main, list) {
|
|
||||||
this.orderByDistance(main, list)[0];
|
|
||||||
}
|
|
||||||
//distanceFn: DistanceFn = getDistance est param sa serrait cool de lui passer un fonction
|
|
||||||
orderByDistance(mainPos, coords) {
|
|
||||||
return coords
|
|
||||||
.slice()
|
|
||||||
.sort((a, b) => this.distanceBetweenPosition(mainPos, a) - this.distanceBetweenPosition(mainPos, b));
|
|
||||||
}
|
|
||||||
;
|
|
||||||
}
|
|
||||||
exports.default = LocationService;
|
|
||||||
//# sourceMappingURL=LocationService.js.map
|
|
@ -1 +0,0 @@
|
|||||||
{"version":3,"file":"LocationService.js","sourceRoot":"","sources":["../../src/service/LocationService.ts"],"names":[],"mappings":"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"}
|
|
@ -1,69 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
||||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
||||||
return new (P || (P = Promise))(function (resolve, reject) {
|
|
||||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
||||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
||||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
||||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
||||||
});
|
|
||||||
};
|
|
||||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
||||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
||||||
};
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
const UserSchema_1 = __importDefault(require("../database/schema/User/UserSchema"));
|
|
||||||
const token_1 = __importDefault(require("../model/token"));
|
|
||||||
class UserService {
|
|
||||||
constructor() {
|
|
||||||
this.user = UserSchema_1.default;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Register a new user
|
|
||||||
*/
|
|
||||||
register(name, email, password, idFlad, idSpotify) {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
try {
|
|
||||||
const user = yield this.user.create({
|
|
||||||
name,
|
|
||||||
email,
|
|
||||||
password,
|
|
||||||
idFlad,
|
|
||||||
idSpotify
|
|
||||||
});
|
|
||||||
const accessToken = token_1.default.createToken(user);
|
|
||||||
return accessToken;
|
|
||||||
}
|
|
||||||
catch (error) {
|
|
||||||
throw new Error(error.message);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Attempt to login a user
|
|
||||||
*/
|
|
||||||
login(email, password) {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
try {
|
|
||||||
// should maybe creat a method base on id and other information for better security
|
|
||||||
// need to view with Emre
|
|
||||||
const user = yield this.user.findOne({ email });
|
|
||||||
// const user = await this.user.findById(idFlad);
|
|
||||||
if (!user) {
|
|
||||||
throw new Error('Unable to find user with that email address');
|
|
||||||
}
|
|
||||||
if (yield user.isValidPassword(password)) {
|
|
||||||
return token_1.default.createToken(user);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw new Error('Wrong credentials given');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (error) {
|
|
||||||
throw new Error('Unable to create user');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
exports.default = UserService;
|
|
||||||
//# sourceMappingURL=UserService.js.map
|
|
@ -1 +0,0 @@
|
|||||||
{"version":3,"file":"UserService.js","sourceRoot":"","sources":["../../src/service/UserService.ts"],"names":[],"mappings":";;;;;;;;;;;;;;AAAA,oFAA4D;AAC5D,2DAAmC;AAGnC,MAAM,WAAW;IAAjB;QACY,SAAI,GAAG,oBAAU,CAAC;IAuD9B,CAAC;IArDG;;OAEG;IACU,QAAQ,CACjB,IAAY,EACZ,KAAa,EACb,QAAgB,EAChB,MAAe,EACf,SAAkB;;YAElB,IAAI;gBACA,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC;oBAChC,IAAI;oBACJ,KAAK;oBACL,QAAQ;oBACR,MAAM;oBACN,SAAS;iBACZ,CAAC,CAAC;gBAEH,MAAM,WAAW,GAAG,eAAK,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;gBAE5C,OAAO,WAAW,CAAC;aACtB;YAAC,OAAO,KAAW,EAAE;gBAClB,MAAM,IAAI,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;aAClC;QACL,CAAC;KAAA;IAED;;OAEG;IACU,KAAK,CACd,KAAa,EACb,QAAgB;;YAEhB,IAAI;gBACA,mFAAmF;gBACnF,yBAAyB;gBACzB,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;gBAChD,iDAAiD;gBAEjD,IAAI,CAAC,IAAI,EAAE;oBACP,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;iBAClE;gBAED,IAAI,MAAM,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,EAAE;oBACtC,OAAO,eAAK,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;iBAClC;qBAAM;oBACH,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;iBAC9C;aACJ;YAAC,OAAO,KAAK,EAAE;gBACZ,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;aAC5C;QACL,CAAC;KAAA;CACJ;AAED,kBAAe,WAAW,CAAC"}
|
|
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"watch": ["src"],
|
||||||
|
"ext": ".ts.js",
|
||||||
|
"exec": "ts-node ./src/index.ts"
|
||||||
|
}
|
@ -1,68 +1,60 @@
|
|||||||
import express, { Application } from 'express';
|
import express, { Application } from 'express';
|
||||||
import cors from 'cors';
|
import cors from 'cors';
|
||||||
import Controller from './controller/Icontroller';
|
import cookieParser from 'cookie-parser';
|
||||||
import bodyParser from 'body-parser';
|
import bodyParser from 'body-parser';
|
||||||
|
import IController from './controllers/interfaces/IController';
|
||||||
import mongoose from 'mongoose';
|
import mongoose from 'mongoose';
|
||||||
|
import swaggerUi from "swagger-ui-express";
|
||||||
import cookieParser from 'cookie-parser';
|
import { specs } from './utils/swagger';
|
||||||
|
|
||||||
class App {
|
class App {
|
||||||
public express: Application;
|
public express: Application;
|
||||||
public port: number;
|
public port: number;
|
||||||
public dataBase: null;
|
|
||||||
|
|
||||||
public server : any;
|
constructor(controllers: IController[], port: number) {
|
||||||
|
|
||||||
constructor(controllers: Controller[], port: number) {
|
|
||||||
this.express = express();
|
this.express = express();
|
||||||
this.port = port;
|
this.port = port;
|
||||||
this.dataBase = null;
|
|
||||||
|
|
||||||
this.initialiseDatabase();
|
|
||||||
this.initialiseMiddleware();
|
|
||||||
this.initialiseControllers(controllers);
|
|
||||||
|
|
||||||
|
this.initDatabase();
|
||||||
|
this.initMiddleware();
|
||||||
|
this.initControllers(controllers);
|
||||||
|
this.initSwagger();
|
||||||
}
|
}
|
||||||
|
|
||||||
private initialiseMiddleware(): void {
|
private initMiddleware(): void {
|
||||||
this.express.use(cors());
|
this.express.use(cors());
|
||||||
this.express.use(cookieParser());
|
this.express.use(cookieParser());
|
||||||
|
|
||||||
|
|
||||||
this.express.use(express.json());
|
this.express.use(express.json());
|
||||||
this.express.use(express.urlencoded({ extended: false }));
|
this.express.use(express.urlencoded({ extended: false }));
|
||||||
|
|
||||||
this.express.use(bodyParser.json());
|
this.express.use(bodyParser.json());
|
||||||
this.express.use(bodyParser.urlencoded({
|
this.express.use(bodyParser.urlencoded({
|
||||||
extended: true
|
extended: true
|
||||||
}));
|
}));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private initialiseControllers(controllers: Controller[]): void {
|
private initControllers(controllers: IController[]): void {
|
||||||
controllers.forEach((controller: Controller) => {
|
controllers.forEach((controller: IController) => {
|
||||||
this.express.use('/api', controller.router);
|
this.express.use('/api', controller.router);
|
||||||
this.express.get('/toto', (req, res) => {
|
|
||||||
res.send('Hello World!');
|
|
||||||
})
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public listen(): void {
|
public listen(): void {
|
||||||
const server = this.express.listen(this.port, () => {
|
this.express.listen(this.port, () => {
|
||||||
console.log(`⚡️[server] : App listening on the port ${this.port}`);
|
console.log(`⚡️[server] : App listening on the port ${this.port}`);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private initialiseDatabase(): void {
|
private initDatabase(): void {
|
||||||
const uri = "mongodb+srv://fladDevDb:ZslYlNRWIOUU7i6o@fladcluster.b29tytu.mongodb.net/?retryWrites=true&w=majority"
|
const MONGO_URL = `mongodb+srv://FladDev:${process.env.MONGO_PASSWORD}@flad.mliekr2.mongodb.net/?retryWrites=true&w=majority`;
|
||||||
mongoose.connect(uri)
|
mongoose.connect(MONGO_URL)
|
||||||
.then(() => console.log("Connect to MongoDB database successfully"))
|
.then(() => console.log("Connect to MongoDB database successfully"))
|
||||||
.catch(err => console.log("Error connecting : "+ err ));
|
.catch(error => console.log("Error connecting : " + error));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public initSwagger(): void {
|
||||||
|
this.express.use("/swagger", swaggerUi.serve, swaggerUi.setup(specs),);
|
||||||
|
console.log(`Docs available at /${this.port}/swagger`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default App;
|
export default App;
|
After Width: | Height: | Size: 8.6 KiB |
@ -1,15 +0,0 @@
|
|||||||
import { Router } from 'express';
|
|
||||||
|
|
||||||
interface Controller {
|
|
||||||
path: string;
|
|
||||||
router: Router;
|
|
||||||
// constructor() {
|
|
||||||
// this.initialiseRoutes();
|
|
||||||
// }
|
|
||||||
|
|
||||||
// initialiseRoutes(): void ;
|
|
||||||
|
|
||||||
}
|
|
||||||
// il y a un truc inject
|
|
||||||
|
|
||||||
export default Controller;
|
|
@ -1,27 +0,0 @@
|
|||||||
import { Router } from "express";
|
|
||||||
import Controller from "./Icontroller";
|
|
||||||
|
|
||||||
type PingResponse = {
|
|
||||||
message: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export default class PingController implements Controller {
|
|
||||||
public path = '/ping';
|
|
||||||
public router = Router();
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
this.initialiseRoutes();
|
|
||||||
}
|
|
||||||
|
|
||||||
private initialiseRoutes(): void {
|
|
||||||
this.router.get("/ping", async (_req, res) => {
|
|
||||||
const response = await this.getMessage();
|
|
||||||
return res.send(response);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
async getMessage(): Promise<PingResponse> {
|
|
||||||
return {
|
|
||||||
message: "pong",
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,6 +0,0 @@
|
|||||||
export type AuthReqBody = {
|
|
||||||
grant_type: string,
|
|
||||||
redirect_uri?: string,
|
|
||||||
code?: string,
|
|
||||||
refresh_token?: string,
|
|
||||||
}
|
|
@ -1,198 +0,0 @@
|
|||||||
import Controller from '../Icontroller';
|
|
||||||
import { Router, Request, Response, NextFunction } from 'express';
|
|
||||||
import HttpException from '../../middleware/exeption/httpExeption';
|
|
||||||
import axios from 'axios';
|
|
||||||
import qs from 'qs';
|
|
||||||
|
|
||||||
class SpotifyController implements Controller {
|
|
||||||
public path = '/spotify';
|
|
||||||
public router = Router();
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
console.log("useeeee");
|
|
||||||
|
|
||||||
this.initialiseRoutes();
|
|
||||||
}
|
|
||||||
initialiseRoutes() {
|
|
||||||
this.router.get(`${this.path}/exchange`,this.login);
|
|
||||||
this.router.get(`${this.path}/callback`,this.getAccessToken);
|
|
||||||
this.router.get(`${this.path}/refresh`,this.getRefreshToken);
|
|
||||||
this.router.get(`${this.path}/spot`, this.getSpot);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private readonly API_URL = "https://accounts.spotify.com/api/token";
|
|
||||||
private readonly CLIENT_ID = "1f1e34e4b6ba48b388469dba80202b10";
|
|
||||||
private readonly CLIENT_SECRET = "779371c6d4994a68b8dd6e84b0873c82";
|
|
||||||
private readonly CALLBACK_2 = 'https://flad-api-production.up.railway.app/api/spotify/callback';
|
|
||||||
private readonly SCOPES ='user-read-private user-read-email user-read-playback-state user-read-currently-playing user-read-recently-played playlist-modify-public ugc-image-upload user-modify-playback-state';
|
|
||||||
private readonly clientRedirect= 'spotify_final_redirect-uri-key';
|
|
||||||
|
|
||||||
private login = async (
|
|
||||||
req: Request,
|
|
||||||
res: Response,
|
|
||||||
next: NextFunction
|
|
||||||
): Promise<Response | void> => {
|
|
||||||
|
|
||||||
console.log("useeeee== login");
|
|
||||||
try {
|
|
||||||
|
|
||||||
const redirectResponse = req.query.redirectUrl ? req.query.redirectUrl : req.headers.referer;
|
|
||||||
res.cookie(this.clientRedirect, redirectResponse);
|
|
||||||
console.log("aloorrr si c'est niquuuuuuuuuuuueeee" +this.CALLBACK_2+ "gennnnnnnnnrree vraiiiiiiiment ");
|
|
||||||
res.redirect('https://accounts.spotify.com/authorize?' +
|
|
||||||
qs.stringify({
|
|
||||||
response_type: 'code',
|
|
||||||
client_id: this.CLIENT_ID,
|
|
||||||
scope: this.SCOPES,
|
|
||||||
redirect_uri: this.CALLBACK_2,
|
|
||||||
}));
|
|
||||||
|
|
||||||
|
|
||||||
} catch (error) {
|
|
||||||
next(new HttpException(400, 'Cannot create spot'));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
private getRefreshToken = async (
|
|
||||||
req: Request,
|
|
||||||
res: Response,
|
|
||||||
next: NextFunction
|
|
||||||
): Promise<Response | void> => {
|
|
||||||
|
|
||||||
console.log('UUse2');
|
|
||||||
|
|
||||||
try {
|
|
||||||
const params = req.query.refresh_token;
|
|
||||||
|
|
||||||
if (!req.query.refresh_token) {
|
|
||||||
return res.json({
|
|
||||||
"error": "Parameter refresh_token missing"
|
|
||||||
});
|
|
||||||
}
|
|
||||||
let authOptions = {
|
|
||||||
method: 'POST',
|
|
||||||
url: 'https://accounts.spotify.com/api/token',
|
|
||||||
data: qs.stringify({
|
|
||||||
grant_type: 'refresh_token',
|
|
||||||
refresh_token: params
|
|
||||||
}),
|
|
||||||
headers: {
|
|
||||||
'Authorization': 'Basic ' + ( Buffer.from(this.CLIENT_ID + ':' + this.CLIENT_SECRET).toString('base64')),
|
|
||||||
'Content-Type' : 'application/x-www-form-urlencoded'
|
|
||||||
},
|
|
||||||
json: true
|
|
||||||
};
|
|
||||||
|
|
||||||
axios(authOptions)
|
|
||||||
.then(session => {
|
|
||||||
if(session.status === 200){
|
|
||||||
console.log('### Information : responce ###' + JSON.stringify( session.data) );
|
|
||||||
console.log('### Information : refresh_token ###' + session.data.refresh_token);
|
|
||||||
|
|
||||||
res.send({
|
|
||||||
"access_token": session.data.access_token,
|
|
||||||
"refresh_token": session.data.refresh_token,
|
|
||||||
"expires_in": session.data.expires_in
|
|
||||||
});
|
|
||||||
}});
|
|
||||||
console.log("goood");
|
|
||||||
} catch (error) {
|
|
||||||
console.log("errur");
|
|
||||||
next(new HttpException(400, 'Cannot create post'));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public getSpot = async (
|
|
||||||
req: Request,
|
|
||||||
res: Response,
|
|
||||||
next: NextFunction
|
|
||||||
): Promise<Response | void> => {
|
|
||||||
const spots = [
|
|
||||||
{
|
|
||||||
name: "blue",
|
|
||||||
sourceUrl: "https://cdns-images.dzcdn.net/images/artist/399e7e760d8fedf3cc2891e9c0c41658/200x200-000000-80-0-0.jpg",
|
|
||||||
index: 3
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "strange history",
|
|
||||||
sourceUrl: "https://images.genius.com/339dfe2a7c0adf9a5d08febf29a845f4.1000x1000x1.jpg",
|
|
||||||
index: 7
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "oboy album",
|
|
||||||
sourceUrl: "https://i.pinimg.com/originals/ad/cc/d5/adccd58a0d0ff516a6114703cd05810e.jpg",
|
|
||||||
index: 1
|
|
||||||
}
|
|
||||||
];
|
|
||||||
try {
|
|
||||||
res.send(spots);
|
|
||||||
|
|
||||||
} catch (error) {
|
|
||||||
console.log('heuuuuuuuuuuuuuuuuuuuuubizzzaaarrreeee');
|
|
||||||
console.log(error);
|
|
||||||
next(new HttpException(400, 'On peut pas avoir darray mec'));
|
|
||||||
} }
|
|
||||||
|
|
||||||
|
|
||||||
private getAccessToken = async (
|
|
||||||
req: Request,
|
|
||||||
res: Response,
|
|
||||||
next: NextFunction
|
|
||||||
): Promise<Response | void> => {
|
|
||||||
console.log("useeeee== accesToken");
|
|
||||||
|
|
||||||
let code = req.query.code;
|
|
||||||
let state = req.query.state || null;
|
|
||||||
let storedredirectUri = req.cookies ? req.cookies[this.clientRedirect] : null;
|
|
||||||
|
|
||||||
var authOptions = {
|
|
||||||
method: 'POST',
|
|
||||||
url: 'https://accounts.spotify.com/api/token',
|
|
||||||
data: qs.stringify({
|
|
||||||
code: code,
|
|
||||||
redirect_uri: this.CALLBACK_2,
|
|
||||||
grant_type: 'authorization_code'
|
|
||||||
}),
|
|
||||||
headers: {
|
|
||||||
'Authorization': 'Basic ' + ( Buffer.from(this.CLIENT_ID + ':' + this.CLIENT_SECRET).toString('base64')),
|
|
||||||
'Content-Type' : 'application/x-www-form-urlencoded'
|
|
||||||
},
|
|
||||||
json: true
|
|
||||||
};
|
|
||||||
try {
|
|
||||||
var resp = await axios(authOptions);
|
|
||||||
if (resp.status === 200) {
|
|
||||||
console.log('oon esttt laaa');
|
|
||||||
let access_token = resp.data.access_token;
|
|
||||||
let expiration =resp.data.expires_in;
|
|
||||||
let refresh = resp.data.refresh_token
|
|
||||||
console.log(access_token);
|
|
||||||
|
|
||||||
res.clearCookie(this.clientRedirect);
|
|
||||||
res.redirect(`${storedredirectUri}?` +
|
|
||||||
qs.stringify({
|
|
||||||
"access_token": access_token,
|
|
||||||
"expires_in": expiration,
|
|
||||||
"refresh_token" : refresh
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.log('heuuuuuuuuuuuuuuuuuuuuubizzzaaarrreeee');
|
|
||||||
console.log(error);
|
|
||||||
next(new HttpException(400, 'On peut pas te connecter mec'+ error.message));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
export default SpotifyController;
|
|
@ -1,254 +0,0 @@
|
|||||||
import { Router, Request, Response, NextFunction, RequestHandler } from 'express';
|
|
||||||
import Controller from '../Icontroller';
|
|
||||||
import HttpException from '../../middleware/exeption/httpExeption';
|
|
||||||
// import LocationService from '../../service/LocationService';
|
|
||||||
import IUser from '../../database/schema/User/UserInterface';
|
|
||||||
import UserService from '../../service/UserService';
|
|
||||||
import validator from '../../database/schema/User/UserValidation'
|
|
||||||
import validationMiddleware from '../../middleware/validation/ValidatorMiddleware';
|
|
||||||
import authenticator from '../../middleware/authMiddleware'
|
|
||||||
import LocationService from '../../service/LocationService';
|
|
||||||
class UserController implements Controller {
|
|
||||||
public path = '/users';
|
|
||||||
public router = Router();
|
|
||||||
private userService = new UserService();
|
|
||||||
private locationService = new LocationService();
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
this.initialiseRoutes();
|
|
||||||
}
|
|
||||||
|
|
||||||
private initialiseRoutes(): void {
|
|
||||||
this.router.post(
|
|
||||||
`${this.path}/register`,
|
|
||||||
validationMiddleware(validator.register),
|
|
||||||
this.register
|
|
||||||
);
|
|
||||||
this.router.post(
|
|
||||||
`${this.path}/login`,
|
|
||||||
validationMiddleware(validator.login),
|
|
||||||
this.login
|
|
||||||
);
|
|
||||||
this.router.get(`${this.path}`, authenticator, this.getUser);
|
|
||||||
this.router.get(`${this.path}/nextTo`, authenticator, this.getUserNext);
|
|
||||||
|
|
||||||
|
|
||||||
// //create
|
|
||||||
// this.router.post(`${this.path}`,this.createUser);
|
|
||||||
|
|
||||||
// // // get One
|
|
||||||
// this.router.get (`${this.path}/:userId`, this.getUserById);
|
|
||||||
// // // get All
|
|
||||||
// this.router.get (`${this.path}`, this.getAllUsers);
|
|
||||||
// //update One
|
|
||||||
// this.router.put (`${this.path}/:userId`, this.updateUser);
|
|
||||||
// //Delete One
|
|
||||||
// this.router.delete (`${this.path}/:userId`, this.deleteUser);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// private createUser = async (
|
|
||||||
// req: Request,
|
|
||||||
// res: Response,
|
|
||||||
// next: NextFunction
|
|
||||||
// ): Promise<Response | void> => {
|
|
||||||
// try {
|
|
||||||
|
|
||||||
// console.log(req.body);
|
|
||||||
// const reqBody:CreateTaskReqBody = Object.assign({}, req.body);
|
|
||||||
// checkIfIsValidCreateTaskReqBody(reqBody);
|
|
||||||
// await this.userService.createUserById(reqBody.fin
|
|
||||||
// );
|
|
||||||
|
|
||||||
// res.status(200).send({ status: "Success", msg: "Success add" });
|
|
||||||
|
|
||||||
|
|
||||||
// } catch (error) {
|
|
||||||
// next(new HttpException(400, 'Cannot create post'));
|
|
||||||
// }
|
|
||||||
// };
|
|
||||||
// private readonly getUserById: RequestHandler = async (
|
|
||||||
// req: Request,
|
|
||||||
// res: Response,
|
|
||||||
// next: NextFunction
|
|
||||||
// ): Promise<Response | void> => {
|
|
||||||
// try {
|
|
||||||
// const id = req.params.taskId;
|
|
||||||
// const userId = req.params.userId;
|
|
||||||
|
|
||||||
// const data = await this.userService.getUserById(id, userId);
|
|
||||||
// res.status(201).send(data);
|
|
||||||
|
|
||||||
// }
|
|
||||||
// catch(error){
|
|
||||||
// next(new HttpException(400, 'Cannot create post'));
|
|
||||||
// }
|
|
||||||
|
|
||||||
// }
|
|
||||||
// private readonly getAllUsers: RequestHandler = async (
|
|
||||||
// req: Request,
|
|
||||||
// res: Response,
|
|
||||||
// next: NextFunction
|
|
||||||
// ): Promise<Response | void> => {
|
|
||||||
// try {
|
|
||||||
// const userId = req.params.userId;
|
|
||||||
// const tasks = await this.userService.getUsers(userId);
|
|
||||||
// const responseList = tasks.map(task => new TaskResumedRes(task));
|
|
||||||
// res.status(201).send(responseList);
|
|
||||||
|
|
||||||
// }
|
|
||||||
// catch(error){
|
|
||||||
// next(new HttpException(400, 'Cannot get user task'));
|
|
||||||
// }
|
|
||||||
|
|
||||||
// }
|
|
||||||
|
|
||||||
// private deleteUser = async (
|
|
||||||
// req: Request,
|
|
||||||
// res: Response,
|
|
||||||
// next: NextFunction
|
|
||||||
// ): Promise<Response | void> => {
|
|
||||||
// try {
|
|
||||||
// const id = req.params.taskId;
|
|
||||||
// const userId = req.params.userId;
|
|
||||||
// await this.userService.DeleteUser(id, userId);
|
|
||||||
// return res.status(200).send({ status: "Success", msg: "Data Removed" });
|
|
||||||
// } catch (error) {
|
|
||||||
// next(new HttpException(400, 'Cannot create post'));
|
|
||||||
// }
|
|
||||||
// };
|
|
||||||
|
|
||||||
// private updateUser = async (
|
|
||||||
// req: Request,
|
|
||||||
// res: Response,
|
|
||||||
// next: NextFunction
|
|
||||||
// ): Promise<Response | void> => {
|
|
||||||
// try {
|
|
||||||
|
|
||||||
// const taskId = req.params.taskId;
|
|
||||||
// const userId = req.params.userId;
|
|
||||||
// const reqBody:CreateTaskReqBody = Object.assign({}, req.body);
|
|
||||||
|
|
||||||
// const updatedTask = await this.userService.UpdateTask(
|
|
||||||
// // req.auth!.uid,
|
|
||||||
// taskId,
|
|
||||||
// userId,
|
|
||||||
// // firebase.auth().currentUser.getIdToken()
|
|
||||||
// reqBody.nom,
|
|
||||||
// reqBody.description,
|
|
||||||
// reqBody.logo,
|
|
||||||
// reqBody.duration,
|
|
||||||
// reqBody.done,
|
|
||||||
// // reqBody.tags,
|
|
||||||
// reqBody.repepat,
|
|
||||||
// reqBody.deb,
|
|
||||||
// reqBody.fin
|
|
||||||
// );
|
|
||||||
// // res.send('Success add');
|
|
||||||
// // res.status(201).json({ task });
|
|
||||||
// res.status(204).send(`Update a new contact: ${updatedTask}`);
|
|
||||||
// } catch (error) {
|
|
||||||
// console.log(error);
|
|
||||||
// next(new HttpException(403, 'Cannot create post'));
|
|
||||||
// }
|
|
||||||
// };
|
|
||||||
|
|
||||||
|
|
||||||
private register = async (
|
|
||||||
req: Request,
|
|
||||||
res: Response,
|
|
||||||
next: NextFunction
|
|
||||||
): Promise<Response | void> => {
|
|
||||||
try {
|
|
||||||
// the FladId should be created by the Userservice
|
|
||||||
const { name, email, password , idFlad, idSpotify } = req.body;
|
|
||||||
console.log(name, email, password, idFlad, idSpotify);
|
|
||||||
|
|
||||||
const token = await this.userService.register(
|
|
||||||
name,
|
|
||||||
email,
|
|
||||||
password,
|
|
||||||
idFlad,
|
|
||||||
idSpotify
|
|
||||||
);
|
|
||||||
|
|
||||||
res.status(201).json({ token });
|
|
||||||
} catch (error : any) {
|
|
||||||
next(new HttpException(400, error.message));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private login = async (
|
|
||||||
req: Request,
|
|
||||||
res: Response,
|
|
||||||
next: NextFunction
|
|
||||||
): Promise<Response | void> => {
|
|
||||||
try {
|
|
||||||
const { email, password } = req.body;
|
|
||||||
|
|
||||||
const token = await this.userService.login(email, password);
|
|
||||||
|
|
||||||
res.status(200).json({ token });
|
|
||||||
} catch (error : any) {
|
|
||||||
next(new HttpException(400, error.message));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private getUser = (
|
|
||||||
req: Request,
|
|
||||||
res: Response,
|
|
||||||
next: NextFunction
|
|
||||||
): Response | void => {
|
|
||||||
if (!req.user) {
|
|
||||||
return next(new HttpException(404, 'No logged in user'));
|
|
||||||
}
|
|
||||||
|
|
||||||
res.status(200).send({ data: req.user });
|
|
||||||
};
|
|
||||||
|
|
||||||
private getUserNext = async (
|
|
||||||
req: Request,
|
|
||||||
res: Response,
|
|
||||||
next: NextFunction
|
|
||||||
): Promise<Response | void> => {
|
|
||||||
try {
|
|
||||||
const longitude = Number(req.query.longitude);
|
|
||||||
const latitude = Number(req.query.latitude);
|
|
||||||
//verify::val_int(){
|
|
||||||
console.log('woooooooooooooo' + req);
|
|
||||||
if (isNaN(longitude) || isNaN(latitude)) {
|
|
||||||
console.log('============' + longitude)
|
|
||||||
console.log('============' + latitude)
|
|
||||||
console.log('Impossible de convertir la chaîne en nombre');
|
|
||||||
}
|
|
||||||
//}
|
|
||||||
const userId = req.user.idFlad;
|
|
||||||
const musicId = String(req.query.currentMusic);
|
|
||||||
console.log('============' + longitude)
|
|
||||||
console.log('============' + latitude)
|
|
||||||
console.log('daaaaaaaaaaaaaaaaaaaaaa' + musicId);
|
|
||||||
const data = await this.locationService.getNearUser(userId,musicId,latitude,longitude);
|
|
||||||
console.log(data);
|
|
||||||
res.status(201).send(data);
|
|
||||||
|
|
||||||
}
|
|
||||||
catch(error : any){
|
|
||||||
next(new HttpException(400, 'Cannot create get netUser'));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
export default UserController;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
declare global {
|
|
||||||
namespace Express {
|
|
||||||
export interface Request {
|
|
||||||
user: IUser;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,8 @@
|
|||||||
|
import { Router } from 'express';
|
||||||
|
|
||||||
|
interface IController {
|
||||||
|
path: string;
|
||||||
|
router: Router;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default IController;
|
@ -0,0 +1,196 @@
|
|||||||
|
import IController from './interfaces/IController';
|
||||||
|
import { Router, Request, Response } from 'express';
|
||||||
|
import axios from 'axios';
|
||||||
|
import qs from 'qs';
|
||||||
|
|
||||||
|
class SpotifyController implements IController {
|
||||||
|
public path = '/spotify';
|
||||||
|
public router = Router();
|
||||||
|
public readonly CLIENT_ID_SPOTIFY = process.env.CLIENT_ID_SPOTIFY;
|
||||||
|
public readonly CLIENT_SECRET_SPOTIFY = process.env.CLIENT_SECRET_SPOTIFY;
|
||||||
|
private readonly API_URL = "https://accounts.spotify.com/api/token";
|
||||||
|
private readonly CALLBACK = 'http://localhost:8080/api/spotify/callback';
|
||||||
|
private readonly SCOPES = 'user-read-private user-read-email user-read-playback-state user-read-currently-playing user-read-recently-played playlist-modify-public ugc-image-upload user-modify-playback-state';
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.initRoutes();
|
||||||
|
}
|
||||||
|
|
||||||
|
initRoutes() {
|
||||||
|
/**
|
||||||
|
* @swagger
|
||||||
|
* /api/spotify/exchange:
|
||||||
|
* get:
|
||||||
|
* summary: Initiate the Spotify login flow
|
||||||
|
* description: Redirect the user to the Spotify login page for authorization
|
||||||
|
* tags:
|
||||||
|
* - Spotify
|
||||||
|
* parameters:
|
||||||
|
* - in: query
|
||||||
|
* name: redirectUrl
|
||||||
|
* schema:
|
||||||
|
* type: string
|
||||||
|
* description: The URL to redirect the user after Spotify authorization (optional)
|
||||||
|
* responses:
|
||||||
|
* 302:
|
||||||
|
* description: Redirecting to Spotify login page
|
||||||
|
* 400:
|
||||||
|
* description: Bad request - Cannot connect to Spotify
|
||||||
|
*/
|
||||||
|
this.router.get(`${this.path}/exchange`, this.login);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @swagger
|
||||||
|
* /api/spotify/callback:
|
||||||
|
* get:
|
||||||
|
* summary: Handle Spotify callback and exchange code for access token
|
||||||
|
* description: Handle Spotify callback and exchange the received code for an access token
|
||||||
|
* tags:
|
||||||
|
* - Spotify
|
||||||
|
* responses:
|
||||||
|
* 302:
|
||||||
|
* description: Redirecting with access token information
|
||||||
|
* 400:
|
||||||
|
* description: Bad request - Error connecting to Spotify
|
||||||
|
*/
|
||||||
|
this.router.get(`${this.path}/callback`, this.getAccessToken);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @swagger
|
||||||
|
* /api/spotify/refresh:
|
||||||
|
* get:
|
||||||
|
* summary: Refresh the Spotify access token using a refresh token
|
||||||
|
* description: Refresh the Spotify access token using a refresh token
|
||||||
|
* tags:
|
||||||
|
* - Spotify
|
||||||
|
* parameters:
|
||||||
|
* - in: query
|
||||||
|
* name: refresh_token
|
||||||
|
* schema:
|
||||||
|
* type: string
|
||||||
|
* required: true
|
||||||
|
* description: The refresh token obtained during the initial authorization
|
||||||
|
* responses:
|
||||||
|
* 200:
|
||||||
|
* description: Successfully refreshed access token
|
||||||
|
* content:
|
||||||
|
* application/json:
|
||||||
|
* schema:
|
||||||
|
* type: object
|
||||||
|
* properties:
|
||||||
|
* access_token:
|
||||||
|
* type: string
|
||||||
|
* description: The new access token
|
||||||
|
* refresh_token:
|
||||||
|
* type: string
|
||||||
|
* description: The new refresh token
|
||||||
|
* expires_in:
|
||||||
|
* type: number
|
||||||
|
* description: The time until the access token expires (in seconds)
|
||||||
|
* 400:
|
||||||
|
* description: Bad request - Cannot refresh the access token
|
||||||
|
*/
|
||||||
|
this.router.get(`${this.path}/refresh`, this.getRefreshToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly clientRedirect = 'spotify_final_redirect-uri-key';
|
||||||
|
|
||||||
|
private login = async (
|
||||||
|
req: Request,
|
||||||
|
res: Response
|
||||||
|
): Promise<Response | void> => {
|
||||||
|
try {
|
||||||
|
const redirectResponse = req.query.redirectUrl ? req.query.redirectUrl : req.headers.referer;
|
||||||
|
res.cookie(this.clientRedirect, redirectResponse);
|
||||||
|
res.redirect('https://accounts.spotify.com/authorize?' +
|
||||||
|
qs.stringify({
|
||||||
|
response_type: 'code',
|
||||||
|
client_id: this.CLIENT_ID_SPOTIFY,
|
||||||
|
scope: this.SCOPES,
|
||||||
|
redirect_uri: this.CALLBACK,
|
||||||
|
}));
|
||||||
|
} catch (error) {
|
||||||
|
res.status(400).send('Cannot connect: ' + error.message);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private getRefreshToken = async (
|
||||||
|
req: Request,
|
||||||
|
res: Response
|
||||||
|
): Promise<Response | void> => {
|
||||||
|
const params = req.query.refresh_token;
|
||||||
|
if (!req.query.refresh_token) {
|
||||||
|
return res.json({
|
||||||
|
"error": "Parameter refresh_token missing"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
const authOptions = {
|
||||||
|
method: 'POST',
|
||||||
|
url: 'https://accounts.spotify.com/api/token',
|
||||||
|
data: qs.stringify({
|
||||||
|
grant_type: 'refresh_token',
|
||||||
|
refresh_token: params
|
||||||
|
}),
|
||||||
|
headers: {
|
||||||
|
'Authorization': 'Basic ' + (Buffer.from(this.CLIENT_ID_SPOTIFY + ':' + this.CLIENT_SECRET_SPOTIFY).toString('base64')),
|
||||||
|
'Content-Type': 'application/x-www-form-urlencoded'
|
||||||
|
},
|
||||||
|
json: true
|
||||||
|
};
|
||||||
|
|
||||||
|
axios(authOptions)
|
||||||
|
.then(session => {
|
||||||
|
if (session.status === 200) {
|
||||||
|
res.send({
|
||||||
|
"access_token": session.data.access_token,
|
||||||
|
"refresh_token": session.data.refresh_token,
|
||||||
|
"expires_in": session.data.expires_in
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
res.status(400).send("Cannot get a new refresh token");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private getAccessToken = async (
|
||||||
|
req: Request,
|
||||||
|
res: Response
|
||||||
|
): Promise<Response | void> => {
|
||||||
|
let code = req.query.code;
|
||||||
|
let storedRedirectUri = req.cookies ? req.cookies[this.clientRedirect] : null;
|
||||||
|
let authOptions = {
|
||||||
|
method: 'POST',
|
||||||
|
url: this.API_URL,
|
||||||
|
data: qs.stringify({
|
||||||
|
code: code,
|
||||||
|
redirect_uri: this.CALLBACK,
|
||||||
|
grant_type: 'authorization_code'
|
||||||
|
}),
|
||||||
|
headers: {
|
||||||
|
'Authorization': 'Basic ' + (Buffer.from(this.CLIENT_ID_SPOTIFY + ':' + this.CLIENT_SECRET_SPOTIFY).toString('base64')),
|
||||||
|
'Content-Type': 'application/x-www-form-urlencoded'
|
||||||
|
},
|
||||||
|
json: true
|
||||||
|
};
|
||||||
|
try {
|
||||||
|
const resp = await axios(authOptions);
|
||||||
|
if (resp.status === 200) {
|
||||||
|
let access_token = resp.data.access_token;
|
||||||
|
let expiration = resp.data.expires_in;
|
||||||
|
let refresh = resp.data.refresh_token
|
||||||
|
res.clearCookie(this.clientRedirect);
|
||||||
|
res.redirect(`${storedRedirectUri}?` +
|
||||||
|
qs.stringify({
|
||||||
|
"access_token": access_token,
|
||||||
|
"expires_in": expiration,
|
||||||
|
"refresh_token": refresh
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
res.status(400).send('Error connection: ' + error.message);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export default SpotifyController;
|
@ -0,0 +1,803 @@
|
|||||||
|
import { Router, Request, Response } from 'express';
|
||||||
|
import IController from './interfaces/IController';
|
||||||
|
import User from '../models/User';
|
||||||
|
import UserService from '../services/UserService';
|
||||||
|
import validator from '../middlewares/UserValidation'
|
||||||
|
import validationMiddleware from '../middlewares/validationMiddleware';
|
||||||
|
import authenticator from '../middlewares/authMiddleware'
|
||||||
|
import LocationService from '../services/LocationService';
|
||||||
|
import axios from 'axios';
|
||||||
|
import { IMusic } from '../models/Music';
|
||||||
|
import * as fs from 'fs';
|
||||||
|
import * as base64js from 'base64-js';
|
||||||
|
|
||||||
|
class UserController implements IController {
|
||||||
|
public path = '/user';
|
||||||
|
public authPath = '/auth';
|
||||||
|
public router = Router();
|
||||||
|
private userService = new UserService();
|
||||||
|
private locationService = new LocationService();
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.initRoutes();
|
||||||
|
}
|
||||||
|
|
||||||
|
private initRoutes(): void {
|
||||||
|
/**
|
||||||
|
* @swagger
|
||||||
|
* /api/auth/register:
|
||||||
|
* post:
|
||||||
|
* summary: Register a new user
|
||||||
|
* description: Register a new user with the provided details
|
||||||
|
* tags:
|
||||||
|
* - Authentication
|
||||||
|
* requestBody:
|
||||||
|
* required: true
|
||||||
|
* content:
|
||||||
|
* application/json:
|
||||||
|
* schema:
|
||||||
|
* type: object
|
||||||
|
* properties:
|
||||||
|
* email:
|
||||||
|
* type: string
|
||||||
|
* default: john.doe@example.com
|
||||||
|
* password:
|
||||||
|
* type: string
|
||||||
|
* default: stringPassword123
|
||||||
|
* name:
|
||||||
|
* type: string
|
||||||
|
* default: john_doe
|
||||||
|
* tokenSpotify:
|
||||||
|
* type: string
|
||||||
|
* responses:
|
||||||
|
* 201:
|
||||||
|
* description: User registered successfully
|
||||||
|
* 400:
|
||||||
|
* description: Bad request - Invalid input data
|
||||||
|
* 401:
|
||||||
|
* description: Unauthorized - Spotify token is invalid
|
||||||
|
* 409:
|
||||||
|
* description: Conflict - Email or username is already in use
|
||||||
|
* 500:
|
||||||
|
* description: Internal Server Error - Spotify account not authorized or not found
|
||||||
|
*/
|
||||||
|
this.router.post(
|
||||||
|
`${this.authPath}/register`,
|
||||||
|
validationMiddleware(validator.register),
|
||||||
|
this.register
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @swagger
|
||||||
|
* /api/auth/login:
|
||||||
|
* post:
|
||||||
|
* summary: Login a user
|
||||||
|
* description: Login with the provided email and password
|
||||||
|
* tags:
|
||||||
|
* - Authentication
|
||||||
|
* requestBody:
|
||||||
|
* required: true
|
||||||
|
* content:
|
||||||
|
* application/json:
|
||||||
|
* schema:
|
||||||
|
* type: object
|
||||||
|
* properties:
|
||||||
|
* email:
|
||||||
|
* type: string
|
||||||
|
* default: john.doe@example.com
|
||||||
|
* password:
|
||||||
|
* type: string
|
||||||
|
* default: stringPassword123
|
||||||
|
* responses:
|
||||||
|
* 200:
|
||||||
|
* description: User logged in successfully
|
||||||
|
* content:
|
||||||
|
* application/json:
|
||||||
|
* schema:
|
||||||
|
* type: object
|
||||||
|
* properties:
|
||||||
|
* token:
|
||||||
|
* type: string
|
||||||
|
* 400:
|
||||||
|
* description: Bad request - Invalid input data
|
||||||
|
*/
|
||||||
|
this.router.post(
|
||||||
|
`${this.authPath}/login`,
|
||||||
|
validationMiddleware(validator.login),
|
||||||
|
this.login
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @swagger
|
||||||
|
* /api/user:
|
||||||
|
* get:
|
||||||
|
* summary: Get user information
|
||||||
|
* description: Get information about the authenticated user
|
||||||
|
* tags:
|
||||||
|
* - User
|
||||||
|
* security:
|
||||||
|
* - bearerAuth: []
|
||||||
|
* responses:
|
||||||
|
* 200:
|
||||||
|
* description: User logged in successfully
|
||||||
|
* 401:
|
||||||
|
* description: Unauthorized - Invalid or missing authentication token
|
||||||
|
*/
|
||||||
|
this.router.get(`${this.path}`, authenticator, this.getUser);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @swagger
|
||||||
|
* /api/users:
|
||||||
|
* get:
|
||||||
|
* summary: Get information about multiple users
|
||||||
|
* description: Get information about multiple users based on provided user ids
|
||||||
|
* tags:
|
||||||
|
* - User
|
||||||
|
* security:
|
||||||
|
* - bearerAuth: []
|
||||||
|
* parameters:
|
||||||
|
* - in: query
|
||||||
|
* name: ids
|
||||||
|
* schema:
|
||||||
|
* type: string
|
||||||
|
* description: Comma-separated list of user ids
|
||||||
|
* responses:
|
||||||
|
* 200:
|
||||||
|
* description: Users information retrieved successfully
|
||||||
|
* 401:
|
||||||
|
* description: Unauthorized - Invalid or missing authentication token
|
||||||
|
*/
|
||||||
|
this.router.get(`${this.path}s`, authenticator, this.getUsers);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @swagger
|
||||||
|
* /api/user:
|
||||||
|
* delete:
|
||||||
|
* summary: Delete the authenticated user
|
||||||
|
* description: Delete the authenticated user and associated data
|
||||||
|
* tags:
|
||||||
|
* - User
|
||||||
|
* security:
|
||||||
|
* - bearerAuth: []
|
||||||
|
* responses:
|
||||||
|
* 204:
|
||||||
|
* description: User deleted successfully
|
||||||
|
* 401:
|
||||||
|
* description: Unauthorized - Invalid or missing authentication token
|
||||||
|
* 404:
|
||||||
|
* description: User not found
|
||||||
|
*/
|
||||||
|
this.router.delete(`${this.path}`, authenticator, this.deleteUser);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @swagger
|
||||||
|
* /api/user/nextTo:
|
||||||
|
* get:
|
||||||
|
* summary: Get users near the authenticated user
|
||||||
|
* description: Get information about users near the authenticated user based on location
|
||||||
|
* tags:
|
||||||
|
* - User
|
||||||
|
* security:
|
||||||
|
* - bearerAuth: []
|
||||||
|
* parameters:
|
||||||
|
* - in: query
|
||||||
|
* name: longitude
|
||||||
|
* schema:
|
||||||
|
* type: number
|
||||||
|
* description: Longitude of the user's current location
|
||||||
|
* - in: query
|
||||||
|
* name: latitude
|
||||||
|
* schema:
|
||||||
|
* type: number
|
||||||
|
* description: Latitude of the user's current location
|
||||||
|
* - in: query
|
||||||
|
* name: currentMusic
|
||||||
|
* schema:
|
||||||
|
* type: string
|
||||||
|
* description: The ID of the currently playing music
|
||||||
|
* responses:
|
||||||
|
* 201:
|
||||||
|
* description: Users near the authenticated user retrieved successfully
|
||||||
|
* content:
|
||||||
|
* application/json:
|
||||||
|
* schema:
|
||||||
|
* type: object
|
||||||
|
* properties:
|
||||||
|
* data:
|
||||||
|
* type: array
|
||||||
|
* 401:
|
||||||
|
* description: Unauthorized - Invalid or missing authentication token
|
||||||
|
* 400:
|
||||||
|
* description: Bad request - Invalid input data
|
||||||
|
*/
|
||||||
|
this.router.get(`${this.path}/nextTo`, authenticator, this.getUserNext);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @swagger
|
||||||
|
* /api/user/musics/{id}:
|
||||||
|
* delete:
|
||||||
|
* summary: Delete a music from the authenticated user's liked list
|
||||||
|
* description: Delete a music from the authenticated user's liked list by music id
|
||||||
|
* tags:
|
||||||
|
* - User
|
||||||
|
* security:
|
||||||
|
* - bearerAuth: []
|
||||||
|
* parameters:
|
||||||
|
* - in: path
|
||||||
|
* name: id
|
||||||
|
* schema:
|
||||||
|
* type: string
|
||||||
|
* description: The ID of the music to delete
|
||||||
|
* responses:
|
||||||
|
* 200:
|
||||||
|
* description: Music deleted successfully
|
||||||
|
* 401:
|
||||||
|
* description: Unauthorized - Invalid or missing authentication token
|
||||||
|
* 404:
|
||||||
|
* description: Music not found
|
||||||
|
*/
|
||||||
|
this.router.delete(`${this.path}/musics/:id`, authenticator, this.deleteMusic);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @swagger
|
||||||
|
* /api/user/musics:
|
||||||
|
* post:
|
||||||
|
* summary: Add a music to the authenticated user's liked list
|
||||||
|
* description: Add a music to the authenticated user's liked list
|
||||||
|
* tags:
|
||||||
|
* - User
|
||||||
|
* security:
|
||||||
|
* - bearerAuth: []
|
||||||
|
* requestBody:
|
||||||
|
* required: true
|
||||||
|
* content:
|
||||||
|
* application/json:
|
||||||
|
* schema:
|
||||||
|
* type: object
|
||||||
|
* properties:
|
||||||
|
* musicId:
|
||||||
|
* type: string
|
||||||
|
* description: The ID of the music to add
|
||||||
|
* userId:
|
||||||
|
* type: string
|
||||||
|
* description: The ID of the user who liked the music
|
||||||
|
* responses:
|
||||||
|
* 201:
|
||||||
|
* description: Music added to liked list successfully
|
||||||
|
* 401:
|
||||||
|
* description: Unauthorized - Invalid or missing authentication token
|
||||||
|
* 400:
|
||||||
|
* description: Bad request - Invalid input data
|
||||||
|
*/
|
||||||
|
this.router.post(`${this.path}/musics`, authenticator, this.addMusic);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @swagger
|
||||||
|
* /api/user/musics:
|
||||||
|
* get:
|
||||||
|
* summary: Get the list of musics liked by the authenticated user
|
||||||
|
* description: Get the list of musics liked by the authenticated user
|
||||||
|
* tags:
|
||||||
|
* - User
|
||||||
|
* security:
|
||||||
|
* - bearerAuth: []
|
||||||
|
* responses:
|
||||||
|
* 200:
|
||||||
|
* description: List of musics retrieved successfully
|
||||||
|
* content:
|
||||||
|
* application/json:
|
||||||
|
* schema:
|
||||||
|
* type: object
|
||||||
|
* properties:
|
||||||
|
* musics:
|
||||||
|
* type: array
|
||||||
|
* 401:
|
||||||
|
* description: Unauthorized - Invalid or missing authentication token
|
||||||
|
*/
|
||||||
|
this.router.get(`${this.path}/musics`, authenticator, this.getMusics);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @swagger
|
||||||
|
* /api/user/name:
|
||||||
|
* put:
|
||||||
|
* summary: Update the name of the authenticated user
|
||||||
|
* description: Update the name of the authenticated user
|
||||||
|
* tags:
|
||||||
|
* - User
|
||||||
|
* security:
|
||||||
|
* - bearerAuth: []
|
||||||
|
* requestBody:
|
||||||
|
* required: true
|
||||||
|
* content:
|
||||||
|
* application/json:
|
||||||
|
* schema:
|
||||||
|
* type: object
|
||||||
|
* properties:
|
||||||
|
* name:
|
||||||
|
* type: string
|
||||||
|
* description: The new name for the user
|
||||||
|
* responses:
|
||||||
|
* 200:
|
||||||
|
* description: User name updated successfully
|
||||||
|
* 401:
|
||||||
|
* description: Unauthorized - Invalid or missing authentication token
|
||||||
|
* 400:
|
||||||
|
* description: Bad request - Invalid input data
|
||||||
|
* 409:
|
||||||
|
* description: Conflict - The provided name is already in use by another user
|
||||||
|
*/
|
||||||
|
this.router.put(`${this.path}/name`, authenticator, this.setName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @swagger
|
||||||
|
* /api/user/email:
|
||||||
|
* put:
|
||||||
|
* summary: Update the email of the authenticated user
|
||||||
|
* description: Update the email of the authenticated user
|
||||||
|
* tags:
|
||||||
|
* - User
|
||||||
|
* security:
|
||||||
|
* - bearerAuth: []
|
||||||
|
* requestBody:
|
||||||
|
* required: true
|
||||||
|
* content:
|
||||||
|
* application/json:
|
||||||
|
* schema:
|
||||||
|
* type: object
|
||||||
|
* properties:
|
||||||
|
* email:
|
||||||
|
* type: string
|
||||||
|
* format: email
|
||||||
|
* description: The new email for the user
|
||||||
|
* responses:
|
||||||
|
* 200:
|
||||||
|
* description: User email updated successfully
|
||||||
|
* 401:
|
||||||
|
* description: Unauthorized - Invalid or missing authentication token
|
||||||
|
* 400:
|
||||||
|
* description: Bad request - Invalid input data
|
||||||
|
* 409:
|
||||||
|
* description: Conflict - The provided email is already in use by another user
|
||||||
|
*/
|
||||||
|
this.router.put(`${this.path}/email`, authenticator, this.setEmail);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @swagger
|
||||||
|
* /api/user/spotify:
|
||||||
|
* put:
|
||||||
|
* summary: Update the spotify account
|
||||||
|
* description: Update the spotify account of the authenticated user
|
||||||
|
* tags:
|
||||||
|
* - User
|
||||||
|
* security:
|
||||||
|
* - bearerAuth: []
|
||||||
|
* requestBody:
|
||||||
|
* required: true
|
||||||
|
* content:
|
||||||
|
* application/json:
|
||||||
|
* schema:
|
||||||
|
* type: object
|
||||||
|
* properties:
|
||||||
|
* tokenSpotify:
|
||||||
|
* type: string
|
||||||
|
* description: Spotify token
|
||||||
|
* responses:
|
||||||
|
* 200:
|
||||||
|
* description: Spotify account updated successfully
|
||||||
|
* 401:
|
||||||
|
* description: Unauthorized - Invalid or missing authentication token
|
||||||
|
* 409:
|
||||||
|
* description: Conflict - The provided token is already in use by another user
|
||||||
|
* 500:
|
||||||
|
* description: Internal Server Error - Spotify account not authorized or not found
|
||||||
|
*/
|
||||||
|
this.router.put(`${this.path}/spotify`, authenticator, this.setSpotify);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @swagger
|
||||||
|
* /api/user/image:
|
||||||
|
* put:
|
||||||
|
* summary: Update the profile image of the authenticated user
|
||||||
|
* description: Update the profile image of the authenticated user
|
||||||
|
* tags:
|
||||||
|
* - User
|
||||||
|
* security:
|
||||||
|
* - bearerAuth: []
|
||||||
|
* requestBody:
|
||||||
|
* required: true
|
||||||
|
* content:
|
||||||
|
* application/json:
|
||||||
|
* schema:
|
||||||
|
* type: object
|
||||||
|
* properties:
|
||||||
|
* image:
|
||||||
|
* type: string
|
||||||
|
* format: base64
|
||||||
|
* description: The new profile image for the user (base64 encoded)
|
||||||
|
* responses:
|
||||||
|
* 200:
|
||||||
|
* description: User profile image updated successfully
|
||||||
|
* 401:
|
||||||
|
* description: Unauthorized - Invalid or missing authentication token
|
||||||
|
* 500:
|
||||||
|
* description: Internal Server Error - Unable to update the profile image
|
||||||
|
*/
|
||||||
|
this.router.put(`${this.path}/image`, authenticator, this.setImage);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @swagger
|
||||||
|
* /api/user/password:
|
||||||
|
* put:
|
||||||
|
* summary: Update the password of the authenticated user
|
||||||
|
* description: Update the password of the authenticated user
|
||||||
|
* tags:
|
||||||
|
* - User
|
||||||
|
* security:
|
||||||
|
* - bearerAuth: []
|
||||||
|
* requestBody:
|
||||||
|
* required: true
|
||||||
|
* content:
|
||||||
|
* application/json:
|
||||||
|
* schema:
|
||||||
|
* type: object
|
||||||
|
* properties:
|
||||||
|
* oldPassword:
|
||||||
|
* type: string
|
||||||
|
* description: The current password of the user
|
||||||
|
* newPassword:
|
||||||
|
* type: string
|
||||||
|
* description: The new password for the user
|
||||||
|
* responses:
|
||||||
|
* 200:
|
||||||
|
* description: User password updated successfully
|
||||||
|
* 401:
|
||||||
|
* description: Unauthorized - Invalid or missing authentication token
|
||||||
|
* 500:
|
||||||
|
* description: Internal Server Error - Unable to update the password
|
||||||
|
*/
|
||||||
|
this.router.put(`${this.path}/password`, authenticator, this.setPassword);
|
||||||
|
}
|
||||||
|
|
||||||
|
private register = async (
|
||||||
|
req: Request,
|
||||||
|
res: Response
|
||||||
|
): Promise<Response | void> => {
|
||||||
|
|
||||||
|
let access_token;
|
||||||
|
let idSpotify: string;
|
||||||
|
let image: string;
|
||||||
|
const { name, email, password, tokenSpotify } = req.body;
|
||||||
|
const apiBaseUrl = process.env.API_BASE_URL || 'http://localhost:8080/api';
|
||||||
|
const refreshUrl = `${apiBaseUrl}/spotify/refresh?refresh_token=${tokenSpotify}`;
|
||||||
|
try {
|
||||||
|
const authOptions = {
|
||||||
|
method: 'GET',
|
||||||
|
url: refreshUrl,
|
||||||
|
json: true
|
||||||
|
};
|
||||||
|
const authResponse = await axios(authOptions);
|
||||||
|
if (authResponse.status === 200) {
|
||||||
|
access_token = authResponse.data.access_token;
|
||||||
|
const headers = {
|
||||||
|
Authorization: `Bearer ${access_token}`,
|
||||||
|
};
|
||||||
|
const resp = await axios.get('https://api.spotify.com/v1/me', { headers });
|
||||||
|
if (resp.status == 200) {
|
||||||
|
const images = resp.data.images;
|
||||||
|
idSpotify = resp.data.id;
|
||||||
|
if (images && images.length > 0) {
|
||||||
|
images.sort((a: any, b: any) => b.height - a.height);
|
||||||
|
image = images[0].url;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const imagePath = './src/assets/images/default_user.png';
|
||||||
|
const imageBuffer = fs.readFileSync(imagePath);
|
||||||
|
const base64Image = 'data:image/png;base64,' + base64js.fromByteArray(imageBuffer);
|
||||||
|
image = base64Image
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error: any) {
|
||||||
|
console.log(error);
|
||||||
|
if (error.response.status === 400) {
|
||||||
|
res.status(401).send("Unauthorized: Spotify token is invalid");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
res.status(500).send("Internal Server Error: Unable to authenticate with Spotify");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const token = await this.userService.register(
|
||||||
|
name.toLowerCase(),
|
||||||
|
email.toLowerCase(),
|
||||||
|
password,
|
||||||
|
idSpotify,
|
||||||
|
tokenSpotify,
|
||||||
|
image
|
||||||
|
);
|
||||||
|
res.status(201).json({ token });
|
||||||
|
} catch (error: any) {
|
||||||
|
res.status(409).json(error.message);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private login = async (
|
||||||
|
req: Request,
|
||||||
|
res: Response
|
||||||
|
): Promise<Response | void> => {
|
||||||
|
try {
|
||||||
|
const { email, password } = req.body;
|
||||||
|
const token = await this.userService.login(email, password);
|
||||||
|
res.status(200).json({ token });
|
||||||
|
} catch (error: any) {
|
||||||
|
res.status(400).json(error.message)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private getUser = (
|
||||||
|
req: Request,
|
||||||
|
res: Response
|
||||||
|
): Response | void => {
|
||||||
|
res.status(200).send({ data: req.user });
|
||||||
|
};
|
||||||
|
|
||||||
|
private getUsers = async (
|
||||||
|
req: Request,
|
||||||
|
res: Response
|
||||||
|
): Promise<Response | void> => {
|
||||||
|
const userIds = req.query.ids as string;
|
||||||
|
|
||||||
|
if (!userIds) {
|
||||||
|
return res.status(200).json([]);
|
||||||
|
}
|
||||||
|
|
||||||
|
const userIdArray = userIds.split('&');
|
||||||
|
|
||||||
|
try {
|
||||||
|
const users = await this.userService.getUsers(userIdArray);
|
||||||
|
res.json(users);
|
||||||
|
} catch (error) {
|
||||||
|
res.status(500).json({ message: error.message });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private deleteUser = async (
|
||||||
|
req: Request,
|
||||||
|
res: Response
|
||||||
|
): Promise<Response | void> => {
|
||||||
|
try {
|
||||||
|
const { _id } = req.user;
|
||||||
|
await this.userService.delete(_id);
|
||||||
|
await this.locationService.delete(_id);
|
||||||
|
res.status(204).send();
|
||||||
|
} catch (error: any) {
|
||||||
|
res.status(404).json(error.message)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private getUserNext = async (
|
||||||
|
req: Request,
|
||||||
|
res: Response
|
||||||
|
): Promise<Response | void> => {
|
||||||
|
try {
|
||||||
|
const longitude = Number(req.query.longitude);
|
||||||
|
const latitude = Number(req.query.latitude);
|
||||||
|
if (isNaN(longitude) || isNaN(latitude)) {
|
||||||
|
console.log('Unable to convert string to number');
|
||||||
|
throw new Error('Unable to convert string to number');
|
||||||
|
}
|
||||||
|
const userId = req.user.id;
|
||||||
|
const musicId = String(req.query.currentMusic);
|
||||||
|
const data = await this.locationService.getNearUser(userId, musicId, latitude, longitude);
|
||||||
|
res.status(201).send(data);
|
||||||
|
}
|
||||||
|
catch (error: any) {
|
||||||
|
res.status(400).json(error.message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private deleteMusic = async (
|
||||||
|
req: Request,
|
||||||
|
res: Response
|
||||||
|
): Promise<Response | void> => {
|
||||||
|
try {
|
||||||
|
const { _id } = req.user;
|
||||||
|
const musicId: string = req.params.id;
|
||||||
|
if (!musicId) {
|
||||||
|
return res.status(400).json({ error: 'musicId are required fields.' });
|
||||||
|
}
|
||||||
|
|
||||||
|
const deleted = await this.userService.deleteMusic(_id, musicId);
|
||||||
|
|
||||||
|
if (deleted) {
|
||||||
|
res.status(200).send({ message: 'Music deleted successfully.' });
|
||||||
|
} else {
|
||||||
|
res.status(404).json({ error: 'Music not found.' });
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (error: any) {
|
||||||
|
res.status(404).json(error.message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private addMusic = async (
|
||||||
|
req: Request,
|
||||||
|
res: Response
|
||||||
|
): Promise<Response | void> => {
|
||||||
|
try {
|
||||||
|
const { _id } = req.user;
|
||||||
|
const { musicId, userId } = req.body;
|
||||||
|
if (!musicId || !userId) {
|
||||||
|
return res.status(400).json({ error: 'musicId and userId are required fields.' });
|
||||||
|
}
|
||||||
|
const music: IMusic = {
|
||||||
|
musicId,
|
||||||
|
userId,
|
||||||
|
date: new Date(),
|
||||||
|
};
|
||||||
|
await this.userService.addMusic(_id, music);
|
||||||
|
res.status(201).send({ music });
|
||||||
|
} catch (error: any) {
|
||||||
|
res.status(400).json(error.message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private getMusics = async (
|
||||||
|
req: Request,
|
||||||
|
res: Response
|
||||||
|
): Promise<Response | void> => {
|
||||||
|
try {
|
||||||
|
const userId: string = req.user.id;
|
||||||
|
const musics = await this.userService.getMusics(userId);
|
||||||
|
return res.status(200).json({ musics });
|
||||||
|
} catch (error: any) {
|
||||||
|
res.status(400).json(error.message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private setName = async (
|
||||||
|
req: Request,
|
||||||
|
res: Response
|
||||||
|
): Promise<Response | void> => {
|
||||||
|
try {
|
||||||
|
const { _id } = req.user;
|
||||||
|
const { name } = req.body;
|
||||||
|
|
||||||
|
const regex = /^\w+$/;
|
||||||
|
if (!regex.test(name) || !name) {
|
||||||
|
return res.status(400).json({ error: "Name should only contain alphanumeric characters (letters, numbers, and underscores)" });
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.userService.setName(_id, name.toLowerCase());
|
||||||
|
|
||||||
|
res.status(200).json({ message: 'Name updated successfully' });
|
||||||
|
} catch (error: any) {
|
||||||
|
res.status(409).json(error.message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private setEmail = async (
|
||||||
|
req: Request,
|
||||||
|
res: Response
|
||||||
|
): Promise<Response | void> => {
|
||||||
|
try {
|
||||||
|
const { _id } = req.user;
|
||||||
|
const { email } = req.body;
|
||||||
|
|
||||||
|
const regex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
|
||||||
|
if (!regex.test(email) || !email) {
|
||||||
|
return res.status(400).json({ error: "Invalid email" });
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.userService.setEmail(_id, email.toLowerCase());
|
||||||
|
|
||||||
|
res.status(200).json({ message: 'Email updated successfully' });
|
||||||
|
} catch (error: any) {
|
||||||
|
res.status(409).json(error.message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private setSpotify = async (
|
||||||
|
req: Request,
|
||||||
|
res: Response
|
||||||
|
): Promise<Response | void> => {
|
||||||
|
let access_token;
|
||||||
|
let idAccount: string;
|
||||||
|
let image: string;
|
||||||
|
const { _id, idSpotify } = req.user;
|
||||||
|
const { tokenSpotify } = req.body;
|
||||||
|
|
||||||
|
if (!tokenSpotify) {
|
||||||
|
return res.status(400).json({ error: 'TokenSpotify is missing in the request.' });
|
||||||
|
}
|
||||||
|
|
||||||
|
const apiBaseUrl = process.env.API_BASE_URL || 'http://localhost:8080/api';
|
||||||
|
const refreshUrl = `${apiBaseUrl}/spotify/refresh?refresh_token=${tokenSpotify}`;
|
||||||
|
try {
|
||||||
|
const authOptions = {
|
||||||
|
method: 'GET',
|
||||||
|
url: refreshUrl,
|
||||||
|
json: true
|
||||||
|
};
|
||||||
|
const authResponse = await axios(authOptions);
|
||||||
|
if (authResponse.status === 200) {
|
||||||
|
access_token = authResponse.data.access_token;
|
||||||
|
const headers = {
|
||||||
|
Authorization: `Bearer ${access_token}`,
|
||||||
|
};
|
||||||
|
const resp = await axios.get('https://api.spotify.com/v1/me', { headers });
|
||||||
|
if (resp.status == 200) {
|
||||||
|
const images = resp.data.images;
|
||||||
|
idAccount = resp.data.id;
|
||||||
|
if (idSpotify === idAccount) {
|
||||||
|
return res.status(400).json({ error: 'idSpotify cannot be the same as idAccount.' });
|
||||||
|
}
|
||||||
|
if (images && images.length > 0) {
|
||||||
|
images.sort((a: any, b: any) => b.height - a.height);
|
||||||
|
image = images[0].url;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const imagePath = './src/assets/images/default_user.png';
|
||||||
|
const imageBuffer = fs.readFileSync(imagePath);
|
||||||
|
const base64Image = 'data:image/png;base64,' + base64js.fromByteArray(imageBuffer);
|
||||||
|
image = base64Image
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error: any) {
|
||||||
|
console.log(error);
|
||||||
|
res.status(500).send("Internal Server Error: Unable to authenticate with Spotify");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
await this.userService.setSpotify(_id, tokenSpotify, idAccount, image);
|
||||||
|
|
||||||
|
res.status(200).json({ message: 'Spotify token updated successfully' });
|
||||||
|
} catch (error: any) {
|
||||||
|
res.status(409).json(error.message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private setImage = async (
|
||||||
|
req: Request,
|
||||||
|
res: Response
|
||||||
|
): Promise<Response | void> => {
|
||||||
|
try {
|
||||||
|
const { _id } = req.user;
|
||||||
|
const { image } = req.body;
|
||||||
|
|
||||||
|
await this.userService.setImage(_id, image);
|
||||||
|
|
||||||
|
res.status(200).json({ message: 'Image updated successfully' });
|
||||||
|
} catch (error: any) {
|
||||||
|
res.status(500).json(error.message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private setPassword = async (
|
||||||
|
req: Request,
|
||||||
|
res: Response
|
||||||
|
): Promise<Response | void> => {
|
||||||
|
try {
|
||||||
|
const { _id } = req.user;
|
||||||
|
const { oldPassword, newPassword } = req.body;
|
||||||
|
|
||||||
|
await this.userService.setPassword(_id, oldPassword, newPassword);
|
||||||
|
|
||||||
|
res.status(200).json({ message: 'Password updated successfully' });
|
||||||
|
} catch (error: any) {
|
||||||
|
res.status(500).json(error.message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export default UserController;
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
namespace Express {
|
||||||
|
export interface Request {
|
||||||
|
user: User;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,26 @@
|
|||||||
|
import { Schema, model } from 'mongoose';
|
||||||
|
import { Location } from '../models/Location';
|
||||||
|
|
||||||
|
const locationSchema = new Schema({
|
||||||
|
userId: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
unique: true,
|
||||||
|
},
|
||||||
|
musicId: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
latitude: {
|
||||||
|
type: Number,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
longitude: {
|
||||||
|
type: Number,
|
||||||
|
required: true,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ timestamps: true }
|
||||||
|
);
|
||||||
|
|
||||||
|
export default model<Location>('Location', locationSchema);
|
@ -1,4 +0,0 @@
|
|||||||
|
|
||||||
// export default db = new MongoClient(uri);
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,62 @@
|
|||||||
|
import User from "../models/User";
|
||||||
|
import { Schema, model } from 'mongoose';
|
||||||
|
import bcrypt from 'bcrypt';
|
||||||
|
|
||||||
|
const userSchema = new Schema({
|
||||||
|
idSpotify: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
unique: true
|
||||||
|
},
|
||||||
|
tokenSpotify: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
name: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
unique: true
|
||||||
|
},
|
||||||
|
email: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
unique: true,
|
||||||
|
trim: true
|
||||||
|
},
|
||||||
|
password: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
,
|
||||||
|
image: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
musics_likes: {
|
||||||
|
type: [{
|
||||||
|
musicId: String,
|
||||||
|
userId: String,
|
||||||
|
date: Date
|
||||||
|
}],
|
||||||
|
default: []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ timestamps: true }
|
||||||
|
);
|
||||||
|
|
||||||
|
userSchema.pre<User>('save', async function (next) {
|
||||||
|
if (!this.isModified('password')) {
|
||||||
|
return next();
|
||||||
|
}
|
||||||
|
const hash = await bcrypt.hash(this.password, 8);
|
||||||
|
this.password = hash;
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
|
||||||
|
userSchema.methods.isValidPassword = async function (
|
||||||
|
password: string
|
||||||
|
): Promise<boolean | Error> {
|
||||||
|
return await bcrypt.compare(password, this.password);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default model<User>('User', userSchema);
|
@ -1,39 +0,0 @@
|
|||||||
import { Schema, model,Document } from 'mongoose';
|
|
||||||
|
|
||||||
|
|
||||||
const locationSchema = new Schema(
|
|
||||||
{
|
|
||||||
|
|
||||||
idFlad: {
|
|
||||||
type: String,
|
|
||||||
required: true,
|
|
||||||
unique: true,
|
|
||||||
},
|
|
||||||
musicId: {
|
|
||||||
type: String,
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
latitude: {
|
|
||||||
type: Number,
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
longitude: {
|
|
||||||
type: Number,
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
},
|
|
||||||
{ timestamps: true }
|
|
||||||
);
|
|
||||||
|
|
||||||
// fladDevDb
|
|
||||||
// ZslYlNRWIOUU7i6o
|
|
||||||
export default model<ILocation>('Location', locationSchema);
|
|
||||||
|
|
||||||
export interface ILocation extends Document {
|
|
||||||
idFlad: string;
|
|
||||||
musicId : string;
|
|
||||||
latitude : number;
|
|
||||||
longitude: number;
|
|
||||||
}
|
|
@ -1,8 +0,0 @@
|
|||||||
import { Schema, model } from 'mongoose';
|
|
||||||
|
|
||||||
const notificationSchema = new Schema({
|
|
||||||
type: {type: String, required: true},
|
|
||||||
content: {type: String, required: true}
|
|
||||||
});
|
|
||||||
|
|
||||||
export default {Notification: model("nofitication", notificationSchema)}
|
|
@ -1,11 +0,0 @@
|
|||||||
import { Document } from 'mongoose';
|
|
||||||
|
|
||||||
export default interface IUser extends Document {
|
|
||||||
email: string;
|
|
||||||
name: string;
|
|
||||||
password: string;
|
|
||||||
idFlad : string;
|
|
||||||
idSpotify : string;
|
|
||||||
|
|
||||||
isValidPassword(password: string): Promise<Error | boolean>;
|
|
||||||
}
|
|
@ -1,79 +0,0 @@
|
|||||||
// maye this file should me the UserModel like we had in php cause it's here we verrify the password
|
|
||||||
import IUser from "./UserInterface";
|
|
||||||
import { Schema, model } from 'mongoose';
|
|
||||||
import bcrypt from 'bcrypt';
|
|
||||||
// const userSchema: Schema = new Schema<IUser>({
|
|
||||||
// pseudo: {type: String, index: { unique: true }},
|
|
||||||
// email: {type: String},
|
|
||||||
// idDafl: {type: String, index: { unique: true }},
|
|
||||||
// idSpotify: {type: String},
|
|
||||||
// password: {type: String},
|
|
||||||
// prenom: {type: String, default: ""},
|
|
||||||
// description: {type: String, default: ""},
|
|
||||||
// nom: {type: String, default: ""},
|
|
||||||
// ville: {type: String, default: ""},
|
|
||||||
// profilPic: {type: String},
|
|
||||||
// noteList: [],
|
|
||||||
// notifications: [],
|
|
||||||
// friends: {type: [String] },
|
|
||||||
// favoris: [],
|
|
||||||
// conversations: {type: [String] }
|
|
||||||
// });
|
|
||||||
|
|
||||||
const userSchema = new Schema(
|
|
||||||
{
|
|
||||||
|
|
||||||
idFlad: {
|
|
||||||
type: String,
|
|
||||||
required: true,
|
|
||||||
unique: true,
|
|
||||||
},
|
|
||||||
idSpotify: {
|
|
||||||
type: String,
|
|
||||||
required: true,
|
|
||||||
unique: true,
|
|
||||||
},
|
|
||||||
name: {
|
|
||||||
type: String,
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
email: {
|
|
||||||
type: String,
|
|
||||||
required: true,
|
|
||||||
// this mean that we identify user by email
|
|
||||||
unique: true,
|
|
||||||
// delete the whitespace
|
|
||||||
trim: true,
|
|
||||||
},
|
|
||||||
password: {
|
|
||||||
type: String,
|
|
||||||
},
|
|
||||||
|
|
||||||
},
|
|
||||||
{ timestamps: true }
|
|
||||||
);
|
|
||||||
|
|
||||||
// this means that we hash the user password before saving it to the database
|
|
||||||
userSchema.pre<IUser>('save', async function (next) {
|
|
||||||
if (!this.isModified('password')) {
|
|
||||||
//just had that to be sure that the api still going
|
|
||||||
return next();
|
|
||||||
}
|
|
||||||
|
|
||||||
const hash = await bcrypt.hash(this.password, 8);
|
|
||||||
|
|
||||||
this.password = hash;
|
|
||||||
|
|
||||||
next();
|
|
||||||
});
|
|
||||||
|
|
||||||
userSchema.methods.isValidPassword = async function (
|
|
||||||
password: string
|
|
||||||
): Promise< boolean | Error> {
|
|
||||||
return await bcrypt.compare(password, this.password);
|
|
||||||
};
|
|
||||||
|
|
||||||
// fladDevDb
|
|
||||||
// ZslYlNRWIOUU7i6o
|
|
||||||
export default model<IUser>('User', userSchema);
|
|
||||||
// export const User: Model<IUser> = model('User', userSchema);
|
|
@ -1,45 +0,0 @@
|
|||||||
import { Request, Response, NextFunction } from 'express';
|
|
||||||
import jwt from 'jsonwebtoken';
|
|
||||||
import IToken from '../database/schema/Token/IToken';
|
|
||||||
import UserSchema from '../database/schema/User/UserSchema';
|
|
||||||
import token from '../model/token';
|
|
||||||
import HttpException from './exeption/httpExeption';
|
|
||||||
|
|
||||||
async function authenticatedMiddleware(
|
|
||||||
req: Request,
|
|
||||||
res: Response,
|
|
||||||
next: NextFunction
|
|
||||||
): Promise<Response | void> {
|
|
||||||
const bearer = req.headers.authorization;
|
|
||||||
|
|
||||||
if (!bearer || !bearer.startsWith('Bearer ')) {
|
|
||||||
return next(new HttpException(401, 'Unauthorised'));
|
|
||||||
}
|
|
||||||
|
|
||||||
const accessToken = bearer.split('Bearer ')[1].trim();
|
|
||||||
try {
|
|
||||||
const payload: IToken | jwt.JsonWebTokenError = await token.verifyToken(
|
|
||||||
accessToken
|
|
||||||
);
|
|
||||||
|
|
||||||
if (payload instanceof jwt.JsonWebTokenError) {
|
|
||||||
return next(new HttpException(401, 'Unauthorised'));
|
|
||||||
}
|
|
||||||
|
|
||||||
const user = await UserSchema.findById(payload.id)
|
|
||||||
.select('-password')
|
|
||||||
.exec();
|
|
||||||
|
|
||||||
if (!user) {
|
|
||||||
return next(new HttpException(401, 'Unauthorised'));
|
|
||||||
}
|
|
||||||
|
|
||||||
req.user = user;
|
|
||||||
|
|
||||||
return next();
|
|
||||||
} catch (error) {
|
|
||||||
return next(new HttpException(401, 'Unauthorised'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default authenticatedMiddleware;
|
|
@ -1,8 +0,0 @@
|
|||||||
// export const loggerOptions: expressWinston.LoggerOptions = {
|
|
||||||
// transports: [new winston.transports.Console()],
|
|
||||||
// format: winston.format.combine(
|
|
||||||
// winston.format.json(),
|
|
||||||
// winston.format.prettyPrint(),
|
|
||||||
// winston.format.colorize({ all: true })
|
|
||||||
// ),
|
|
||||||
// };
|
|
@ -1,14 +1,11 @@
|
|||||||
import Joi from 'joi';
|
import Joi from 'joi';
|
||||||
|
|
||||||
const register = Joi.object({
|
const register = Joi.object({
|
||||||
name: Joi.string().max(30).required(),
|
name: Joi.string().max(30).required().regex(/^\w+$/)
|
||||||
|
.message("Name should only contain alphanumeric characters (letters, numbers, and underscores)"),
|
||||||
email: Joi.string().email().required(),
|
email: Joi.string().email().required(),
|
||||||
|
|
||||||
password: Joi.string().min(6).required(),
|
password: Joi.string().min(6).required(),
|
||||||
// can add an field like confimPassword and cheked that the password is equal to the confirmPassword
|
tokenSpotify: Joi.string().required()
|
||||||
idSpotify: Joi.string(),
|
|
||||||
idFlad : Joi.string(),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const login = Joi.object({
|
const login = Joi.object({
|
@ -0,0 +1,45 @@
|
|||||||
|
import { Request, Response, NextFunction } from 'express';
|
||||||
|
import jwt from 'jsonwebtoken';
|
||||||
|
import Token from '../models/Token';
|
||||||
|
import UserSchema from '../database/UserSchema';
|
||||||
|
import token from '../services/TokenService';
|
||||||
|
import HttpException from '../exception/HttpException';
|
||||||
|
|
||||||
|
async function authMiddleware(
|
||||||
|
req: Request,
|
||||||
|
res: Response,
|
||||||
|
next: NextFunction
|
||||||
|
): Promise<Response | void> {
|
||||||
|
const bearer = req.headers.authorization;
|
||||||
|
|
||||||
|
if (!bearer || !bearer.startsWith('Bearer ')) {
|
||||||
|
return next(new HttpException(401, 'Unauthorized'));
|
||||||
|
}
|
||||||
|
|
||||||
|
const accessToken = bearer.split('Bearer')[1].trim();
|
||||||
|
try {
|
||||||
|
const payload: Token | jwt.JsonWebTokenError = await token.verifyToken(
|
||||||
|
accessToken
|
||||||
|
);
|
||||||
|
|
||||||
|
if (payload instanceof jwt.JsonWebTokenError) {
|
||||||
|
return next(new HttpException(401, 'Unauthorized'));
|
||||||
|
}
|
||||||
|
|
||||||
|
const user = await UserSchema.findById(payload.id)
|
||||||
|
.select('-password')
|
||||||
|
.exec();
|
||||||
|
|
||||||
|
if (!user) {
|
||||||
|
return next(new HttpException(401, 'Unauthorized'));
|
||||||
|
}
|
||||||
|
|
||||||
|
req.user = user;
|
||||||
|
|
||||||
|
return next();
|
||||||
|
} catch (error) {
|
||||||
|
return next(new HttpException(401, 'Unauthorized'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default authMiddleware;
|
@ -1,5 +0,0 @@
|
|||||||
export default interface IUser{
|
|
||||||
name: string;
|
|
||||||
email: string;
|
|
||||||
avatar?: string;
|
|
||||||
}
|
|