A decentralized music tracking and discovery platform built on AT Protocol 馃幍
at feat/discord-embed-title 124 lines 3.9 kB view raw
1/** 2 * Welcome to Cloudflare Workers! This is your first worker. 3 * 4 * - Run `npm run dev` in your terminal to start a development server 5 * - Open a browser tab at http://localhost:8787/ to see your worker in action 6 * - Run `npm run deploy` to publish your worker 7 * 8 * Bind resources to your worker in `wrangler.json`. After adding bindings, a type definition for the 9 * `Env` object can be regenerated with `npm run cf-typegen`. 10 * 11 * Learn more at https://developers.cloudflare.com/workers/ 12 */ 13 14const metadata = { 15 redirect_uris: ['https://rocksky.app/oauth/callback'], 16 response_types: ['code'], 17 grant_types: ['authorization_code', 'refresh_token'], 18 scope: 'atproto transition:generic', 19 token_endpoint_auth_method: 'none', 20 application_type: 'web', 21 client_id: 'https://rocksky.app/client-metadata.json', 22 client_name: 'AT Protocol Express App', 23 client_uri: 'https://rocksky.app', 24 dpop_bound_access_tokens: true, 25}; 26 27const jwks = { 28 keys: [ 29 { 30 kty: 'EC', 31 use: 'sig', 32 alg: 'ES256', 33 kid: '2dfa3fd9-57b3-4738-ac27-9e6dadec13b7', 34 crv: 'P-256', 35 x: 'V_00KDnoEPsNqbt0y2Ke8v27Mv9WP70JylDUD5rvIek', 36 y: 'HAyjaQeA2DU6wjZO0ggTadUS6ij1rmiYTxzmWeBKfRc', 37 }, 38 { 39 kty: 'EC', 40 use: 'sig', 41 alg: 'ES256', 42 kid: '5e816ff2-6bff-4177-b1c0-67ad3cd3e7cd', 43 crv: 'P-256', 44 x: 'YwEY5NsoYQVB_G7xPYMl9sUtxRbcPFNffnZcTS5nbPQ', 45 y: '5n5mybPvISyYAnRv1Ii1geqKfXv2GA8p9Xemwx2a8CM', 46 }, 47 { 48 kty: 'EC', 49 use: 'sig', 50 kid: 'a1067a48-a54a-43a0-9758-4d55b51fdd8b', 51 crv: 'P-256', 52 x: 'yq17Nd2DGcjP1i9I0NN3RBmgSbLQUZOtG6ec5GaqzmU', 53 y: 'ieIU9mcfaZwAW5b3WgJkIRgddymG_ckcZ0n1XjbEIvc', 54 }, 55 ], 56}; 57 58export default { 59 async fetch(request, env, ctx): Promise<Response> { 60 const url = new URL(request.url); 61 let redirectToApi = false; 62 63 const API_ROUTES = ['/login', '/profile', '/token', '/now-playing', '/ws']; 64 65 console.log('Request URL:', url.pathname, url.pathname === '/client-metadata.json'); 66 67 if (url.pathname === '/client-metadata.json') { 68 return Response.json(metadata); 69 } 70 71 if (url.pathname === '/jwks.json') { 72 return Response.json(jwks); 73 } 74 75 if ( 76 API_ROUTES.includes(url.pathname) || 77 url.pathname.startsWith('/oauth/callback') || 78 url.pathname.startsWith('/users') || 79 url.pathname.startsWith('/albums') || 80 url.pathname.startsWith('/artists') || 81 url.pathname.startsWith('/tracks') || 82 url.pathname.startsWith('/scrobbles') || 83 url.pathname.startsWith('/likes') || 84 url.pathname.startsWith('/spotify') || 85 url.pathname.startsWith('/dropbox/oauth/callback') || 86 url.pathname.startsWith('/googledrive/oauth/callback') || 87 url.pathname.startsWith('/dropbox/files') || 88 url.pathname.startsWith('/dropbox/file') || 89 url.pathname.startsWith('/googledrive/files') || 90 url.pathname.startsWith('/dropbox/login') || 91 url.pathname.startsWith('/googledrive/login') || 92 url.pathname.startsWith('/dropbox/join') || 93 url.pathname.startsWith('/googledrive/join') || 94 url.pathname.startsWith('/search') || 95 url.pathname.startsWith('/public/scrobbles') 96 ) { 97 redirectToApi = true; 98 } 99 100 if (redirectToApi) { 101 const proxyUrl = new URL(request.url); 102 proxyUrl.host = 'api.rocksky.app'; 103 proxyUrl.hostname = 'api.rocksky.app'; 104 return fetch(proxyUrl, request) as any; 105 } 106 107 // check header if from mobile device, android or ios 108 const userAgent = request.headers.get('user-agent'); 109 const mobileRegex = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i; 110 const isMobile = mobileRegex.test(userAgent!); 111 112 if (isMobile) { 113 const mobileUrl = new URL(request.url); 114 mobileUrl.host = 'm.rocksky.app'; 115 mobileUrl.hostname = 'm.rocksky.app'; 116 return fetch(mobileUrl, request); 117 } 118 119 const proxyUrl = new URL(request.url); 120 proxyUrl.host = 'rocksky.pages.dev'; 121 proxyUrl.hostname = 'rocksky.pages.dev'; 122 return fetch(proxyUrl, request) as any; 123 }, 124} satisfies ExportedHandler<Env>;