integration of authentication

This commit is contained in:
Cyril Rouillon 2024-08-06 17:44:09 +02:00
parent d38817f4c5
commit e7a78dcaad
21 changed files with 526 additions and 127 deletions

1
.gitignore vendored
View File

@ -1,4 +1,5 @@
.vscode
.Key.js
agent/node_modules

View File

@ -1,5 +1,6 @@
// Interencheres.js
'use strict';
const { config } = require('../../../config');
const {Scraper} = require('../Scraper');
const DrouotData = require('./DrouotData');
@ -131,6 +132,8 @@ class Drouot extends Scraper {
// askStop : sale is followed by the AuctionAgent and the user ask to stop following
// pause : the Sale is stopped by the Auction House and ready to restart
// end : the Sale is ended
// endOnError : the Sale is ended on error
// endOnRequest: end of follow asked by user
let status = 'ready'
@ -258,6 +261,9 @@ class Drouot extends Scraper {
page = await this.CheckAndConnect(page);
let lastbid = 0;
let CloseCount = 0;
//init Protobuf Decoder
const protobuf = require("protobufjs");
const root = await protobuf.load(this._PATH_PROTOBUF_FILE);
@ -278,7 +284,6 @@ class Drouot extends Scraper {
if(BideMessage.vente && BideMessage.vente.lot && BideMessage.vente.lot.lotId != undefined){
DataLot = await this.platformData.getLiveDataLot(BideMessage.vente.lot.lotId);
}
//console.log('BideMessage Type: '+BideMessage.type+' Lot: '+BideMessage.vente.lot.lotId);
switch (BideMessage.type) {
case 'PING':
@ -287,16 +292,31 @@ class Drouot extends Scraper {
break;
case 'INIT':
console.log('INIT');
break;
case 'CLOSE':
case 'CLOSE':
console.log('CLOSE');
//refresh the live to avoid unintoended close
clearInterval(CheckAskStop);
CloseCount++;
if(CloseCount > config.agent.maxCloseWebsockets){
console.log('CloseCount > config.agent.maxCloseWebsockets')
StopLive('endOnError')
return
}else{
console.log('Retry #'+CloseCount)
await GoLive();
}
break;
case 'BID':
console.log('BID');
console.log('Lot: '+BideMessage.vente.lot.lotId+' Amount: '+BideMessage.vente.bid.amount);
lastbid = Date.now();
await this.JucundusBid(
BideMessage.vente.lot.lotId,
Date.now(),
@ -392,61 +412,91 @@ class Drouot extends Scraper {
//console.log('Unknown type:', BideMessage);
}
};
};
let CheckAskStop = null;
let CheckLastBid = null;
let Socket = null;
// Stop the Live
const StopLive = async (code) => {
clearInterval(CheckAskStop);
clearInterval(CheckLastBid);
await this.JucundusEndSale(code)
page.close()
browser.close()
}
return
// create the live URL
let {saleID} = await this.platformData.getUrlInfo(this.Url);
let UrlLive = this._PAGE_MAIN + "live/bidlive/" + saleID;
let CheckAskStop = null;
let Socket = null;
// Stop the Live
const StopLive = async (params) => {
clearInterval(CheckAskStop);
page.close()
browser.close()
const GoLive = async () => {
try{
console.log('UrlLive : '+UrlLive)
await page.goto(UrlLive, { waitUntil: 'domcontentloaded' });
// intercept Lots Data
await page.route('https://api.drouot.com/drouot/gingolem/api/live/venteInfos/'+saleID+'?lang=fr', async route => {
console.log('GetLiveData')
const response = await route.fetch();
const LotData = await response.json();
this.platformData.setLiveData(LotData.data);
route.continue();
});
page.on('websocket', ws => {
Socket = ws;
Socket.on('framereceived', listener);
console.log('Websocket connected');
});
console.log('UrlLive : reload')
await page.reload();
// check if stop was asked
CheckAskStop = setInterval(async () => {
this.JucundusCheckStop()
.then(async AskStop => {
if(AskStop){
await StopLive('endOnRequest')
return
}
})
}, 10000); // 10000 milliseconds = 10 seconds
// Check every minute if the last event is more than 10 minutes ago
CheckLastBid = setInterval(() => {
if (lastbid && Date.now() - lastbid > 10 * 60 * 1000) {
console.log("More than 10 minutes since the last bid.");
this.JucundusSetSaleStatus(saleInfo, 'end')
(async () => {
await StopLive('end');
})();
return
}
}, 60 * 1000); // 60 seconds = 1 minute
}catch(e){
console.log('Error : '+e)
throw new Error('Error: '+e)
}
}
try{
console.log('UrlLive : '+UrlLive)
await GoLive();
await page.goto(UrlLive, { waitUntil: 'domcontentloaded' });
// intercept Lots Data
await page.route('https://api.drouot.com/drouot/gingolem/api/live/venteInfos/'+saleID+'?lang=fr', async route => {
console.log('GetLiveData')
const response = await route.fetch();
const LotData = await response.json();
this.platformData.setLiveData(LotData.data);
route.continue();
});
}
page.on('websocket', ws => {
Socket = ws;
Socket.on('framereceived', listener);
console.log('Websocket connected');
});
console.log('UrlLive : reload')
await page.reload();
// check if stop was asked
CheckAskStop = setInterval(async () => {
this.JucundusCheckStop()
.then(AskStop => {
if(AskStop){
StopLive()
}
})
}, 10000); // 10000 milliseconds = 10 seconds
}catch(e){
console.log('Error : '+e)
throw new Error('Error: '+e)
}
CaptureVideo = async () => {
}
};
module.exports = Drouot

View File

@ -344,9 +344,35 @@ class DrouotData extends ScraperTools {
SaleDateString = SaleDateString.trim()
let cleanStr = SaleDateString.replace(/\\s|\\n/g, ' ').replace(/\s+/g, ' ');
SaleDate = moment.tz(cleanStr, 'dddd D MMMM à HH:mm (z)', 'fr', 'Europe/Paris').format();
// Extract the timezone abbreviation
const timezoneAbbrMatch = cleanStr.match(/\(([^)]+)\)$/);
let timezoneAbbr = timezoneAbbrMatch ? timezoneAbbrMatch[1] : null;
// Map of common timezone abbreviations to full timezone names
const timezoneMap = {
'BST': 'Europe/London',
'CET': 'Europe/Paris',
'CEST': 'Europe/Paris',
'EDT': 'America/New_York',
'EST': 'America/New_York',
'PST': 'America/Los_Angeles',
'CDT': 'America/Chicago',
// Add more as needed
};
// Replace the abbreviation with the full timezone name if it exists in the map
if (timezoneAbbr && timezoneMap[timezoneAbbr]) {
cleanStr = cleanStr.replace(`(${timezoneAbbr})`, timezoneMap[timezoneAbbr]);
}
console.log('cleanStr : '+cleanStr)
// Parse the date string with the correct format and timezone
let saleDate = moment.tz(cleanStr, 'dddd D MMMM à HH:mm z', 'fr', timezoneMap[timezoneAbbr] || 'UTC');
// Convert to the desired timezone "Europe/Paris"
SaleDate = saleDate.tz('Europe/Paris').format();
// Live Sale
}else{
SaleDate = moment.tz('Europe/Paris').format();

View File

@ -120,6 +120,8 @@ class Interencheres extends Scraper {
// askStop : sale is followed by the AuctionAgent and the user ask to stop following
// pause : the Sale is stopped by the Auction House and ready to restart
// end : the Sale is ended
// endOnError : the Sale is ended on error
// endOnRequest: end of follow asked by user
let status = 'ready'
@ -178,6 +180,7 @@ class Interencheres extends Scraper {
const StopLive = async (params) => {
clearInterval(CheckAskStop);
//Socket.off('Network.webSocketFrameReceived', listener);
await this.JucundusEndSale('end')
page.close()
browser.close()
}

View File

@ -2,6 +2,8 @@
'use strict';
const fs = require('node:fs');
const fetch = require('node-fetch');
const { config } = require('../../config');
const { Key } = require('../../.Key');
class Scraper {
@ -13,18 +15,26 @@ class Scraper {
_PWD = ""
_PATH_SESSION_FILE = ""
_PATH_TOKEN_FILE = ""
_BROWSER_TOOL = null
_Proxy = ""
_DebugMode = false
_JucundusUrl = "http://host.docker.internal:3000"
_JucundusUrl = ""
token = ""
constructor(Url) {
this.Url = Url;
this._JucundusUrl = config.jucundus.url;
this._PATH_TOKEN_FILE = ".session/token.json"
this.token = this.getTokenInCache();
}
async _getContext(browser) {
return new Promise(async (resolve, reject) => {
try {
@ -73,9 +83,146 @@ class Scraper {
getLotList({ page, data}) {}
async Live({ page, data}) {}
getTokenInCache(){
if (fs.existsSync(this._PATH_TOKEN_FILE)) {
let rawdata = fs.readFileSync(this._PATH_TOKEN_FILE);
let token = JSON.parse(rawdata);
return token.token;
}
return "";
}
setTokenInCache(token){
let data = JSON.stringify({token: token});
fs.writeFileSync(this._PATH_TOKEN_FILE, data);
}
isTokenExpired(token) {
try {
const payload = JSON.parse(atob(token.split('.')[1]));
if (!payload || !payload.exp) {
return true;
}
const currentTime = Math.floor(Date.now() / 1000);
return payload.exp < currentTime;
} catch (error) {
console.error('Error decoding token:', error);
return true;
}
}
async isAgentConnected(){
return new Promise((resolve, reject) => {
fetch(this._JucundusUrl+'/api/user/agentConnected',{
method: 'GET',
headers: {
'Authorization': 'Bearer '+this.token
}
})
.then(response => {
if (!response.ok) {
console.log('isAgentConnected ? Agent not connected: '+response.statusText)
reject(false)
return;
}
console.log('isAgentConnected ? Agent connected')
resolve(true);
return;
})
.catch(error => {
console.log('isAgentConnected ? error Agent not connected: '+error)
reject(false)
return;
});
});
}
async checkJucundusConnexion(){
if(!this.token){
console.log('No token')
return false
}
if(this.isTokenExpired(this.token)){
console.log('Token expired')
return false
}
try {
const isConnected = await this.isAgentConnected();
if (!isConnected) {
console.log('Agent not connected');
return false;
}
} catch (error) {
console.log('Agent not connected');
return false;
}
return true;
}
async getNewToken(email, password) {
try {
const response = await fetch(this._JucundusUrl+'/authenticate', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ email, password })
});
if (!response.ok) {
throw new Error('Failed to retrieve new token');
}
const data = await response.json();
this.setTokenInCache(data.token);
return data.token;
} catch (error) {
console.error('Error retrieving new token:', error);
throw error;
}
}
async RequestJucundus(url, method, body = null){
console.log('RequestJucundus() '+url)
if (!await this.checkJucundusConnexion()) {
this.token = await this.getNewToken(config.jucundus.useremail, Key.jucundusPassword);
}
return new Promise((resolve, reject) => {
fetch(url,{
method: method,
headers: {
'Authorization': 'Bearer '+this.token,
'Content-Type': 'application/json'
},
body: body
})
.then(response => {
if (!response.ok) {
return response.json().then(err => {
throw new Error(err.error || 'Unknown error');
});
}
return response.json();
})
.then(data => {
console.log('RequestJucundus() data:' + JSON.stringify(data, null, 2))
resolve(data);
})
.catch(error => {
reject(error);
});
});
}
async JucundusCheckStop(){
//console.log('Check if Stop is asked')
@ -83,8 +230,7 @@ class Scraper {
let url = encodeURIComponent(this.Url)
return new Promise((resolve, reject) => {
fetch(this._JucundusUrl+'/api/sale/getByUrl/'+url)
.then(response => response.json())
this.RequestJucundus(this._JucundusUrl+'/api/sale/getByUrl/'+url, 'GET')
.then(saleInfo => {
let status = saleInfo.status
//console.log('status : '+status)
@ -93,34 +239,75 @@ class Scraper {
console.log('Stop was asked')
// return to ready status
this.JucundusSetSaleStatus(saleInfo, 'ready')
this.JucundusSetSaleStatus(saleInfo, 'end')
.then(
resolve(true)
);
} else {
resolve(false);
}
}
})
.catch(error => {
console.error(error);
reject(new Error('Error: '+error))
});
})
// return new Promise((resolve, reject) => {
// fetch(this._JucundusUrl+'/api/sale/getByUrl/'+url)
// .then(response => {
// if (!response.ok) {
// return response.json().then(err => {
// throw new Error(err.error || 'Unknown error');
// });
// }
// return response.json();
// })
// .then(saleInfo => {
// let status = saleInfo.status
// //console.log('status : '+status)
// if(status == 'askStop'){
// console.log('Stop was asked')
// // return to ready status
// this.JucundusSetSaleStatus(saleInfo, 'end')
// .then(
// resolve(true)
// );
// } else {
// resolve(false);
// }
// })
// .catch(error => {
// console.error(error);
// reject(new Error('Error: '+error))
// });
// })
}
async JucundusEndSale(){
console.log('JucundusEndSale')
async JucundusEndSale(code){
console.log('JucundusEndSale: '+code)
// check if stop was asked
let url = encodeURIComponent(this.Url)
return new Promise((resolve, reject) => {
fetch(this._JucundusUrl+'/api/sale/getByUrl/'+url)
.then(response => response.json())
// DEBUG
resolve(true)
if(code != 'end' && code != 'endOnError' && code != 'endOnRequest'){
console.error('Error: code must be end or endOnError or endOnRequest')
reject(new Error('Error: code must be end or endOnError or endOnRequest'))
}
this.RequestJucundus(this._JucundusUrl+'/api/sale/getByUrl/'+url, 'GET')
.then(saleInfo => {
// set end status
this.JucundusSetSaleStatus(saleInfo, 'end')
this.JucundusSetSaleStatus(saleInfo, code)
.then(
resolve(true)
);
@ -133,13 +320,11 @@ class Scraper {
}
async JucundusSetSaleStatus(saleInfo, status){
// change the status of the sale
saleInfo.status = status
return new Promise((resolve, reject) => {
fetch(this._JucundusUrl+'/api/sale/sale/'+saleInfo._id, {
method: 'PUT',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify(saleInfo)})
this.RequestJucundus(this._JucundusUrl+'/api/sale/sale/'+saleInfo._id, 'PUT', JSON.stringify(saleInfo))
.then(resolve(true))
.catch(error => {
console.error(error);
@ -149,13 +334,14 @@ class Scraper {
}
async JucunduNextItem(sale_id, timestamp, item_id, num_lot, title, description, EstimateLow, EstimateHigh, RawData){
console.log('JucunduNextItem', sale_id, timestamp, item_id, num_lot)
return new Promise((resolve, reject) => {
fetch(this._JucundusUrl+'/api/lot/NextItem', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify(
return new Promise((resolve, reject) => {
this.RequestJucundus(
this._JucundusUrl+'/api/lot/NextItem',
'POST',
JSON.stringify(
{
idPlatform: item_id,
idSalePlatform: sale_id,
@ -168,7 +354,7 @@ class Scraper {
EstimateHigh: EstimateHigh,
RawData: RawData
}
)})
))
.then(resolve(true))
.catch(error => {
console.error(error);
@ -178,12 +364,13 @@ class Scraper {
}
async JucundusBid(item_id, timestamp, amount, auctioned_type){
console.log('JucundusBid', timestamp, item_id, amount, auctioned_type)
return new Promise((resolve, reject) => {
fetch(this._JucundusUrl+'/api/lot/Bid', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify(
this.RequestJucundus(
this._JucundusUrl+'/api/lot/Bid',
'POST',
JSON.stringify(
{
idPlatform: item_id,
platform: this._Name,
@ -191,7 +378,7 @@ class Scraper {
amount: amount,
auctioned_type: auctioned_type
}
)})
))
.then(resolve(true))
.catch(error => {
console.error(error);
@ -200,14 +387,14 @@ class Scraper {
})
}
async JucunduAuctionedItem(item_id, timestamp, amount, sold, auctioned_type){
async JucunduAuctionedItem(item_id, timestamp, amount, sold, auctioned_type){
console.log('JucunduAuctionedItem', timestamp, item_id, amount, sold)
return new Promise((resolve, reject) => {
fetch(this._JucundusUrl+'/api/lot/AuctionedItem', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify(
this.RequestJucundus(
this._JucundusUrl+'/api/lot/AuctionedItem',
'POST',
JSON.stringify(
{
idPlatform: item_id,
platform: this._Name,
@ -216,7 +403,7 @@ class Scraper {
auctioned_type: auctioned_type,
sold: sold,
}
)})
))
.then(resolve(true))
.catch(error => {
console.error(error);

View File

@ -10,26 +10,6 @@
"secure": false,
"sameSite": "Lax"
},
{
"name": "JSESSIONID",
"value": "CEE9A69D532738CA6F448BC54BD5FA98",
"domain": "drouot.com",
"path": "/",
"expires": -1,
"httpOnly": true,
"secure": true,
"sameSite": "Lax"
},
{
"name": "cf_clearance",
"value": "Nw88GFRRH4A.R3IrqBs1WHV3v2j6b72TL4xFNt1qtRY-1716455904-1.0.1.1-YiA2MwdTbDytd5SaxdOm_F7ru5Q5bW.MaPs1FxJrr7YtILq0z0u9a4Lghyt2DIaNM_b_2hbki5IKioTVnUlqkQ",
"domain": ".drouot.com",
"path": "/",
"expires": 1747991903.778234,
"httpOnly": true,
"secure": true,
"sameSite": "None"
},
{
"name": "consentLevel",
"value": "none",
@ -41,33 +21,96 @@
"sameSite": "Lax"
},
{
"name": "aws.auth.refresh",
"value": "eyJjdHkiOiJKV1QiLCJlbmMiOiJBMjU2R0NNIiwiYWxnIjoiUlNBLU9BRVAifQ.ej0FDIw3VwTFabbv_Xrthwn6QRxOrGSlTP8P-hM3xyDmhigcIepCgEUlgjSO-taBevdDgiDNuRZ2ymbsmSHjBTgtPPhBJMlNW1CJMFpf34cnHp8P8fNso7KVZH98CVT8a-klxeNUw8sJbzV76E2pefGPiKahMbgNcct6I4C0lmK60569b1ADgDJUXoZ3ZWLM5h7dmu2_zEwcu3rcJSAZvqLBQBrBhw1ck2tivoMVl0Rp3rRDmYCkbvjYpVxozv_KCBA1pKdm_n1E78T4nlJR12UVZKwGj4TnM3_AiV43J-FUKkj-rDEoPfJrWlZh0J3aV403sDGeO_R7C8zOvMz8qQ.HTEsnaMZSmoB5bMT.CPMenx7Y1fkZnG3xdudDXwto0S9nXhlrviwGAUaEV0PdAiN1JRyWyfd2gfZ9gqDJ6CxBog-kZ45nttrdY2JjS71HgBfrg3RAqRqUyiRd9OLUTtHXgysdf6tXGZYqm2j62uTzq5aYWwr_KUMEYKqH45TrxAEnBGlCaKX5ielLghK6ZA_EWrOK3oJW3aM_-mZKD0vrJd9_iwVAUMKk_hdCF1UFqsuVHXZqXxQ_iOPzyd_t5Ui_2WgVqqLZTteAsFwr_L_TqpoM11AgSH-8a1ad05JwCdeMxyhZnW8Gf172Yt7pVzUFuV491KAxXdsgxCbFIhReYhOqABCsS9fKKbi6VBDtDBrRqGeiHgfOapVMLeg8-Va-_YGa1_4oRbX_zye_HTz3WE-xmBBwt98PVEJp4pWr2lY7wDgisqzLgI8foWm1YVWFD5rypAsJxEu-9-25SVErMVlptRaZ650YFHWNrkEr3oeqzwriIxMEjm92gxgVPQOO0Q5gqj9WcUHrbeq01xr6WBhX84AqGqTpT-kxbSrFBxHFMM3zhPey4ElJ2unc_ppj2r96e3FNjTmhRdhYYz827oewmJZZwhAF2KI8a_MEz6-W18b5ju0teM4lWBWRedq8IMeTFuEZ8-nlkQTiDnsSFXqZNtFVfJGcbKKTX8LCm708DrG5QGvqjycOkXrrnw-OCaUibCWbymJzwYdPD1sLLhitMpgI6pKW8H74K7bIb_v2IeMo3hH9gm2n6SI120EpD7n74UCIGx1fn5CB28neuj-_BegrcZNd6KEs0iPEhNOpHKd7k_G8riKX-ZtKIQcqZ8MtwAvjWVVFELEkpXR2IwfW2jXzBObIvcDYYNVijroFUZ-8oObp0dAIaUFtoByIzw3VOzOc4qbCSyelFC1YyoZJgbNW2ic6ZvL8pdzYTogjI_XHakVLBk8jeRg95SXtz9XzpLyx_ZoTX5LzEh5T897tOePl1NmIptU17IiBuwxFj_nYoVgDYbbGz1ox9vEWdrAE6EpfzhFrxWVMijyfjyauWaixri-harPAbhirrGG7QEeURqv0LCMMy1w3LyaZ9p9saG3DzX0yzrERgXMNvbFi4OYY3Cb0O8bo0kjHVY7a6Yj_qKKpfIKGclRKmndxkLK5A6JJkqy4fSLK-v9RbpWUiTC-_0L2k9lEGiK5rgPhMSRhyI5XYUW1rbB_XEKPU12M5uxER0NvjomXgTUy0yOdbDfpIYb89Bs2BK-SE0MAJSepzC8bsW4CWOnfCWGnuOGQphRfCuxAIkvd-4Lwm-Nyt8-Mmvh5VhQw79v8mx2eZNzk4DyiTDbSQUwdoCoEpgyoQnvnxObYVxXUeixB.LW8iCOUVXGCbeHw2rTF6Uw",
"name": "JSESSIONID",
"value": "F6EE192A727F489C38F2DB477FC1A27D",
"domain": "drouot.com",
"path": "/",
"expires": -1,
"httpOnly": true,
"secure": true,
"sameSite": "Lax"
},
{
"name": "sbss_e51870e9-89ed-4337-872e-e48073010805",
"value": "70066e04-417d-4157-ab37-5b19f86e2bae",
"domain": "site-azp.slgnt.eu",
"path": "/",
"expires": 1752310289.04592,
"httpOnly": true,
"secure": true,
"sameSite": "None"
},
{
"name": "sbt_i",
"value": "7ZmU0ZTAyMGUtMDY0YS00ODJlLTk4YjAtODQyZTEyZTVkOWNhOzNzAwNjZlMDQtNDE3ZC00MTU3LWFiMzctNWIxOWY4NmUyYmFlOzsA=",
"domain": ".drouot.com",
"path": "/",
"expires": 1718955905.860105,
"expires": 1752310289,
"httpOnly": false,
"secure": false,
"sameSite": "Lax"
},
{
"name": "sbt_p",
"value": "H4sIAAAAAAAAAwGcAmP9/////x+LCAAAAAAAAAPtVstu00AUdYpUaCkLWMCylhrRlZETnJeEhNxkjCJIXdwUiLqo4mQiBaVx5aQUFkhFsIEVQohP4Ce6Cb+ABCskdpW64RfAQ31tZzxOL48uEDnSOOOZO8fnjO/4ZllKF1Q1n6eqpmiZQtu75ApK075eUHJ2ptQp5mnWbtK06kMRXACfDpfev05JEvyeABbBL+GXRlnm/PvLS/H4lBQ2GLuy7djdXpe68lXZsR/S4UBuLzfdoSTt3/ydOMClsl4nt0yrsbVC9I0HulVfH5PL68A857hFWCppnMnzLafXo61h1+kPeMGT5gAXAzM1c6V6p0oslBeeOqbflXH6Z9td1+Ph5SUMAy7ULd0wquV1c8MqE5TiCGNM7AApdmanxSsSDAHmK+RetUzqjTWcQp8qpm6YoC4gjEJ07M5axCAW92ah8wjp/UzH7fJORWOAuYreMI37hNxGmQeqmPs9pL5zHcelfcfp84ISJwKla94RNg1PL0rpGF9M7mOk3AXP71aSsomTgIWaWSOrdcQeA473+I8tPkFanG+7zq4zvNZytnkPE6YAsxWzpldXUXo5ujHFsC7doRpVsypV1LzWVLRiliqloq0qRS1LM1maa5daTRE5L0xUosZOXWqTH/ln8Nn3dsoO4DHTii4gn1b0aUWPQnQOpxV9WtEZ/tuKLklfFj/uHf7s7c/4JHffhtOBDVG5XnyGCBQhaRoU3GgkBMRYWPv2Jux/lSXpxUHI9PwAwxTysbX8p0SE7x7wzCH/Sf+CJiLyrtiSp5vYp7L28l3YP5K9+5GX9zA3wrkGvlcjnOAg+T/g438Vf3NXWdawDIIcZJnFGutDZgH3kR/H3gLbW9ZYH/Y2puEHt1WZzyMSAABay56MnAIAAM6uM7zWcrZ5DxOmALMVs6ZXV1F6OboxxbAu3aEaVbMqVdS81lS0YpYqpaKtKkUtSzNZmmuXWk0ROS9MVKLGTl1qkx/5Z/DZ93bKDuAx",
"domain": ".drouot.com",
"path": "/",
"expires": 1752310289,
"httpOnly": false,
"secure": false,
"sameSite": "Lax"
},
{
"name": "cf_clearance",
"value": "wMZTGpFvQrXVc24EgBEh5Z_l07dq3n7E_GmmYYMM_Zg-1720774289-1.0.1.1-6kQTG9zdIWY9Ticp9YkIpsJlgtCDUnN9A4gIx5h.nMvWEqSMySuZZoJ5rAF1ts.QH.MzWJ8HzESZuBALJ_K9Cw",
"domain": ".drouot.com",
"path": "/",
"expires": 1752310289.605213,
"httpOnly": true,
"secure": true,
"sameSite": "None"
},
{
"name": "aws.auth.refresh",
"value": "eyJjdHkiOiJKV1QiLCJlbmMiOiJBMjU2R0NNIiwiYWxnIjoiUlNBLU9BRVAifQ.imuPu0l2BWRSCp5Deo-kkfjqrbXvrMOC7aLb73FLvWMEbZ_8wYPMIYDBVxWXCOue9lBOYWmBZ-gYmOpFjuub48kr0YH2XmS0CWvAjVaFOd1SLtA1JqPNCjzOhr4HqHNzY2p1v-LlWVkZMb6yzSJCo2i69X_uMhjI7vkwF5JBRLPfnhgpbTtuAfShe2fxwFVF3wcnIGwxwf9Mewftjw0vYAnU25kcUALthY_7os1vXG10B0HLJFlfG8AA0AZgOWin7YEYtNCR0fyILwVQLLrwrN1Df9I6nw0BT82u37GAZSihBNUekCBmLRf_eLad4DACY5YTwywzQjfLWIv6by0SYQ.32xpzYSlssbruFav.hmnVMOwHMa4fnXFrO_Eu402cEKhzl-uS_62OC51WXTOrY0qSXAGSjQLUleR8Aznkugbt738kCq7wzHeOxydaKdBIJC-hYfI3T1sFFBWPkyEjAmLPy6FI2FeFdKzFrIEOsKYyEQ_7R8uOzarTXnBr0wHBKyKqRhAmZpUO9ytMS2HHNd39Ta8kwDtkA848k-3XQ1J3we0r5w177Kp8jgZv2lmItu17Z3Q8xZbZNuZwdG2pyDUTJpoQRdbrhBFfPi2x5Arm3tSbOCX3eF_TOnFA5EPfuJF_OQkzFN1FgnJcXwY63VKcy4EzR02njK6WLDzECekK7ly_hAk83Rcon7NSWj0R-QCmtJu92MIwQ1VwOpfKZSG9s8w9V4TcFaRM7y_1CS8sa6hMiM6j1mvWsEk1pu-MyqsV-nZi6HRqtbCXAgrzkQ0JyrqHM17pLwoMC-YzHFVkYO2x9JvszbNg85QVC50e7HKEpg8DEfoXz-i686zxOCjEBTIzHEEs4L7ZgHm9wjKUdC7iyGdMxr1DhO4VFWxUENYJrDgFoUyHFmZbiz6tUzxYwZfYhJP-jb1UKNNYXl477kgmcr5x4nM0ShSWnKLiPUOkeez2D9THXLdPFliXiGfbL126AJMsSS16oiW9DaSfq6mikjiuBZhhLEKboRbzBVAAFx55BjWKs_x7O9MMbHGFeX5AQAfkgTbFKy92sahH_MimP7JQn7yx-AQefJpiKHt4aVoLTs2c09ytEgBQkY7m-zaRKAwCIUIa3IG4N2SU8aU0rDgg9_QXG6WV2G7M6GxEMqjeBU_o3CqS-2XP5lyxF5abY4yoxtiMbngXG-YrPcxQqMWX0SaRZSIp5vwKfc8CoELs0kmpZpJ3pJLwSCdmfrKqp4_fAGvYWB0UpAsUN9IqvYDROkCZlJMCh5X0N5U01jxjSOQFYDpQrkNQ4lwt1VQeAphH5ohPD0XRq3xm7amsouF6D2B0cmZIRSKf6yR013jL85RmKMxXQTHyFHLo5QCoUjgTfl6QfO11W7RUcitXtuG3Dthyx3NQ9Y9kypdZ3qJBg-RjQdIhJPVOUvjTDzka81tnLK3TisSjKEg8NSPeA0F-gihIPz5R88rKAWT_BKa4ugEjGuEKMdccglXmcFxkGMq-AR87t5Wfa9Ft2F5OS9rZuunpLXsHGRcQRvx46zfW_AvV0FOAgHDJvJ3FdWiIfN9Zazi5NnM5E-ZCtg9mlWYpxTn3_gljob8pOgD_AVltpsRMvgSmV5g_NwJTAqp8vQGQMNEg-ZFb3UtG4hpbHFre0CxQQ3iXfMF8bla5APL90ABvAtZHQMcsTaiOAMkCnzUmTVIgqcM4D2vH.wyRM3-165fGB8NIdapX8iA",
"domain": ".drouot.com",
"path": "/",
"expires": 1723274291.075802,
"httpOnly": false,
"secure": true,
"sameSite": "Lax"
},
{
"name": "aws.auth.id",
"value": "eyJraWQiOiJaTktsNEx3c1NcL0xyYVdwaGVtcHE4OWVLWk05eUtUemtUQW40ZlM2bXFtST0iLCJhbGciOiJSUzI1NiJ9.eyJzdWIiOiI1ODY0NWVjYS1mNDllLTQ1YTktOWI0ZC1lNTg0M2RhZWNjNWUiLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwiaXNzIjoiaHR0cHM6XC9cL2NvZ25pdG8taWRwLmV1LWNlbnRyYWwtMS5hbWF6b25hd3MuY29tXC9ldS1jZW50cmFsLTFfWE5GWDNIMzE0IiwiY29nbml0bzp1c2VybmFtZSI6IjU4NjQ1ZWNhLWY0OWUtNDVhOS05YjRkLWU1ODQzZGFlY2M1ZSIsIm9yaWdpbl9qdGkiOiI2YjUxMTM2Mi1kYmMwLTQ3MDctYjA0Zi05YTVmNzQyZjM5YjAiLCJhdWQiOiI0amNsZG9ib2YycWJuc3NtN2YxMDdnbGlxOCIsImV2ZW50X2lkIjoiNDAwNGViODItNDg1Mi00OTk2LWFjMjctNWQ1MTBiMmI3NTJmIiwidG9rZW5fdXNlIjoiaWQiLCJhdXRoX3RpbWUiOjE3MTY0NTU5MDUsImV4cCI6MTcxNjQ1OTUwNiwiaWF0IjoxNzE2NDU1OTA2LCJjdXN0b206cGFzc19pZCI6IjczOTAzMCIsImp0aSI6IjZjZjhmYjFlLWU1YTgtNDBkNS04NzkzLTk2YmRjNmZjMDU0ZCIsImVtYWlsIjoianAucmFudUBjb2dpcC5kZSJ9.I6lc4Y-fKSQJ1Vd5Lu41fP6_XuG9yaedk1ZKlXy3iyYV17HVxbypjkdTkgy1vbTU-QdS2gHcp9Ynf90q-PxkMuJZ_IWIU3njhoKE7--U4OkIPf7wfsFKq2rZGcUEyM0DxuedpRYbjN0Xesd6DF8nqWs5WGzy1NZDbXVys3ji0h5Y9H00bX7oypI_2ihFkcpRUYRzv8wywjBYoD8Jc7eOwqzeHNUkbs8L4ON2OnPCNBkJ33HKfw5Prnf4DahiZ9h6Vz0I2CTG4uIjI7yy0PpmDXz81-4JHy9G8NV2rEWTKUvJu1TWsMB5tRH50Ho3TBAqhUafKr1VB9uLTRg3gezsHw",
"value": "eyJraWQiOiJaTktsNEx3c1NcL0xyYVdwaGVtcHE4OWVLWk05eUtUemtUQW40ZlM2bXFtST0iLCJhbGciOiJSUzI1NiJ9.eyJzdWIiOiI1ODY0NWVjYS1mNDllLTQ1YTktOWI0ZC1lNTg0M2RhZWNjNWUiLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwiaXNzIjoiaHR0cHM6XC9cL2NvZ25pdG8taWRwLmV1LWNlbnRyYWwtMS5hbWF6b25hd3MuY29tXC9ldS1jZW50cmFsLTFfWE5GWDNIMzE0IiwiY29nbml0bzp1c2VybmFtZSI6IjU4NjQ1ZWNhLWY0OWUtNDVhOS05YjRkLWU1ODQzZGFlY2M1ZSIsIm9yaWdpbl9qdGkiOiJiOTZmZDY0Zi05MWEwLTRmMmMtYTk2OC1kYmRkNDcxMTY4ZDYiLCJhdWQiOiI0amNsZG9ib2YycWJuc3NtN2YxMDdnbGlxOCIsImV2ZW50X2lkIjoiZDU5ZWE4NWYtZjQ4ZC00MWE1LTlmOGItYWQ1Njk4N2FiYWJiIiwidG9rZW5fdXNlIjoiaWQiLCJhdXRoX3RpbWUiOjE3MjA3NzQyOTAsImV4cCI6MTcyMDc3Nzg5MSwiaWF0IjoxNzIwNzc0MjkxLCJjdXN0b206cGFzc19pZCI6IjczOTAzMCIsImp0aSI6IjIwYmQ0NDRkLTE1YWMtNDRiYi05NzliLTI4YjM1OTgxMjIzMiIsImVtYWlsIjoianAucmFudUBjb2dpcC5kZSJ9.DnFgUj9yehDb5Y3bTobAkm1S5Pa59GJBKOn65KVbiTA3ou_haxwRLNewchwHChyK6q8fZvmllXdPAnMdCcF44UAo7sYjGAJK9u47AMer3oi-luNtAZzC8Jt94KaBRMTJLC7s3fCIkcZcVBk9FoSRwfPxVjR-w4rT4TLcxJQNT4OqEk2UAoGhtU4KHDfGkj3zM7ttPaXYz3KgQ4vBlK5iJ8G8AtQuoR84V5ZIhRzVqNjjIPKxfsh6sgv2cYxw0ceZwHj0_3-FdtMsMa1JRamWy16hGULof-n84kmdlEsRefKDK_62t-gN1Ngi2wn37IFsfviaM3WC99K5HWUCATNSMg",
"domain": ".drouot.com",
"path": "/",
"expires": 1716459506.054849,
"expires": 1720777891.317947,
"httpOnly": false,
"secure": true,
"sameSite": "Lax"
}
],
"origins": [
{
"origin": "https://drouot.com",
"localStorage": [
{
"name": "sbt_i",
"value": "7ZmU0ZTAyMGUtMDY0YS00ODJlLTk4YjAtODQyZTEyZTVkOWNhOzNzAwNjZlMDQtNDE3ZC00MTU3LWFiMzctNWIxOWY4NmUyYmFlOzsA="
},
{
"name": "sbt_p",
"value": "H4sIAAAAAAAAAwGcAmP9/////x+LCAAAAAAAAAPtVstu00AUdYpUaCkLWMCylhrRlZETnJeEhNxkjCJIXdwUiLqo4mQiBaVx5aQUFkhFsIEVQohP4Ce6Cb+ABCskdpW64RfAQ31tZzxOL48uEDnSOOOZO8fnjO/4ZllKF1Q1n6eqpmiZQtu75ApK075eUHJ2ptQp5mnWbtK06kMRXACfDpfev05JEvyeABbBL+GXRlnm/PvLS/H4lBQ2GLuy7djdXpe68lXZsR/S4UBuLzfdoSTt3/ydOMClsl4nt0yrsbVC9I0HulVfH5PL68A857hFWCppnMnzLafXo61h1+kPeMGT5gAXAzM1c6V6p0oslBeeOqbflXH6Z9td1+Ph5SUMAy7ULd0wquV1c8MqE5TiCGNM7AApdmanxSsSDAHmK+RetUzqjTWcQp8qpm6YoC4gjEJ07M5axCAW92ah8wjp/UzH7fJORWOAuYreMI37hNxGmQeqmPs9pL5zHcelfcfp84ISJwKla94RNg1PL0rpGF9M7mOk3AXP71aSsomTgIWaWSOrdcQeA473+I8tPkFanG+7zq4zvNZytnkPE6YAsxWzpldXUXo5ujHFsC7doRpVsypV1LzWVLRiliqloq0qRS1LM1maa5daTRE5L0xUosZOXWqTH/ln8Nn3dsoO4DHTii4gn1b0aUWPQnQOpxV9WtEZ/tuKLklfFj/uHf7s7c/4JHffhtOBDVG5XnyGCBQhaRoU3GgkBMRYWPv2Jux/lSXpxUHI9PwAwxTysbX8p0SE7x7wzCH/Sf+CJiLyrtiSp5vYp7L28l3YP5K9+5GX9zA3wrkGvlcjnOAg+T/g438Vf3NXWdawDIIcZJnFGutDZgH3kR/H3gLbW9ZYH/Y2puEHt1WZzyMSAABay56MnAIAAM6uM7zWcrZ5DxOmALMVs6ZXV1F6OboxxbAu3aEaVbMqVdS81lS0YpYqpaKtKkUtSzNZmmuXWk0ROS9MVKLGTl1qkx/5Z/DZ93bKDuAx"
}
]
},
{
"origin": "https://auth.drouot.com",
"localStorage": [
{
"name": "CognitoIdentityServiceProvider.4jcldobof2qbnssm7f107gliq8.58645eca-f49e-45a9-9b4d-e5843daecc5e.accessToken",
"value": "eyJraWQiOiJYSTd2ejJDRW9pRVwvTnR0UGNkOEY0NE5QSDhHMzMzclJQRVB3OFFwRlJJRT0iLCJhbGciOiJSUzI1NiJ9.eyJzdWIiOiI1ODY0NWVjYS1mNDllLTQ1YTktOWI0ZC1lNTg0M2RhZWNjNWUiLCJpc3MiOiJodHRwczpcL1wvY29nbml0by1pZHAuZXUtY2VudHJhbC0xLmFtYXpvbmF3cy5jb21cL2V1LWNlbnRyYWwtMV9YTkZYM0gzMTQiLCJjbGllbnRfaWQiOiI0amNsZG9ib2YycWJuc3NtN2YxMDdnbGlxOCIsIm9yaWdpbl9qdGkiOiI2YjUxMTM2Mi1kYmMwLTQ3MDctYjA0Zi05YTVmNzQyZjM5YjAiLCJldmVudF9pZCI6IjQwMDRlYjgyLTQ4NTItNDk5Ni1hYzI3LTVkNTEwYjJiNzUyZiIsInRva2VuX3VzZSI6ImFjY2VzcyIsInNjb3BlIjoiYXdzLmNvZ25pdG8uc2lnbmluLnVzZXIuYWRtaW4iLCJhdXRoX3RpbWUiOjE3MTY0NTU5MDUsImV4cCI6MTcxNjQ1OTUwNiwiaWF0IjoxNzE2NDU1OTA2LCJqdGkiOiJkOGViNmNlNS00ZTE3LTRiZmQtYWVkNy01MjBmNzZlOGU2NGYiLCJ1c2VybmFtZSI6IjU4NjQ1ZWNhLWY0OWUtNDVhOS05YjRkLWU1ODQzZGFlY2M1ZSJ9.ltgmmPsITav_sGRrsc7AJz7GzViEGpWc_0qly3dVkZPZfL_NpDxIEz0_-XaikQd_Al_WYZ_k5yvh3DeDJzM4TiBFVVQDPydBb3IkeEj0x7djK_Yj5JUXM-SxaDIrtCkzXhxrwt_SCa0wkeKoPGfHSDt75-NYo4LXeZ15tntnsox-RoasVEop4HXBejWsfOiBsqptd4N8vCrK67nxiuNHTWZYylUz72iwMxtgwSvMVVNVV3FzU2N-puM8QvHhZQ96tCq0-jwTBVwR-DRdHL7IwbStze3-c53LFxbBmreXKn4aGiQybTEEwpDASeU0-YOl-Hgw4BD9gyOv2ECbINeiGw"
"value": "eyJraWQiOiJYSTd2ejJDRW9pRVwvTnR0UGNkOEY0NE5QSDhHMzMzclJQRVB3OFFwRlJJRT0iLCJhbGciOiJSUzI1NiJ9.eyJzdWIiOiI1ODY0NWVjYS1mNDllLTQ1YTktOWI0ZC1lNTg0M2RhZWNjNWUiLCJpc3MiOiJodHRwczpcL1wvY29nbml0by1pZHAuZXUtY2VudHJhbC0xLmFtYXpvbmF3cy5jb21cL2V1LWNlbnRyYWwtMV9YTkZYM0gzMTQiLCJjbGllbnRfaWQiOiI0amNsZG9ib2YycWJuc3NtN2YxMDdnbGlxOCIsIm9yaWdpbl9qdGkiOiJiOTZmZDY0Zi05MWEwLTRmMmMtYTk2OC1kYmRkNDcxMTY4ZDYiLCJldmVudF9pZCI6ImQ1OWVhODVmLWY0OGQtNDFhNS05ZjhiLWFkNTY5ODdhYmFiYiIsInRva2VuX3VzZSI6ImFjY2VzcyIsInNjb3BlIjoiYXdzLmNvZ25pdG8uc2lnbmluLnVzZXIuYWRtaW4iLCJhdXRoX3RpbWUiOjE3MjA3NzQyOTAsImV4cCI6MTcyMDc3Nzg5MSwiaWF0IjoxNzIwNzc0MjkxLCJqdGkiOiJjMThlYjZjMi0yMGUyLTRmNmUtOWExMi02ZmM4NmVhMGE0ODgiLCJ1c2VybmFtZSI6IjU4NjQ1ZWNhLWY0OWUtNDVhOS05YjRkLWU1ODQzZGFlY2M1ZSJ9.AbzC8YGLJqrMxcXYxbCW8XNMEQSZh-hgeWrfr7l-TdZ5aRa_M-U1ZffZWQtkotMuy1C6mBlItxFDTTt5iO2N0ijUzER3BVfIqZG_xzGf74eNcS64Y64mrSw2U5MLAhmXaLNFlbjhBj9IYyOUMZJE0RexIQByXzo0Yh72XUMWJKP1IEMgGlO-KqY3hoEnD7KJrgu0VMgOzvrITQ4dizeux-v8McEG79MKwyl810H_x0GzY_-L9LfTIZ_IfOHg6OuHnY-nfg5EY7NyvVEvNwZsuH7yjjLYIm2hcrryN0p_obwMYos6NDuo8NQNyP0iDTZeviQsR1iRp9Jtsh4w1pj0Sw"
},
{
"name": "persist:root",
@ -75,7 +118,7 @@
},
{
"name": "CognitoIdentityServiceProvider.4jcldobof2qbnssm7f107gliq8.58645eca-f49e-45a9-9b4d-e5843daecc5e.clockDrift",
"value": "-1"
"value": "0"
},
{
"name": "amplify-signin-with-hostedUI",
@ -91,11 +134,11 @@
},
{
"name": "CognitoIdentityServiceProvider.4jcldobof2qbnssm7f107gliq8.58645eca-f49e-45a9-9b4d-e5843daecc5e.idToken",
"value": "eyJraWQiOiJaTktsNEx3c1NcL0xyYVdwaGVtcHE4OWVLWk05eUtUemtUQW40ZlM2bXFtST0iLCJhbGciOiJSUzI1NiJ9.eyJzdWIiOiI1ODY0NWVjYS1mNDllLTQ1YTktOWI0ZC1lNTg0M2RhZWNjNWUiLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwiaXNzIjoiaHR0cHM6XC9cL2NvZ25pdG8taWRwLmV1LWNlbnRyYWwtMS5hbWF6b25hd3MuY29tXC9ldS1jZW50cmFsLTFfWE5GWDNIMzE0IiwiY29nbml0bzp1c2VybmFtZSI6IjU4NjQ1ZWNhLWY0OWUtNDVhOS05YjRkLWU1ODQzZGFlY2M1ZSIsIm9yaWdpbl9qdGkiOiI2YjUxMTM2Mi1kYmMwLTQ3MDctYjA0Zi05YTVmNzQyZjM5YjAiLCJhdWQiOiI0amNsZG9ib2YycWJuc3NtN2YxMDdnbGlxOCIsImV2ZW50X2lkIjoiNDAwNGViODItNDg1Mi00OTk2LWFjMjctNWQ1MTBiMmI3NTJmIiwidG9rZW5fdXNlIjoiaWQiLCJhdXRoX3RpbWUiOjE3MTY0NTU5MDUsImV4cCI6MTcxNjQ1OTUwNiwiaWF0IjoxNzE2NDU1OTA2LCJjdXN0b206cGFzc19pZCI6IjczOTAzMCIsImp0aSI6ImIwNDEyYTBmLTZiN2UtNDc1YS04NTAyLTU0YmY5ODU5MzkxMiIsImVtYWlsIjoianAucmFudUBjb2dpcC5kZSJ9.Qfnv42vNIezdxohbyA1rF_ebfjeqx-LReTDOsYyWxwXdJC7yceu2P84Chr0DvZ0bo2dVtvgsL4TAV1pwFNjqMr5xSzcFNwDF-MzgBRtRWQ6R5OnHN1IX0zUFP9qZkuhaJMCz2kId84C_1YaXhDKqrK_qcvQ_-W1J11yfEbS4kVVZXf70Ko2eAq4XnTjtnTWURjEHM7KTpAehqoxGG96kmaOz4DQ6BKsGdg8BvuG9W7G9wEoU6pBSPgblnTyVvqYvoOrG_TbK3T0K-a3xyWfeEnqW3omTyN_lWhLInZYCejIqxkgVgqGguZxgB5AV0JC77pyxEKs2DRu642mlsqEDZQ"
"value": "eyJraWQiOiJaTktsNEx3c1NcL0xyYVdwaGVtcHE4OWVLWk05eUtUemtUQW40ZlM2bXFtST0iLCJhbGciOiJSUzI1NiJ9.eyJzdWIiOiI1ODY0NWVjYS1mNDllLTQ1YTktOWI0ZC1lNTg0M2RhZWNjNWUiLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwiaXNzIjoiaHR0cHM6XC9cL2NvZ25pdG8taWRwLmV1LWNlbnRyYWwtMS5hbWF6b25hd3MuY29tXC9ldS1jZW50cmFsLTFfWE5GWDNIMzE0IiwiY29nbml0bzp1c2VybmFtZSI6IjU4NjQ1ZWNhLWY0OWUtNDVhOS05YjRkLWU1ODQzZGFlY2M1ZSIsIm9yaWdpbl9qdGkiOiJiOTZmZDY0Zi05MWEwLTRmMmMtYTk2OC1kYmRkNDcxMTY4ZDYiLCJhdWQiOiI0amNsZG9ib2YycWJuc3NtN2YxMDdnbGlxOCIsImV2ZW50X2lkIjoiZDU5ZWE4NWYtZjQ4ZC00MWE1LTlmOGItYWQ1Njk4N2FiYWJiIiwidG9rZW5fdXNlIjoiaWQiLCJhdXRoX3RpbWUiOjE3MjA3NzQyOTAsImV4cCI6MTcyMDc3Nzg5MSwiaWF0IjoxNzIwNzc0MjkxLCJjdXN0b206cGFzc19pZCI6IjczOTAzMCIsImp0aSI6ImJhYzZlZGYxLTRiNGQtNDlkOC04ZDQ4LWY1ZWVkNWM2MmZhOSIsImVtYWlsIjoianAucmFudUBjb2dpcC5kZSJ9.B9XsvDvfUatg9Mf0EEX-Z1tTi7bBzqZisa_8UaBR24O1nov_86N7XnPPVc92NtdXcHZItaSBQxAPPhWdHBwW-W8JAAoCHFo7LoouakwR8i5zfaMFG5JWhsf4Ifw6vqbxTnRUdOawBUlrr6saJgeo9uKyMd-KwBdxwMIuASNtZ0glVUecHPeHhoU_QVNTYzkAhVYiBHPF3YvyOYuRuW7gDI5mD26oMZm62XoekEq1IK-hq_P_BzmJ0b6RZZASvvo5CCkjlGUF8eweYwMfGROYaGh5e6K6wcN-C2R3MnXKROifGCTaoBEnCdt990WNNwbUY9CtinQanhZ6m11CI7ZkQg"
},
{
"name": "CognitoIdentityServiceProvider.4jcldobof2qbnssm7f107gliq8.58645eca-f49e-45a9-9b4d-e5843daecc5e.refreshToken",
"value": "eyJjdHkiOiJKV1QiLCJlbmMiOiJBMjU2R0NNIiwiYWxnIjoiUlNBLU9BRVAifQ.ej0FDIw3VwTFabbv_Xrthwn6QRxOrGSlTP8P-hM3xyDmhigcIepCgEUlgjSO-taBevdDgiDNuRZ2ymbsmSHjBTgtPPhBJMlNW1CJMFpf34cnHp8P8fNso7KVZH98CVT8a-klxeNUw8sJbzV76E2pefGPiKahMbgNcct6I4C0lmK60569b1ADgDJUXoZ3ZWLM5h7dmu2_zEwcu3rcJSAZvqLBQBrBhw1ck2tivoMVl0Rp3rRDmYCkbvjYpVxozv_KCBA1pKdm_n1E78T4nlJR12UVZKwGj4TnM3_AiV43J-FUKkj-rDEoPfJrWlZh0J3aV403sDGeO_R7C8zOvMz8qQ.HTEsnaMZSmoB5bMT.CPMenx7Y1fkZnG3xdudDXwto0S9nXhlrviwGAUaEV0PdAiN1JRyWyfd2gfZ9gqDJ6CxBog-kZ45nttrdY2JjS71HgBfrg3RAqRqUyiRd9OLUTtHXgysdf6tXGZYqm2j62uTzq5aYWwr_KUMEYKqH45TrxAEnBGlCaKX5ielLghK6ZA_EWrOK3oJW3aM_-mZKD0vrJd9_iwVAUMKk_hdCF1UFqsuVHXZqXxQ_iOPzyd_t5Ui_2WgVqqLZTteAsFwr_L_TqpoM11AgSH-8a1ad05JwCdeMxyhZnW8Gf172Yt7pVzUFuV491KAxXdsgxCbFIhReYhOqABCsS9fKKbi6VBDtDBrRqGeiHgfOapVMLeg8-Va-_YGa1_4oRbX_zye_HTz3WE-xmBBwt98PVEJp4pWr2lY7wDgisqzLgI8foWm1YVWFD5rypAsJxEu-9-25SVErMVlptRaZ650YFHWNrkEr3oeqzwriIxMEjm92gxgVPQOO0Q5gqj9WcUHrbeq01xr6WBhX84AqGqTpT-kxbSrFBxHFMM3zhPey4ElJ2unc_ppj2r96e3FNjTmhRdhYYz827oewmJZZwhAF2KI8a_MEz6-W18b5ju0teM4lWBWRedq8IMeTFuEZ8-nlkQTiDnsSFXqZNtFVfJGcbKKTX8LCm708DrG5QGvqjycOkXrrnw-OCaUibCWbymJzwYdPD1sLLhitMpgI6pKW8H74K7bIb_v2IeMo3hH9gm2n6SI120EpD7n74UCIGx1fn5CB28neuj-_BegrcZNd6KEs0iPEhNOpHKd7k_G8riKX-ZtKIQcqZ8MtwAvjWVVFELEkpXR2IwfW2jXzBObIvcDYYNVijroFUZ-8oObp0dAIaUFtoByIzw3VOzOc4qbCSyelFC1YyoZJgbNW2ic6ZvL8pdzYTogjI_XHakVLBk8jeRg95SXtz9XzpLyx_ZoTX5LzEh5T897tOePl1NmIptU17IiBuwxFj_nYoVgDYbbGz1ox9vEWdrAE6EpfzhFrxWVMijyfjyauWaixri-harPAbhirrGG7QEeURqv0LCMMy1w3LyaZ9p9saG3DzX0yzrERgXMNvbFi4OYY3Cb0O8bo0kjHVY7a6Yj_qKKpfIKGclRKmndxkLK5A6JJkqy4fSLK-v9RbpWUiTC-_0L2k9lEGiK5rgPhMSRhyI5XYUW1rbB_XEKPU12M5uxER0NvjomXgTUy0yOdbDfpIYb89Bs2BK-SE0MAJSepzC8bsW4CWOnfCWGnuOGQphRfCuxAIkvd-4Lwm-Nyt8-Mmvh5VhQw79v8mx2eZNzk4DyiTDbSQUwdoCoEpgyoQnvnxObYVxXUeixB.LW8iCOUVXGCbeHw2rTF6Uw"
"value": "eyJjdHkiOiJKV1QiLCJlbmMiOiJBMjU2R0NNIiwiYWxnIjoiUlNBLU9BRVAifQ.imuPu0l2BWRSCp5Deo-kkfjqrbXvrMOC7aLb73FLvWMEbZ_8wYPMIYDBVxWXCOue9lBOYWmBZ-gYmOpFjuub48kr0YH2XmS0CWvAjVaFOd1SLtA1JqPNCjzOhr4HqHNzY2p1v-LlWVkZMb6yzSJCo2i69X_uMhjI7vkwF5JBRLPfnhgpbTtuAfShe2fxwFVF3wcnIGwxwf9Mewftjw0vYAnU25kcUALthY_7os1vXG10B0HLJFlfG8AA0AZgOWin7YEYtNCR0fyILwVQLLrwrN1Df9I6nw0BT82u37GAZSihBNUekCBmLRf_eLad4DACY5YTwywzQjfLWIv6by0SYQ.32xpzYSlssbruFav.hmnVMOwHMa4fnXFrO_Eu402cEKhzl-uS_62OC51WXTOrY0qSXAGSjQLUleR8Aznkugbt738kCq7wzHeOxydaKdBIJC-hYfI3T1sFFBWPkyEjAmLPy6FI2FeFdKzFrIEOsKYyEQ_7R8uOzarTXnBr0wHBKyKqRhAmZpUO9ytMS2HHNd39Ta8kwDtkA848k-3XQ1J3we0r5w177Kp8jgZv2lmItu17Z3Q8xZbZNuZwdG2pyDUTJpoQRdbrhBFfPi2x5Arm3tSbOCX3eF_TOnFA5EPfuJF_OQkzFN1FgnJcXwY63VKcy4EzR02njK6WLDzECekK7ly_hAk83Rcon7NSWj0R-QCmtJu92MIwQ1VwOpfKZSG9s8w9V4TcFaRM7y_1CS8sa6hMiM6j1mvWsEk1pu-MyqsV-nZi6HRqtbCXAgrzkQ0JyrqHM17pLwoMC-YzHFVkYO2x9JvszbNg85QVC50e7HKEpg8DEfoXz-i686zxOCjEBTIzHEEs4L7ZgHm9wjKUdC7iyGdMxr1DhO4VFWxUENYJrDgFoUyHFmZbiz6tUzxYwZfYhJP-jb1UKNNYXl477kgmcr5x4nM0ShSWnKLiPUOkeez2D9THXLdPFliXiGfbL126AJMsSS16oiW9DaSfq6mikjiuBZhhLEKboRbzBVAAFx55BjWKs_x7O9MMbHGFeX5AQAfkgTbFKy92sahH_MimP7JQn7yx-AQefJpiKHt4aVoLTs2c09ytEgBQkY7m-zaRKAwCIUIa3IG4N2SU8aU0rDgg9_QXG6WV2G7M6GxEMqjeBU_o3CqS-2XP5lyxF5abY4yoxtiMbngXG-YrPcxQqMWX0SaRZSIp5vwKfc8CoELs0kmpZpJ3pJLwSCdmfrKqp4_fAGvYWB0UpAsUN9IqvYDROkCZlJMCh5X0N5U01jxjSOQFYDpQrkNQ4lwt1VQeAphH5ohPD0XRq3xm7amsouF6D2B0cmZIRSKf6yR013jL85RmKMxXQTHyFHLo5QCoUjgTfl6QfO11W7RUcitXtuG3Dthyx3NQ9Y9kypdZ3qJBg-RjQdIhJPVOUvjTDzka81tnLK3TisSjKEg8NSPeA0F-gihIPz5R88rKAWT_BKa4ugEjGuEKMdccglXmcFxkGMq-AR87t5Wfa9Ft2F5OS9rZuunpLXsHGRcQRvx46zfW_AvV0FOAgHDJvJ3FdWiIfN9Zazi5NnM5E-ZCtg9mlWYpxTn3_gljob8pOgD_AVltpsRMvgSmV5g_NwJTAqp8vQGQMNEg-ZFb3UtG4hpbHFre0CxQQ3iXfMF8bla5APL90ABvAtZHQMcsTaiOAMkCnzUmTVIgqcM4D2vH.wyRM3-165fGB8NIdapX8iA"
}
]
}

View File

@ -0,0 +1 @@
{"token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI2Njc5YTA2ZmRjY2NiYmUwMGMzYTc4NjgiLCJlbWFpbCI6ImFnZW50QGFnZW50LmNvbSIsImlhdCI6MTcyMjk1NTI3NywiZXhwIjoxNzI1NTQ3Mjc3LCJhdWQiOiJ5b3Vyc2l0ZSIsImlzcyI6Imp1Y3VuZHVzLmNvbSJ9.K9uGLVH42tfajV7mt_G66-iZVmgUFNLBmPNKinZ4B4o"}

View File

@ -15,6 +15,9 @@ RUN apt-get update && apt-get install gnupg wget -y && \
# Install Playwright
RUN npx -y playwright@1.44.0 install --with-deps
# install ffmpeg
RUN apt-get update && apt-get install ffmpeg -y
# Setting up the work directory
WORKDIR /agent

0
agent/config.js Executable file
View File

View File

@ -4,9 +4,6 @@ const app = express()
var bodyParser = require('body-parser');
app.use(bodyParser.json())
//const puppeteer = require('puppeteer');
//const puppeteerPackage = require('puppeteer/package.json');
const puppeteer = require('puppeteer-extra');
const pluginStealth = require('puppeteer-extra-plugin-stealth');
puppeteer.use(pluginStealth())

View File

@ -0,0 +1,25 @@
const { Key } = require("../.Key.js");
const validateInternToken = () => {
return (req, res, next) => {
const token = req.headers['authorization'];
console.log(`Token provided: ${token}`);
if (!token) {
console.log("No token provided");
return res.status(403).send({ message: 'No token provided.' });
}
console.log(`Expected token: ${Key.internToken}`);
if (token === Key.internToken) {
console.log("Token valid, calling next()");
next();
} else {
console.log("Unauthorized access attempt");
return res.status(401).send({ message: 'Unauthorized.' });
}
}
}
module.exports = { validateInternToken };

View File

@ -15,6 +15,7 @@
"express-async-handler": "^1.2.0",
"moment-timezone": "^0.5.45",
"node-fetch": "^2.6.1",
"node-webrtc": "^0.0.0",
"protobufjs": "^7.3.0",
"puppeteer": "^22.10.0",
"puppeteer-extra": "^3.3.6",
@ -1776,6 +1777,17 @@
}
}
},
"node_modules/node-webrtc": {
"version": "0.0.0",
"resolved": "https://registry.npmjs.org/node-webrtc/-/node-webrtc-0.0.0.tgz",
"integrity": "sha512-8EXsvPcAhveVs8IOyglv0F6tdzYVgJ5ujoXVk+XRw/UoCifCsoi2oARkG0HcYUL2j0U8kNPMsVU3SFaFxMZMeA==",
"bin": {
"node-webrtc": "bin/node-webrtc"
},
"engines": {
"node": ">= 0.5.0 < 0.7.0"
}
},
"node_modules/nodemon": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.0.tgz",

View File

@ -17,6 +17,7 @@
"express-async-handler": "^1.2.0",
"moment-timezone": "^0.5.45",
"node-fetch": "^2.6.1",
"node-webrtc": "^0.0.0",
"protobufjs": "^7.3.0",
"puppeteer": "^22.10.0",
"puppeteer-extra": "^3.3.6",

View File

@ -1,6 +1,7 @@
const controllers = require('../controllers/follow')
const router = require('express').Router()
const { validateInternToken } = require('../middleware/validateToken');
router.get('/sale/:url', controllers.sale)
router.get('/sale/:url',validateInternToken(), controllers.sale)
module.exports = router

12
config.js Normal file
View File

@ -0,0 +1,12 @@
const config = {
jucundus: {
url: 'http://host.docker.internal:3000',
useremail: 'agent@agent.com'
},
agent: {
urlApi: 'http://agent/internApi',
maxCloseWebsockets: 5,
}
};
module.exports = { config };

View File

@ -7,6 +7,8 @@ services:
dockerfile: Dockerfile.dev
volumes:
- ./agent:/agent
- ./.Key.js:/agent/.Key.js
- ./config.js:/agent/config.js
- ./AuctionServices:/agent/AuctionServices
networks:
- internal
@ -21,6 +23,8 @@ services:
- 3020:3020
volumes:
- ./scrapper:/scrapper
- ./.Key.js:/scrapper/.Key.js
- ./config.js:/scrapper/config.js
- ./AuctionServices:/scrapper/AuctionServices
networks:
- internal

0
scrapper/config.js Executable file
View File

View File

@ -5,6 +5,9 @@ const {ScraperTools} = require('../AuctionServices/Scraper/Scraper.js')
const Drouot = require('../AuctionServices/Scraper/Drouot/Drouot.js')
const Interencheres = require('../AuctionServices/Scraper/Interencheres/Interencheres.js')
const {config} = require('../config.js');
const { Key } = require("../.Key.js");
let getAuctionPlatform = function(Url){
@ -88,7 +91,7 @@ exports.getLotList = asyncHandler(async (req, res, next) => {
}
});
// ## AGENT PUPPETEER
// ## AGENT PUPPETEER/PLAYWRIGHT
//Follow a live Sale
exports.followSale = asyncHandler(async (req, res, next) => {
@ -103,12 +106,16 @@ exports.followSale = asyncHandler(async (req, res, next) => {
try{
let AuctionPlatform = getAuctionPlatform(url);
if(AuctionPlatform){
console.log('Scrapper followSale : '+encodeURIComponent(url))
fetch('http://agent/internApi/follow/sale/'+encodeURIComponent(url))
fetch(config.agent.urlApi+'/follow/sale/'+encodeURIComponent(url),{
headers: {
'authorization': Key.internToken
}
})
.then(response => {
console.log("fetch OK")
//response.json()
} )
console.log("fetch OK")
//response.json()
} )
.then(saleInfo => {})
.catch(error => {
console.error(error);

View File

@ -0,0 +1,24 @@
const { Key } = require("../.Key.js");
const validateToken = () => {
return (req, res, next) => {
const token = req.headers['authorization'];
if (!token) {
console.log("No token provided");
return res.status(403).send({ message: 'No token provided.' });
}
console.log(`Expected token: ${Key.token}`);
if (token === Key.token) {
console.log("Token valid, calling next()");
next();
} else {
console.log("Unauthorized access attempt");
return res.status(401).send({ message: 'Unauthorized.' });
}
}
}
module.exports = { validateToken };

View File

@ -1,7 +1,8 @@
const controllers = require('../controllers/lot')
const router = require('express').Router()
const { validateToken } = require('../middleware/validateToken');
router.get('/getPictures/:url', controllers.getPictures)
router.get('/getInfos/:url', controllers.getInfos)
router.get('/getPictures/:url', validateToken(),controllers.getPictures)
router.get('/getInfos/:url', validateToken(),controllers.getInfos)
module.exports = router

View File

@ -1,8 +1,9 @@
const controllers = require('../controllers/sale')
const router = require('express').Router()
const { validateToken } = require('../middleware/validateToken');
router.get('/getSaleInfos/:url', controllers.getSaleInfos)
router.get('/getLotList/:url', controllers.getLotList)
router.get('/followSale/:url', controllers.followSale)
router.get('/getSaleInfos/:url', validateToken(), controllers.getSaleInfos)
router.get('/getLotList/:url', validateToken(), controllers.getLotList)
router.get('/followSale/:url', validateToken(), controllers.followSale)
module.exports = router