|
1 | 1 | import { FastifyInstance } from 'fastify' |
2 | | -import { Static, Type } from '@sinclair/typebox' |
3 | | -import { extractCookieForHeader } from '../../other/extractCookieForHeader' |
4 | | -import { EventDao } from '../../dao/eventDao' |
5 | | - |
6 | | -const BupherLoginBody = Type.Object({ |
7 | | - email: Type.String(), |
8 | | - password: Type.String(), |
9 | | -}) |
10 | | - |
11 | | -type BupherLoginBodyType = Static<typeof BupherLoginBody> |
12 | | - |
13 | | -const BupherLoginReply = Type.Object({ |
14 | | - success: Type.Boolean(), |
15 | | - error: Type.Optional(Type.String()), |
16 | | - cookies: Type.Optional(Type.String()), |
17 | | -}) |
18 | | - |
19 | | -type BupherLoginReplyType = Static<typeof BupherLoginReply> |
20 | | - |
21 | | -const bupherDomain = 'login' + '.' + 'bu' + 'f' + 'f' + 'er' + '.com' |
22 | | - |
23 | | -const browserHeaders = { |
24 | | - 'User-Agent': |
25 | | - 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36', |
26 | | - Accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8', |
27 | | - 'Accept-Language': 'en-US,en;q=0.9', |
28 | | - Origin: 'https://' + bupherDomain, |
29 | | - Host: bupherDomain, |
30 | | - 'X-Target-Domain': bupherDomain, |
31 | | - Referer: 'https://' + bupherDomain + '.com/login', |
32 | | - 'Sec-Ch-Ua': '"Chromium";v="122", "Not(A:Brand";v="24", "Google Chrome";v="122"', |
33 | | - 'Sec-Ch-Ua-Mobile': '?0', |
34 | | - 'Sec-Ch-Ua-Platform': '"macOS"', |
35 | | - 'Sec-Fetch-Dest': 'document', |
36 | | - 'Sec-Fetch-Mode': 'navigate', |
37 | | - 'Sec-Fetch-Site': 'same-origin', |
38 | | - 'Sec-Fetch-User': '?1', |
39 | | - 'Upgrade-Insecure-Requests': '1', |
40 | | -} |
41 | | - |
42 | | -const BASE_URL = 'https://proxy.minix.gresse.io' |
| 2 | +import { bupherLoginRoute } from './bupherLoginRoute' |
| 3 | +import { bupherChannelsRoute } from './bupherChannelsRoute' |
| 4 | +// import { bupherScheduledPostsRoute } from './bupherScheduledPostsRoute' |
43 | 5 |
|
44 | 6 | export const bupherRoutes = (fastify: FastifyInstance, options: any, done: () => any) => { |
45 | | - fastify.post<{ Body: BupherLoginBodyType; Reply: BupherLoginReplyType }>( |
46 | | - '/v1/:eventId/bupher/login', |
47 | | - { |
48 | | - schema: { |
49 | | - tags: ['bupher'], |
50 | | - summary: 'Login to Bupher using credentials', |
51 | | - querystring: { |
52 | | - type: 'object', |
53 | | - additionalProperties: false, |
54 | | - properties: { |
55 | | - apiKey: { |
56 | | - type: 'string', |
57 | | - description: 'The API key of the event', |
58 | | - }, |
59 | | - }, |
60 | | - }, |
61 | | - body: BupherLoginBody, |
62 | | - response: { |
63 | | - 200: BupherLoginReply, |
64 | | - 400: Type.Object({ |
65 | | - error: Type.String(), |
66 | | - }), |
67 | | - }, |
68 | | - security: [ |
69 | | - { |
70 | | - apiKey: [], |
71 | | - }, |
72 | | - ], |
73 | | - }, |
74 | | - preHandler: fastify.auth([fastify.verifyApiKey]), |
75 | | - }, |
76 | | - async (request, reply) => { |
77 | | - try { |
78 | | - const { eventId } = request.params as { eventId: string } |
79 | | - const { email, password } = request.body |
80 | | - |
81 | | - // Fetch the login page |
82 | | - const loginPageResponse = await fetch(`${BASE_URL}/login`, { |
83 | | - headers: { |
84 | | - ...browserHeaders, |
85 | | - 'Sec-Fetch-Site': 'none', |
86 | | - }, |
87 | | - }) |
88 | | - |
89 | | - if (!loginPageResponse.ok) { |
90 | | - console.log('Bupher first fetch:', loginPageResponse.statusText, loginPageResponse.status) |
91 | | - return reply.code(500).send({ |
92 | | - success: false, |
93 | | - error: 'Failed to fetch Bupher login page', |
94 | | - }) |
95 | | - } |
96 | | - |
97 | | - // Get the HTML content |
98 | | - const htmlContent = await loginPageResponse.text() |
99 | | - |
100 | | - // Extract CSRF token from the HTML |
101 | | - const csrfMatch = htmlContent.match(/<input[^>]*name="_csrf"[^>]*value="([^"]*)"/) |
102 | | - if (!csrfMatch) { |
103 | | - return reply.code(500).send({ |
104 | | - success: false, |
105 | | - error: 'Could not extract CSRF token', |
106 | | - }) |
107 | | - } |
108 | | - const csrfToken = csrfMatch[1] |
109 | | - |
110 | | - // Get cookies from the login page response and format them properly |
111 | | - const rawCookies = loginPageResponse.headers.get('set-cookie') |
112 | | - const cookies = rawCookies |
113 | | - ?.split(',') |
114 | | - .map((cookie) => cookie.split(';')[0]) |
115 | | - .join('; ') |
116 | | - |
117 | | - // Submit login form with CSRF token |
118 | | - const loginResponse = await fetch(`${BASE_URL}/login`, { |
119 | | - method: 'POST', |
120 | | - headers: { |
121 | | - ...browserHeaders, |
122 | | - 'Content-Type': 'application/x-www-form-urlencoded', |
123 | | - Cookie: cookies || '', |
124 | | - }, |
125 | | - body: new URLSearchParams({ |
126 | | - _csrf: csrfToken, |
127 | | - email: email, |
128 | | - password: password, |
129 | | - }).toString(), |
130 | | - redirect: 'manual', |
131 | | - }) |
132 | | - |
133 | | - console.log('Bupher login response:', loginResponse.statusText, loginResponse.status) |
134 | | - |
135 | | - if (loginResponse.status !== 302) { |
136 | | - return reply.code(401).send({ |
137 | | - success: false, |
138 | | - error: 'Invalid credentials or login failed, status: ' + loginResponse.status, |
139 | | - }) |
140 | | - } |
141 | | - |
142 | | - const loginCookies = loginResponse.headers.get('set-cookie') |
143 | | - |
144 | | - const bupherSession = extractCookieForHeader(loginCookies || '') |
145 | | - |
146 | | - await EventDao.saveBupherSession(fastify.firebase, eventId, bupherSession) |
| 7 | + // Register all Bupher routes |
| 8 | + bupherLoginRoute(fastify, options, () => {}) |
| 9 | + bupherChannelsRoute(fastify, options, () => {}) |
| 10 | + // bupherScheduledPostsRoute(fastify, options, () => {}) |
147 | 11 |
|
148 | | - reply.send({ |
149 | | - success: true, |
150 | | - }) |
151 | | - } catch (error) { |
152 | | - console.error('Bupher login error:', error) |
153 | | - reply.code(500).send({ |
154 | | - success: false, |
155 | | - error: 'Internal server error during Bupher login', |
156 | | - }) |
157 | | - } |
158 | | - } |
159 | | - ) |
160 | 12 | done() |
161 | 13 | } |
0 commit comments