mirror of
https://github.com/pezkuwichain/pezkuwi-telegram-miniapp.git
synced 2026-04-22 03:07:55 +00:00
feat(supabase): add pezkiwi.app CORS and multi-bot-token auth support
- Add telegram.pezkiwi.app to CORS allowed origins in all edge functions - Support multiple bot tokens (TELEGRAM_BOT_TOKEN, TELEGRAM_BOT_TOKEN_KRD) in auth - Dynamic origin matching for proper CORS headers
This commit is contained in:
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "pezkuwi-telegram-miniapp",
|
||||
"version": "1.0.187",
|
||||
"version": "1.0.188",
|
||||
"type": "module",
|
||||
"description": "Pezkuwichain Telegram Mini App - Forum, Announcements, Rewards",
|
||||
"author": "Pezkuwichain Team",
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"version": "1.0.187",
|
||||
"buildTime": "2026-02-14T08:08:25.403Z",
|
||||
"buildNumber": 1771056505404
|
||||
"version": "1.0.188",
|
||||
"buildTime": "2026-02-14T08:09:14.764Z",
|
||||
"buildNumber": 1771056554765
|
||||
}
|
||||
|
||||
@@ -2,11 +2,13 @@ import { serve } from 'https://deno.land/std@0.177.0/http/server.ts';
|
||||
import { createClient } from 'https://esm.sh/@supabase/supabase-js@2';
|
||||
import { createHmac } from 'https://deno.land/std@0.177.0/node/crypto.ts';
|
||||
|
||||
const ALLOWED_ORIGIN = 'https://telegram.pezkuwichain.io';
|
||||
const ALLOWED_ORIGINS = ['https://telegram.pezkuwichain.io', 'https://telegram.pezkiwi.app'];
|
||||
|
||||
function getCorsHeaders(): Record<string, string> {
|
||||
function getCorsHeaders(origin?: string | null): Record<string, string> {
|
||||
const allowedOrigin =
|
||||
origin && ALLOWED_ORIGINS.some((o) => origin.startsWith(o)) ? origin : ALLOWED_ORIGINS[0];
|
||||
return {
|
||||
'Access-Control-Allow-Origin': ALLOWED_ORIGIN,
|
||||
'Access-Control-Allow-Origin': allowedOrigin,
|
||||
'Access-Control-Allow-Headers':
|
||||
'authorization, x-client-info, apikey, content-type, x-supabase-client-platform',
|
||||
'Access-Control-Allow-Methods': 'POST, OPTIONS',
|
||||
@@ -52,7 +54,8 @@ function validateInitData(initData: string, botToken: string): TelegramUser | nu
|
||||
}
|
||||
|
||||
serve(async (req) => {
|
||||
const corsHeaders = getCorsHeaders();
|
||||
const origin = req.headers.get('origin');
|
||||
const corsHeaders = getCorsHeaders(origin);
|
||||
|
||||
if (req.method === 'OPTIONS') {
|
||||
return new Response('ok', { headers: corsHeaders });
|
||||
|
||||
@@ -13,7 +13,7 @@ import { sha256 } from 'https://esm.sh/@noble/hashes@1.3.2/sha256';
|
||||
import { bytesToHex } from 'https://esm.sh/@noble/hashes@1.3.2/utils';
|
||||
import { secp256k1 } from 'https://esm.sh/@noble/curves@1.2.0/secp256k1';
|
||||
|
||||
const ALLOWED_ORIGIN = 'https://telegram.pezkuwichain.io';
|
||||
const ALLOWED_ORIGINS = ['https://telegram.pezkuwichain.io', 'https://telegram.pezkiwi.app'];
|
||||
const MIN_DEPOSIT = 10; // Minimum 10 USDT
|
||||
|
||||
// Platform fees per network
|
||||
@@ -32,9 +32,11 @@ const TRON_USDT_CONTRACT = 'TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t'; // TRC20 USDT
|
||||
|
||||
const BASE58_ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';
|
||||
|
||||
function getCorsHeaders(): Record<string, string> {
|
||||
function getCorsHeaders(origin?: string | null): Record<string, string> {
|
||||
const allowedOrigin =
|
||||
origin && ALLOWED_ORIGINS.some((o) => origin.startsWith(o)) ? origin : ALLOWED_ORIGINS[0];
|
||||
return {
|
||||
'Access-Control-Allow-Origin': ALLOWED_ORIGIN,
|
||||
'Access-Control-Allow-Origin': allowedOrigin,
|
||||
'Access-Control-Allow-Headers':
|
||||
'authorization, x-client-info, apikey, content-type, x-supabase-client-platform',
|
||||
'Access-Control-Allow-Methods': 'POST, OPTIONS',
|
||||
@@ -313,7 +315,8 @@ async function checkTrc20Deposits(
|
||||
}
|
||||
|
||||
serve(async (req) => {
|
||||
const corsHeaders = getCorsHeaders();
|
||||
const origin = req.headers.get('origin');
|
||||
const corsHeaders = getCorsHeaders(origin);
|
||||
|
||||
if (req.method === 'OPTIONS') {
|
||||
return new Response('ok', { headers: corsHeaders });
|
||||
|
||||
@@ -3,7 +3,11 @@ import { createClient } from 'https://esm.sh/@supabase/supabase-js@2';
|
||||
import { createHmac } from 'https://deno.land/std@0.177.0/node/crypto.ts';
|
||||
|
||||
// CORS - Production domain only
|
||||
const ALLOWED_ORIGINS = ['https://telegram.pezkuwichain.io', 'https://t.me'];
|
||||
const ALLOWED_ORIGINS = [
|
||||
'https://telegram.pezkuwichain.io',
|
||||
'https://telegram.pezkiwi.app',
|
||||
'https://t.me',
|
||||
];
|
||||
|
||||
function getCorsHeaders(origin: string | null): Record<string, string> {
|
||||
const allowedOrigin =
|
||||
|
||||
@@ -2,11 +2,13 @@ import { serve } from 'https://deno.land/std@0.177.0/http/server.ts';
|
||||
import { createClient } from 'https://esm.sh/@supabase/supabase-js@2';
|
||||
import { createHmac } from 'https://deno.land/std@0.177.0/node/crypto.ts';
|
||||
|
||||
const ALLOWED_ORIGIN = 'https://telegram.pezkuwichain.io';
|
||||
const ALLOWED_ORIGINS = ['https://telegram.pezkuwichain.io', 'https://telegram.pezkiwi.app'];
|
||||
|
||||
function getCorsHeaders(): Record<string, string> {
|
||||
function getCorsHeaders(origin?: string | null): Record<string, string> {
|
||||
const allowedOrigin =
|
||||
origin && ALLOWED_ORIGINS.some((o) => origin.startsWith(o)) ? origin : ALLOWED_ORIGINS[0];
|
||||
return {
|
||||
'Access-Control-Allow-Origin': ALLOWED_ORIGIN,
|
||||
'Access-Control-Allow-Origin': allowedOrigin,
|
||||
'Access-Control-Allow-Headers':
|
||||
'authorization, x-client-info, apikey, content-type, x-supabase-client-platform',
|
||||
'Access-Control-Allow-Methods': 'POST, OPTIONS',
|
||||
@@ -61,7 +63,8 @@ function generateDepositCode(): string {
|
||||
}
|
||||
|
||||
serve(async (req) => {
|
||||
const corsHeaders = getCorsHeaders();
|
||||
const origin = req.headers.get('origin');
|
||||
const corsHeaders = getCorsHeaders(origin);
|
||||
|
||||
if (req.method === 'OPTIONS') {
|
||||
return new Response('ok', { headers: corsHeaders });
|
||||
|
||||
@@ -13,12 +13,14 @@ import { sha256 } from 'https://esm.sh/@noble/hashes@1.3.2/sha256';
|
||||
import { bytesToHex, hexToBytes } from 'https://esm.sh/@noble/hashes@1.3.2/utils';
|
||||
import { secp256k1 } from 'https://esm.sh/@noble/curves@1.2.0/secp256k1';
|
||||
|
||||
const ALLOWED_ORIGIN = 'https://telegram.pezkuwichain.io';
|
||||
const ALLOWED_ORIGINS = ['https://telegram.pezkuwichain.io', 'https://telegram.pezkiwi.app'];
|
||||
const BASE58_ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';
|
||||
|
||||
function getCorsHeaders(): Record<string, string> {
|
||||
function getCorsHeaders(origin?: string | null): Record<string, string> {
|
||||
const allowedOrigin =
|
||||
origin && ALLOWED_ORIGINS.some((o) => origin.startsWith(o)) ? origin : ALLOWED_ORIGINS[0];
|
||||
return {
|
||||
'Access-Control-Allow-Origin': ALLOWED_ORIGIN,
|
||||
'Access-Control-Allow-Origin': allowedOrigin,
|
||||
'Access-Control-Allow-Headers':
|
||||
'authorization, x-client-info, apikey, content-type, x-supabase-client-platform',
|
||||
'Access-Control-Allow-Methods': 'POST, OPTIONS',
|
||||
@@ -143,7 +145,8 @@ function deriveTronAddress(mnemonic: string, index: number): string {
|
||||
}
|
||||
|
||||
serve(async (req) => {
|
||||
const corsHeaders = getCorsHeaders();
|
||||
const origin = req.headers.get('origin');
|
||||
const corsHeaders = getCorsHeaders(origin);
|
||||
|
||||
if (req.method === 'OPTIONS') {
|
||||
return new Response('ok', { headers: corsHeaders });
|
||||
|
||||
@@ -2,11 +2,13 @@ import { serve } from 'https://deno.land/std@0.177.0/http/server.ts';
|
||||
import { createClient } from 'https://esm.sh/@supabase/supabase-js@2';
|
||||
import { createHmac } from 'https://deno.land/std@0.177.0/node/crypto.ts';
|
||||
|
||||
const ALLOWED_ORIGIN = 'https://telegram.pezkuwichain.io';
|
||||
const ALLOWED_ORIGINS = ['https://telegram.pezkuwichain.io', 'https://telegram.pezkiwi.app'];
|
||||
|
||||
function getCorsHeaders(): Record<string, string> {
|
||||
function getCorsHeaders(origin?: string | null): Record<string, string> {
|
||||
const allowedOrigin =
|
||||
origin && ALLOWED_ORIGINS.some((o) => origin.startsWith(o)) ? origin : ALLOWED_ORIGINS[0];
|
||||
return {
|
||||
'Access-Control-Allow-Origin': ALLOWED_ORIGIN,
|
||||
'Access-Control-Allow-Origin': allowedOrigin,
|
||||
'Access-Control-Allow-Headers':
|
||||
'authorization, x-client-info, apikey, content-type, x-supabase-client-platform',
|
||||
'Access-Control-Allow-Methods': 'POST, OPTIONS',
|
||||
@@ -52,7 +54,8 @@ function validateInitData(initData: string, botToken: string): TelegramUser | nu
|
||||
}
|
||||
|
||||
serve(async (req) => {
|
||||
const corsHeaders = getCorsHeaders();
|
||||
const origin = req.headers.get('origin');
|
||||
const corsHeaders = getCorsHeaders(origin);
|
||||
|
||||
if (req.method === 'OPTIONS') {
|
||||
return new Response('ok', { headers: corsHeaders });
|
||||
|
||||
@@ -3,7 +3,11 @@ import { createClient } from 'https://esm.sh/@supabase/supabase-js@2';
|
||||
import { createHmac } from 'https://deno.land/std@0.177.0/node/crypto.ts';
|
||||
|
||||
// CORS - Production domain only
|
||||
const ALLOWED_ORIGINS = ['https://telegram.pezkuwichain.io', 'https://t.me'];
|
||||
const ALLOWED_ORIGINS = [
|
||||
'https://telegram.pezkuwichain.io',
|
||||
'https://telegram.pezkiwi.app',
|
||||
'https://t.me',
|
||||
];
|
||||
|
||||
function getCorsHeaders(origin: string | null): Record<string, string> {
|
||||
const allowedOrigin =
|
||||
|
||||
@@ -9,7 +9,11 @@ import { ApiPromise, WsProvider, Keyring } from 'npm:@pezkuwi/api@16.5.36';
|
||||
import { cryptoWaitReady } from 'npm:@pezkuwi/util-crypto@14.0.25';
|
||||
|
||||
// CORS - Restricted for security (cron/admin only)
|
||||
const ALLOWED_ORIGINS = ['https://telegram.pezkuwichain.io', 'https://supabase.com'];
|
||||
const ALLOWED_ORIGINS = [
|
||||
'https://telegram.pezkuwichain.io',
|
||||
'https://telegram.pezkiwi.app',
|
||||
'https://supabase.com',
|
||||
];
|
||||
|
||||
function getCorsHeaders(origin: string | null): Record<string, string> {
|
||||
const allowedOrigin =
|
||||
|
||||
@@ -6,11 +6,13 @@ import { serve } from 'https://deno.land/std@0.177.0/http/server.ts';
|
||||
import { createClient } from 'https://esm.sh/@supabase/supabase-js@2';
|
||||
import { createHmac } from 'https://deno.land/std@0.177.0/node/crypto.ts';
|
||||
|
||||
const ALLOWED_ORIGIN = 'https://telegram.pezkuwichain.io';
|
||||
const ALLOWED_ORIGINS = ['https://telegram.pezkuwichain.io', 'https://telegram.pezkiwi.app'];
|
||||
|
||||
function getCorsHeaders(): Record<string, string> {
|
||||
function getCorsHeaders(origin?: string | null): Record<string, string> {
|
||||
const allowedOrigin =
|
||||
origin && ALLOWED_ORIGINS.some((o) => origin.startsWith(o)) ? origin : ALLOWED_ORIGINS[0];
|
||||
return {
|
||||
'Access-Control-Allow-Origin': ALLOWED_ORIGIN,
|
||||
'Access-Control-Allow-Origin': allowedOrigin,
|
||||
'Access-Control-Allow-Headers':
|
||||
'authorization, x-client-info, apikey, content-type, x-supabase-client-platform',
|
||||
'Access-Control-Allow-Methods': 'POST, OPTIONS',
|
||||
@@ -65,7 +67,8 @@ function isValidSubstrateAddress(address: string): boolean {
|
||||
}
|
||||
|
||||
serve(async (req) => {
|
||||
const corsHeaders = getCorsHeaders();
|
||||
const origin = req.headers.get('origin');
|
||||
const corsHeaders = getCorsHeaders(origin);
|
||||
|
||||
if (req.method === 'OPTIONS') {
|
||||
return new Response('ok', { headers: corsHeaders });
|
||||
|
||||
@@ -2,11 +2,13 @@ import { serve } from 'https://deno.land/std@0.177.0/http/server.ts';
|
||||
import { createClient } from 'https://esm.sh/@supabase/supabase-js@2';
|
||||
import { createHmac } from 'https://deno.land/std@0.177.0/node/crypto.ts';
|
||||
|
||||
const ALLOWED_ORIGIN = 'https://telegram.pezkuwichain.io';
|
||||
const ALLOWED_ORIGINS = ['https://telegram.pezkuwichain.io', 'https://telegram.pezkiwi.app'];
|
||||
|
||||
function getCorsHeaders(): Record<string, string> {
|
||||
function getCorsHeaders(origin?: string | null): Record<string, string> {
|
||||
const allowedOrigin =
|
||||
origin && ALLOWED_ORIGINS.some((o) => origin.startsWith(o)) ? origin : ALLOWED_ORIGINS[0];
|
||||
return {
|
||||
'Access-Control-Allow-Origin': ALLOWED_ORIGIN,
|
||||
'Access-Control-Allow-Origin': allowedOrigin,
|
||||
'Access-Control-Allow-Headers':
|
||||
'authorization, x-client-info, apikey, content-type, x-supabase-client-platform',
|
||||
'Access-Control-Allow-Methods': 'POST, OPTIONS',
|
||||
@@ -93,7 +95,8 @@ function verifySessionToken(token: string, botToken: string): number | null {
|
||||
}
|
||||
|
||||
serve(async (req) => {
|
||||
const corsHeaders = getCorsHeaders();
|
||||
const origin = req.headers.get('origin');
|
||||
const corsHeaders = getCorsHeaders(origin);
|
||||
|
||||
if (req.method === 'OPTIONS') {
|
||||
return new Response('ok', { headers: corsHeaders });
|
||||
@@ -105,9 +108,15 @@ serve(async (req) => {
|
||||
|
||||
const supabaseUrl = Deno.env.get('SUPABASE_URL')!;
|
||||
const supabaseServiceKey = Deno.env.get('SUPABASE_SERVICE_ROLE_KEY')!;
|
||||
const botToken = Deno.env.get('TELEGRAM_BOT_TOKEN');
|
||||
|
||||
if (!botToken) {
|
||||
// Collect all available bot tokens
|
||||
const botTokens: string[] = [];
|
||||
const mainToken = Deno.env.get('TELEGRAM_BOT_TOKEN');
|
||||
const krdToken = Deno.env.get('TELEGRAM_BOT_TOKEN_KRD');
|
||||
if (mainToken) botTokens.push(mainToken);
|
||||
if (krdToken) botTokens.push(krdToken);
|
||||
|
||||
if (botTokens.length === 0) {
|
||||
return new Response(JSON.stringify({ error: 'Server configuration error' }), {
|
||||
status: 500,
|
||||
headers: { ...corsHeaders, 'Content-Type': 'application/json' },
|
||||
@@ -118,7 +127,15 @@ serve(async (req) => {
|
||||
|
||||
// Method 1: Session token verification
|
||||
if (sessionToken) {
|
||||
const tgId = verifySessionToken(sessionToken, botToken);
|
||||
let tgId: number | null = null;
|
||||
let matchedToken: string = botTokens[0];
|
||||
for (const token of botTokens) {
|
||||
tgId = verifySessionToken(sessionToken, token);
|
||||
if (tgId) {
|
||||
matchedToken = token;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!tgId) {
|
||||
return new Response(JSON.stringify({ error: 'Invalid or expired session' }), {
|
||||
status: 401,
|
||||
@@ -142,7 +159,7 @@ serve(async (req) => {
|
||||
return new Response(
|
||||
JSON.stringify({
|
||||
user: userData,
|
||||
session_token: generateSessionToken(tgId, botToken),
|
||||
session_token: generateSessionToken(tgId, matchedToken),
|
||||
}),
|
||||
{ headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
|
||||
);
|
||||
@@ -156,7 +173,15 @@ serve(async (req) => {
|
||||
});
|
||||
}
|
||||
|
||||
const telegramUser = validateInitData(initData, botToken);
|
||||
let telegramUser: TelegramUser | null = null;
|
||||
let matchedBotToken: string = botTokens[0];
|
||||
for (const token of botTokens) {
|
||||
telegramUser = validateInitData(initData, token);
|
||||
if (telegramUser) {
|
||||
matchedBotToken = token;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!telegramUser) {
|
||||
return new Response(JSON.stringify({ error: 'Invalid Telegram data' }), {
|
||||
status: 401,
|
||||
@@ -216,7 +241,7 @@ serve(async (req) => {
|
||||
JSON.stringify({
|
||||
user: userData,
|
||||
telegram_user: telegramUser,
|
||||
session_token: generateSessionToken(telegramUser.id, botToken),
|
||||
session_token: generateSessionToken(telegramUser.id, matchedBotToken),
|
||||
}),
|
||||
{ headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
|
||||
);
|
||||
|
||||
@@ -8,7 +8,11 @@ import { ApiPromise, WsProvider } from 'npm:@pezkuwi/api@16.5.36';
|
||||
import { createHmac } from 'https://deno.land/std@0.177.0/node/crypto.ts';
|
||||
|
||||
// CORS - Production domain only
|
||||
const ALLOWED_ORIGINS = ['https://telegram.pezkuwichain.io', 'https://t.me'];
|
||||
const ALLOWED_ORIGINS = [
|
||||
'https://telegram.pezkuwichain.io',
|
||||
'https://telegram.pezkiwi.app',
|
||||
'https://t.me',
|
||||
];
|
||||
|
||||
function getCorsHeaders(origin: string | null): Record<string, string> {
|
||||
const allowedOrigin =
|
||||
|
||||
Reference in New Issue
Block a user