panel-install-fix
Some checks failed
Deploy on push / deploy (push) Failing after 32s

This commit is contained in:
2025-09-27 13:08:57 +03:00
parent 0f6cc61286
commit 97cb0f999c
4 changed files with 15 additions and 187 deletions

View File

@@ -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
View File

@@ -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",

View File

@@ -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"
}
}
}

View File

@@ -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)
})