Spaces:
Running
Running
Update index.js
Browse files
index.js
CHANGED
@@ -1,260 +1,312 @@
|
|
1 |
const express = require('express');
|
2 |
-
const
|
3 |
-
const
|
|
|
4 |
|
5 |
const app = express();
|
6 |
-
|
7 |
-
|
8 |
-
//
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
// Domain servers
|
35 |
-
const nameservers = data.match(/Domain Servers:\n([\s\S]*?)\n\n/)?.[1]?.trim().split('\n');
|
36 |
-
|
37 |
-
// Additional info (Created and Expiry dates)
|
38 |
-
const createdDate = data.match(/Created on.*:\s*(.*)/)?.[1]?.trim();
|
39 |
-
const expiresDate = data.match(/Expires on.*:\s*(.*)/)?.[1]?.trim();
|
40 |
-
|
41 |
-
// Last update time
|
42 |
-
const lastUpdateTime = data.match(/Last Update Time:\s*(.*)/)?.[1]?.trim();
|
43 |
-
|
44 |
-
return {
|
45 |
-
domainName,
|
46 |
-
domainStatus,
|
47 |
-
frozenStatus,
|
48 |
-
transferStatus,
|
49 |
-
registrant,
|
50 |
-
registrar: {
|
51 |
-
nicHandle,
|
52 |
-
registrarName,
|
53 |
-
registrarAddress,
|
54 |
-
registrarPhone,
|
55 |
-
registrarFax
|
56 |
-
},
|
57 |
-
nameservers,
|
58 |
-
createdDate,
|
59 |
-
expiresDate,
|
60 |
-
lastUpdateTime
|
61 |
-
};
|
62 |
};
|
63 |
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
'sec-fetch-mode': 'navigate',
|
81 |
-
'sec-fetch-site': 'same-origin',
|
82 |
-
'sec-fetch-user': '?1',
|
83 |
-
'upgrade-insecure-requests': '1',
|
84 |
-
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36 Edg/129.0.0.0'
|
85 |
-
}
|
86 |
});
|
|
|
87 |
|
88 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
89 |
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
94 |
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
|
|
102 |
}
|
|
|
103 |
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
}
|
112 |
-
|
113 |
-
setInterval(sendRequestAndSetGlobals, 3600000);
|
114 |
-
|
115 |
-
app.use((req, res, next) => {
|
116 |
-
const startTime = Date.now();
|
117 |
-
requestsCount++;
|
118 |
-
next();
|
119 |
-
const endTime = Date.now();
|
120 |
-
totalTime += endTime - startTime;
|
121 |
-
averageResponseTime = (totalTime / requestsCount).toFixed(2);
|
122 |
-
|
123 |
-
// track domains queried
|
124 |
-
if (req.query.domain) {
|
125 |
-
const domain = req.query.domain;
|
126 |
-
if (!domainsQueried[domain]) {
|
127 |
-
domainsQueried[domain] = 1;
|
128 |
-
} else {
|
129 |
-
domainsQueried[domain]++;
|
130 |
}
|
131 |
-
}
|
132 |
});
|
133 |
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
}
|
143 |
-
};
|
144 |
-
|
145 |
-
res.json(stats);
|
146 |
});
|
147 |
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
'https://www.trabis.gov.tr/search-domain',
|
158 |
-
new URLSearchParams({
|
159 |
-
_token: token,
|
160 |
-
domain: domain
|
161 |
-
}),
|
162 |
-
{
|
163 |
-
headers: {
|
164 |
-
'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
|
165 |
-
'accept-language': 'en,tr;q=0.9,en-GB;q=0.8,en-US;q=0.7',
|
166 |
-
'cache-control': 'max-age=0',
|
167 |
-
'content-type': 'application/x-www-form-urlencoded',
|
168 |
-
'cookie': cookies,
|
169 |
-
'origin': 'https://www.trabis.gov.tr',
|
170 |
-
'priority': 'u=0, i',
|
171 |
-
'referer': 'https://www.trabis.gov.tr/',
|
172 |
-
'sec-ch-ua': '"Microsoft Edge";v="129", "Not=A?Brand";v="8", "Chromium";v="129"',
|
173 |
-
'sec-ch-ua-mobile': '?0',
|
174 |
-
'sec-ch-ua-platform': '"Windows"',
|
175 |
-
'sec-fetch-dest': 'document',
|
176 |
-
'sec-fetch-mode': 'navigate',
|
177 |
-
'sec-fetch-site': 'same-origin',
|
178 |
-
'sec-fetch-user': '?1',
|
179 |
-
'upgrade-insecure-requests': '1',
|
180 |
-
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36 Edg/129.0.0.0'
|
181 |
-
}
|
182 |
-
}
|
183 |
-
);
|
184 |
-
|
185 |
-
const html = response.data;
|
186 |
-
const $ = cheerio.load(html);
|
187 |
-
|
188 |
-
const keywords = {
|
189 |
-
Belgeli: false,
|
190 |
-
Belgesiz: false,
|
191 |
-
kullanımdadır: false,
|
192 |
-
başvurulmuş: false,
|
193 |
-
tahsis: false
|
194 |
-
};
|
195 |
-
|
196 |
-
// Search for the keywords
|
197 |
-
const text = $('body').text();
|
198 |
-
keywords.Belgeli = text.includes('Belgeli');
|
199 |
-
keywords.Belgesiz = text.includes('Belgesiz');
|
200 |
-
keywords.kullanımdadır = text.includes('kullanımdadır');
|
201 |
-
keywords.başvurulmuş = text.includes('başvuruldu');
|
202 |
-
|
203 |
-
// Check for reassignment text and extract date
|
204 |
-
let reassignmentDate = null;
|
205 |
-
if (text.includes('yeniden tahsis listesinde')) {
|
206 |
-
keywords.tahsis = true;
|
207 |
-
const dateMatch = text.match(/(\d{2}\/\d{2}\/\d{4}) tarihinden itibaren/);
|
208 |
-
if (dateMatch) {
|
209 |
-
reassignmentDate = dateMatch[1];
|
210 |
-
}
|
211 |
}
|
|
|
212 |
|
213 |
-
|
214 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
215 |
}
|
|
|
216 |
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
whoisData = extractData(whoisData);
|
226 |
-
res.json({
|
227 |
-
domain,
|
228 |
-
status: keywords,
|
229 |
-
whoisData,
|
230 |
-
...(reassignmentDate && { reassignmentDate })
|
231 |
-
});
|
232 |
-
} else {
|
233 |
-
res.json({
|
234 |
-
domain,
|
235 |
-
status: keywords,
|
236 |
-
...(reassignmentDate && { reassignmentDate })
|
237 |
-
});
|
238 |
}
|
|
|
239 |
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
|
|
|
|
|
|
|
|
245 |
});
|
246 |
|
247 |
-
//
|
248 |
-
app.
|
249 |
-
|
250 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
251 |
|
252 |
-
//
|
253 |
-
app.
|
254 |
-
|
255 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
256 |
|
257 |
-
|
258 |
-
|
259 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
260 |
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
const express = require('express');
|
2 |
+
const bodyParser = require('body-parser');
|
3 |
+
const DomainNameAPI = require('./index');
|
4 |
+
const crypto = require('crypto');
|
5 |
|
6 |
const app = express();
|
7 |
+
app.use(bodyParser.json());
|
8 |
+
|
9 |
+
// Initialize the Domain API client
|
10 |
+
const api = new DomainNameAPI(process.env.API_USERNAME || 'harmon', process.env.API_PASSWORD || 'PrivatePass123#');
|
11 |
+
|
12 |
+
// Authorization middleware
|
13 |
+
const authorizeRequest = (req, res, next) => {
|
14 |
+
const authHeader = req.headers.authorization;
|
15 |
+
if (!authHeader || !authHeader.startsWith('Bearer ')) {
|
16 |
+
return res.status(401).json({
|
17 |
+
success: false,
|
18 |
+
error: 'Authorization header missing or invalid format'
|
19 |
+
});
|
20 |
+
}
|
21 |
+
|
22 |
+
const token = authHeader.split(' ')[1];
|
23 |
+
const today = new Date().toLocaleDateString('en-US', { weekday: 'long' }).toLowerCase();
|
24 |
+
const expectedToken = crypto.createHash('sha256').update(today + 'harmon').digest('hex');
|
25 |
+
|
26 |
+
if (token !== expectedToken) {
|
27 |
+
return res.status(401).json({
|
28 |
+
success: false,
|
29 |
+
error: 'Invalid token'
|
30 |
+
});
|
31 |
+
}
|
32 |
+
|
33 |
+
next();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
34 |
};
|
35 |
|
36 |
+
// Apply authorization middleware to all /api routes
|
37 |
+
app.use('/api', authorizeRequest);
|
38 |
+
|
39 |
+
// Root endpoint
|
40 |
+
app.get('/', (req, res) => {
|
41 |
+
res.json({
|
42 |
+
success: true,
|
43 |
+
message: 'Domain Name API Server',
|
44 |
+
version: '1.0.0',
|
45 |
+
endpoints: {
|
46 |
+
root: '/',
|
47 |
+
domains: '/api/domains',
|
48 |
+
balance: '/api/balance',
|
49 |
+
tlds: '/api/tlds',
|
50 |
+
reseller: '/api/reseller'
|
51 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
52 |
});
|
53 |
+
});
|
54 |
|
55 |
+
// Middleware to handle errors
|
56 |
+
const errorHandler = (err, req, res, next) => {
|
57 |
+
console.error(err.stack);
|
58 |
+
res.status(500).json({
|
59 |
+
success: false,
|
60 |
+
error: err.message
|
61 |
+
});
|
62 |
+
};
|
63 |
|
64 |
+
// Add Child Name Server endpoint
|
65 |
+
app.post('/api/domains/:domainName/childNameServer', async (req, res, next) => {
|
66 |
+
try {
|
67 |
+
const { domainName } = req.params;
|
68 |
+
const { nameServer, ipAddress } = req.body;
|
69 |
+
const result = await api.AddChildNameServer(domainName, nameServer, ipAddress);
|
70 |
+
res.json(result);
|
71 |
+
} catch (error) {
|
72 |
+
next(error);
|
73 |
+
}
|
74 |
+
});
|
75 |
|
76 |
+
// Delete Child Name Server endpoint
|
77 |
+
app.delete('/api/domains/:domainName/childNameServer/:nameServer', async (req, res, next) => {
|
78 |
+
try {
|
79 |
+
const { domainName, nameServer } = req.params;
|
80 |
+
const result = await api.DeleteChildNameServer(domainName, nameServer);
|
81 |
+
res.json(result);
|
82 |
+
} catch (error) {
|
83 |
+
next(error);
|
84 |
}
|
85 |
+
});
|
86 |
|
87 |
+
// Modify Child Name Server endpoint
|
88 |
+
app.put('/api/domains/:domainName/childNameServer', async (req, res, next) => {
|
89 |
+
try {
|
90 |
+
const { domainName } = req.params;
|
91 |
+
const { nameServer, ipAddress } = req.body;
|
92 |
+
const result = await api.ModifyChildNameServer(domainName, nameServer, ipAddress);
|
93 |
+
res.json(result);
|
94 |
+
} catch (error) {
|
95 |
+
next(error);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
96 |
}
|
|
|
97 |
});
|
98 |
|
99 |
+
// Get Contacts endpoint
|
100 |
+
app.get('/api/domains/:domainName/contacts', async (req, res, next) => {
|
101 |
+
try {
|
102 |
+
const { domainName } = req.params;
|
103 |
+
const result = await api.GetContacts(domainName);
|
104 |
+
res.json(result);
|
105 |
+
} catch (error) {
|
106 |
+
next(error);
|
107 |
+
}
|
|
|
|
|
|
|
108 |
});
|
109 |
|
110 |
+
// Save Contacts endpoint
|
111 |
+
app.put('/api/domains/:domainName/contacts', async (req, res, next) => {
|
112 |
+
try {
|
113 |
+
const { domainName } = req.params;
|
114 |
+
const { contacts } = req.body;
|
115 |
+
const result = await api.SaveContacts(domainName, contacts);
|
116 |
+
res.json(result);
|
117 |
+
} catch (error) {
|
118 |
+
next(error);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
119 |
}
|
120 |
+
});
|
121 |
|
122 |
+
// Transfer domain endpoint
|
123 |
+
app.post('/api/domains/transfer', async (req, res, next) => {
|
124 |
+
try {
|
125 |
+
const { domainName, eppCode, period = 1 } = req.body;
|
126 |
+
const result = await api.Transfer(domainName, eppCode, period);
|
127 |
+
res.json(result);
|
128 |
+
} catch (error) {
|
129 |
+
next(error);
|
130 |
}
|
131 |
+
});
|
132 |
|
133 |
+
// Cancel Transfer endpoint
|
134 |
+
app.post('/api/domains/:domainName/cancelTransfer', async (req, res, next) => {
|
135 |
+
try {
|
136 |
+
const { domainName } = req.params;
|
137 |
+
const result = await api.CancelTransfer(domainName);
|
138 |
+
res.json(result);
|
139 |
+
} catch (error) {
|
140 |
+
next(error);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
141 |
}
|
142 |
+
});
|
143 |
|
144 |
+
// Approve Transfer endpoint
|
145 |
+
app.post('/api/domains/:domainName/approveTransfer', async (req, res, next) => {
|
146 |
+
try {
|
147 |
+
const { domainName } = req.params;
|
148 |
+
const result = await api.ApproveTransfer(domainName);
|
149 |
+
res.json(result);
|
150 |
+
} catch (error) {
|
151 |
+
next(error);
|
152 |
+
}
|
153 |
});
|
154 |
|
155 |
+
// Reject Transfer endpoint
|
156 |
+
app.post('/api/domains/:domainName/rejectTransfer', async (req, res, next) => {
|
157 |
+
try {
|
158 |
+
const { domainName } = req.params;
|
159 |
+
const result = await api.RejectTransfer(domainName);
|
160 |
+
res.json(result);
|
161 |
+
} catch (error) {
|
162 |
+
next(error);
|
163 |
+
}
|
164 |
+
});
|
165 |
|
166 |
+
// Renew domain endpoint
|
167 |
+
app.post('/api/domains/:domainName/renew', async (req, res, next) => {
|
168 |
+
try {
|
169 |
+
const { domainName } = req.params;
|
170 |
+
const { period } = req.body;
|
171 |
+
const result = await api.Renew(domainName, period);
|
172 |
+
res.json(result);
|
173 |
+
} catch (error) {
|
174 |
+
next(error);
|
175 |
+
}
|
176 |
+
});
|
177 |
|
178 |
+
// Register domain with contact info endpoint
|
179 |
+
app.post('/api/domains/register', async (req, res, next) => {
|
180 |
+
try {
|
181 |
+
const {
|
182 |
+
domainName,
|
183 |
+
period = 1,
|
184 |
+
contacts,
|
185 |
+
nameServers = ["ns1.harmon.web.tr", "ns2.harmon.web.tr"],
|
186 |
+
eppLock = true,
|
187 |
+
privacyLock = false,
|
188 |
+
additionalAttributes
|
189 |
+
} = req.body;
|
190 |
+
|
191 |
+
const result = await api.RegisterWithContactInfo(
|
192 |
+
domainName,
|
193 |
+
period,
|
194 |
+
contacts,
|
195 |
+
nameServers,
|
196 |
+
eppLock,
|
197 |
+
privacyLock,
|
198 |
+
additionalAttributes
|
199 |
+
);
|
200 |
+
|
201 |
+
res.json(result);
|
202 |
+
} catch (error) {
|
203 |
+
next(error);
|
204 |
+
}
|
205 |
});
|
206 |
+
|
207 |
+
// Modify Privacy Protection Status endpoint
|
208 |
+
app.put('/api/domains/:domainName/privacy', async (req, res, next) => {
|
209 |
+
try {
|
210 |
+
const { domainName } = req.params;
|
211 |
+
const { status, reason = "Owner request" } = req.body;
|
212 |
+
const result = await api.ModifyPrivacyProtectionStatus(domainName, status, reason);
|
213 |
+
res.json(result);
|
214 |
+
} catch (error) {
|
215 |
+
next(error);
|
216 |
+
}
|
217 |
+
});
|
218 |
+
|
219 |
+
// Sync From Registry endpoint
|
220 |
+
app.post('/api/domains/:domainName/sync', async (req, res, next) => {
|
221 |
+
try {
|
222 |
+
const { domainName } = req.params;
|
223 |
+
const result = await api.SyncFromRegistry(domainName);
|
224 |
+
res.json(result);
|
225 |
+
} catch (error) {
|
226 |
+
next(error);
|
227 |
+
}
|
228 |
+
});
|
229 |
+
|
230 |
+
// Get Current Balance endpoint
|
231 |
+
app.get('/api/balance', async (req, res, next) => {
|
232 |
+
try {
|
233 |
+
const { currencyId = 2 } = req.query;
|
234 |
+
const result = await api.GetCurrentBalance(currencyId);
|
235 |
+
res.json(result);
|
236 |
+
} catch (error) {
|
237 |
+
next(error);
|
238 |
+
}
|
239 |
+
});
|
240 |
+
|
241 |
+
// Check Domain Availability endpoint
|
242 |
+
app.post('/api/domains/check', async (req, res, next) => {
|
243 |
+
try {
|
244 |
+
const { domains, extensions, period = 1, command = 'create' } = req.body;
|
245 |
+
const result = await api.CheckAvailability(domains, extensions, period, command);
|
246 |
+
res.json(result);
|
247 |
+
} catch (error) {
|
248 |
+
next(error);
|
249 |
+
}
|
250 |
+
});
|
251 |
+
|
252 |
+
// Get Domain List endpoint
|
253 |
+
app.get('/api/domains', async (req, res, next) => {
|
254 |
+
try {
|
255 |
+
const extraParameters = req.query;
|
256 |
+
const result = await api.GetList(extraParameters);
|
257 |
+
res.json(result);
|
258 |
+
} catch (error) {
|
259 |
+
next(error);
|
260 |
+
}
|
261 |
+
});
|
262 |
+
|
263 |
+
// Get TLD List endpoint
|
264 |
+
app.get('/api/tlds', async (req, res, next) => {
|
265 |
+
try {
|
266 |
+
const { count = 20 } = req.query;
|
267 |
+
const result = await api.GetTldList(count);
|
268 |
+
res.json(result);
|
269 |
+
} catch (error) {
|
270 |
+
next(error);
|
271 |
+
}
|
272 |
+
});
|
273 |
+
|
274 |
+
// Get Domain Details endpoint
|
275 |
+
app.get('/api/domains/:domainName', async (req, res, next) => {
|
276 |
+
try {
|
277 |
+
const { domainName } = req.params;
|
278 |
+
const result = await api.GetDetails(domainName);
|
279 |
+
res.json(result);
|
280 |
+
} catch (error) {
|
281 |
+
next(error);
|
282 |
+
}
|
283 |
+
});
|
284 |
+
|
285 |
+
// Get Reseller Details endpoint
|
286 |
+
app.get('/api/reseller', async (req, res, next) => {
|
287 |
+
try {
|
288 |
+
const result = await api.GetResellerDetails();
|
289 |
+
res.json(result);
|
290 |
+
} catch (error) {
|
291 |
+
next(error);
|
292 |
+
}
|
293 |
+
});
|
294 |
+
|
295 |
+
// 404 handler - must be placed after all other routes
|
296 |
+
app.use((req, res) => {
|
297 |
+
res.status(404).json({
|
298 |
+
success: false,
|
299 |
+
error: 'Endpoint not found'
|
300 |
+
});
|
301 |
+
});
|
302 |
+
|
303 |
+
app.use(errorHandler);
|
304 |
+
|
305 |
+
const PORT = process.env.PORT || 3000;
|
306 |
+
app.listen(PORT, () => {
|
307 |
+
console.log(`Server is running on port ${PORT}`);
|
308 |
+
// Log today's token for testing
|
309 |
+
const today = new Date().toLocaleDateString('en-US', { weekday: 'long' }).toLowerCase();
|
310 |
+
const token = crypto.createHash('sha256').update(today + 'harmon').digest('hex');
|
311 |
+
console.log(`Today's auth token: ${token}`);
|
312 |
+
});
|