This commit is contained in:
@@ -787,7 +787,12 @@ async def oauth_callback_http(request: Request) -> JSONResponse | RedirectRespon
|
||||
logger.error(f"❌ Exception while creating session token for {provider}: {e}", exc_info=True)
|
||||
raise # Re-raise для обработки в основном except блоке
|
||||
|
||||
if not session_token:
|
||||
logger.error(f"❌ Session token is empty for {provider}")
|
||||
raise ValueError("Session token creation failed")
|
||||
|
||||
logger.info(f"✅ Session token created for {provider}: token_length={len(session_token)}")
|
||||
logger.info(f"🔧 Session token preview: {session_token[:20]}..." if len(session_token) > 20 else f"🔧 Session token: {session_token}")
|
||||
|
||||
# Получаем redirect_uri из OAuth данных
|
||||
redirect_uri = oauth_data.get("redirect_uri", FRONTEND_URL)
|
||||
@@ -844,6 +849,7 @@ async def oauth_callback_http(request: Request) -> JSONResponse | RedirectRespon
|
||||
response = RedirectResponse(url=final_redirect_url, status_code=307)
|
||||
|
||||
# 🍪 Устанавливаем httpOnly cookie для безопасности
|
||||
cookie_domain = ".discours.io" if "discours.io" in parsed_redirect.netloc else None
|
||||
response.set_cookie(
|
||||
SESSION_COOKIE_NAME,
|
||||
session_token,
|
||||
@@ -852,10 +858,12 @@ async def oauth_callback_http(request: Request) -> JSONResponse | RedirectRespon
|
||||
samesite=SESSION_COOKIE_SAMESITE,
|
||||
max_age=SESSION_COOKIE_MAX_AGE,
|
||||
path="/", # Важно: устанавливаем path="/" для доступности cookie во всех путях
|
||||
domain=".discours.io" if "discours.io" in parsed_redirect.netloc else None, # Поддержка поддоменов
|
||||
domain=cookie_domain, # Поддержка поддоменов
|
||||
)
|
||||
|
||||
logger.info(f"OAuth успешно завершен для {provider}, user_id={author.id}")
|
||||
logger.info(f"🍪 Cookie установлен: name={SESSION_COOKIE_NAME}, domain={cookie_domain}, secure={SESSION_COOKIE_SECURE}")
|
||||
logger.info(f"🔗 Final redirect: {final_redirect_url}")
|
||||
logger.info(f"✅ OAuth успешно завершен для {provider}, user_id={author.id}")
|
||||
return response
|
||||
|
||||
except Exception as e:
|
||||
|
||||
4
package-lock.json
generated
4
package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "publy-panel",
|
||||
"version": "0.9.25",
|
||||
"version": "0.9.29",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "publy-panel",
|
||||
"version": "0.9.25",
|
||||
"version": "0.9.29",
|
||||
"devDependencies": {
|
||||
"@biomejs/biome": "^2.2.4",
|
||||
"@graphql-codegen/cli": "^6.0.0",
|
||||
|
||||
@@ -5,14 +5,12 @@
|
||||
"description": "Publy, a modern platform for collaborative text creation, offers a user-friendly interface for authors, editors, and readers, supporting real-time collaboration and structured feedback.",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"prebuild": "node scripts/check-graphql-server.js",
|
||||
"build": "npm run codegen:all && vite build",
|
||||
"build": "npm run codegen && vite build",
|
||||
"serve": "vite preview",
|
||||
"lint": "biome check . --fix",
|
||||
"format": "biome format . --write",
|
||||
"typecheck": "tsc --noEmit",
|
||||
"codegen": "graphql-codegen --config codegen.ts",
|
||||
"codegen:all": "npm run codegen"
|
||||
"codegen": "graphql-codegen --config codegen.ts"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@biomejs/biome": "^2.2.4",
|
||||
@@ -38,4 +36,4 @@
|
||||
"overrides": {
|
||||
"vite": "^7.1.7"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,178 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* 🔍 Проверка доступности GraphQL сервера для Code Generator
|
||||
*
|
||||
* Проверяет доступность v3.dscrs.site/graphql и переключается на локальные схемы
|
||||
* если сервер недоступен (например, в CI окружении Vercel/Netlify)
|
||||
*/
|
||||
|
||||
import { readFileSync, writeFileSync, existsSync } from 'fs'
|
||||
import { join } from 'path'
|
||||
|
||||
const GRAPHQL_URL = 'https://v3.dscrs.site/graphql'
|
||||
const TIMEOUT = 10000 // 10 секунд
|
||||
|
||||
/**
|
||||
* Проверяет доступность GraphQL сервера
|
||||
*/
|
||||
async function checkGraphQLServer() {
|
||||
try {
|
||||
console.log('🔍 Проверяем доступность GraphQL сервера...')
|
||||
|
||||
const controller = new AbortController()
|
||||
const timeoutId = setTimeout(() => controller.abort(), TIMEOUT)
|
||||
|
||||
const response = await fetch(GRAPHQL_URL, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'User-Agent': 'GraphQL-Codegen-Check/1.0'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
query: '{ __typename }'
|
||||
}),
|
||||
signal: controller.signal
|
||||
})
|
||||
|
||||
clearTimeout(timeoutId)
|
||||
|
||||
if (response.ok) {
|
||||
console.log('✅ GraphQL сервер доступен')
|
||||
return true
|
||||
} else {
|
||||
console.log(`⚠️ GraphQL сервер вернул статус: ${response.status}`)
|
||||
return false
|
||||
}
|
||||
} catch (error) {
|
||||
if (error.name === 'AbortError') {
|
||||
console.log('⏰ Таймаут подключения к GraphQL серверу')
|
||||
} else {
|
||||
console.log(`❌ Ошибка подключения к GraphQL серверу: ${error.message}`)
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Создает fallback конфигурацию с локальными схемами
|
||||
*/
|
||||
function createFallbackConfig() {
|
||||
console.log('🔄 Создаем fallback конфигурацию с локальными схемами...')
|
||||
|
||||
const fallbackConfig = `import type { CodegenConfig } from '@graphql-codegen/cli'
|
||||
|
||||
const config: CodegenConfig = {
|
||||
overwrite: true,
|
||||
// 🚨 FALLBACK: Используем локальные схемы вместо удаленного сервера
|
||||
schema: ['schema/*.graphql'],
|
||||
documents: ['panel/graphql/queries/**/*.ts', 'panel/**/*.{ts,tsx}', '!panel/graphql/generated/**'],
|
||||
generates: {
|
||||
'./panel/graphql/generated/introspection.json': {
|
||||
plugins: ['introspection'],
|
||||
config: {
|
||||
minify: true
|
||||
}
|
||||
},
|
||||
'./panel/graphql/generated/schema.graphql': {
|
||||
plugins: ['schema-ast'],
|
||||
config: {
|
||||
includeDirectives: false
|
||||
}
|
||||
},
|
||||
'./panel/graphql/generated/': {
|
||||
preset: 'client',
|
||||
plugins: [],
|
||||
presetConfig: {
|
||||
gqlTagName: 'gql',
|
||||
fragmentMasking: false
|
||||
},
|
||||
config: {
|
||||
scalars: {
|
||||
DateTime: 'string',
|
||||
JSON: 'Record<string, any>'
|
||||
},
|
||||
skipTypename: false,
|
||||
useTypeImports: true,
|
||||
dedupeOperationSuffix: true,
|
||||
dedupeFragments: true,
|
||||
avoidOptionals: false,
|
||||
enumsAsTypes: false
|
||||
}
|
||||
}
|
||||
},
|
||||
config: {
|
||||
skipTypename: false,
|
||||
useTypeImports: true,
|
||||
dedupeOperationSuffix: true,
|
||||
dedupeFragments: true,
|
||||
avoidOptionals: false,
|
||||
enumsAsTypes: false
|
||||
}
|
||||
}
|
||||
|
||||
export default config`
|
||||
|
||||
writeFileSync('codegen.fallback.ts', fallbackConfig)
|
||||
console.log('✅ Fallback конфигурация создана: codegen.fallback.ts')
|
||||
}
|
||||
|
||||
/**
|
||||
* Проверяет наличие локальных схем
|
||||
*/
|
||||
function checkLocalSchemas() {
|
||||
const schemaFiles = [
|
||||
'schema/admin.graphql',
|
||||
'schema/enum.graphql',
|
||||
'schema/input.graphql',
|
||||
'schema/mutation.graphql',
|
||||
'schema/query.graphql',
|
||||
'schema/type.graphql'
|
||||
]
|
||||
|
||||
const missingFiles = schemaFiles.filter(file => !existsSync(file))
|
||||
|
||||
if (missingFiles.length > 0) {
|
||||
console.log('❌ Отсутствуют локальные схемы:')
|
||||
missingFiles.forEach(file => console.log(` - ${file}`))
|
||||
return false
|
||||
}
|
||||
|
||||
console.log('✅ Все локальные схемы найдены')
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* Основная функция
|
||||
*/
|
||||
async function main() {
|
||||
const isCI = process.env.CI === 'true' || process.env.VERCEL || process.env.NETLIFY
|
||||
|
||||
if (isCI) {
|
||||
console.log('🏗️ CI окружение обнаружено, используем локальные схемы')
|
||||
}
|
||||
|
||||
const serverAvailable = await checkGraphQLServer()
|
||||
|
||||
if (!serverAvailable || isCI) {
|
||||
if (!checkLocalSchemas()) {
|
||||
console.log('❌ Локальные схемы недоступны, сборка невозможна')
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
createFallbackConfig()
|
||||
|
||||
// Обновляем package.json для использования fallback конфигурации
|
||||
const packageJson = JSON.parse(readFileSync('package.json', 'utf8'))
|
||||
packageJson.scripts.codegen = 'graphql-codegen --config codegen.fallback.ts'
|
||||
writeFileSync('package.json', JSON.stringify(packageJson, null, 2))
|
||||
|
||||
console.log('🔄 package.json обновлен для использования fallback конфигурации')
|
||||
} else {
|
||||
console.log('✅ Используем удаленный GraphQL сервер')
|
||||
}
|
||||
}
|
||||
|
||||
main().catch(error => {
|
||||
console.error('💥 Критическая ошибка:', error)
|
||||
process.exit(1)
|
||||
})
|
||||
Reference in New Issue
Block a user