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)
|
logger.error(f"❌ Exception while creating session token for {provider}: {e}", exc_info=True)
|
||||||
raise # Re-raise для обработки в основном except блоке
|
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 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 данных
|
||||||
redirect_uri = oauth_data.get("redirect_uri", FRONTEND_URL)
|
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)
|
response = RedirectResponse(url=final_redirect_url, status_code=307)
|
||||||
|
|
||||||
# 🍪 Устанавливаем httpOnly cookie для безопасности
|
# 🍪 Устанавливаем httpOnly cookie для безопасности
|
||||||
|
cookie_domain = ".discours.io" if "discours.io" in parsed_redirect.netloc else None
|
||||||
response.set_cookie(
|
response.set_cookie(
|
||||||
SESSION_COOKIE_NAME,
|
SESSION_COOKIE_NAME,
|
||||||
session_token,
|
session_token,
|
||||||
@@ -852,10 +858,12 @@ async def oauth_callback_http(request: Request) -> JSONResponse | RedirectRespon
|
|||||||
samesite=SESSION_COOKIE_SAMESITE,
|
samesite=SESSION_COOKIE_SAMESITE,
|
||||||
max_age=SESSION_COOKIE_MAX_AGE,
|
max_age=SESSION_COOKIE_MAX_AGE,
|
||||||
path="/", # Важно: устанавливаем path="/" для доступности cookie во всех путях
|
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
|
return response
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|||||||
4
package-lock.json
generated
4
package-lock.json
generated
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "publy-panel",
|
"name": "publy-panel",
|
||||||
"version": "0.9.25",
|
"version": "0.9.29",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "publy-panel",
|
"name": "publy-panel",
|
||||||
"version": "0.9.25",
|
"version": "0.9.29",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@biomejs/biome": "^2.2.4",
|
"@biomejs/biome": "^2.2.4",
|
||||||
"@graphql-codegen/cli": "^6.0.0",
|
"@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.",
|
"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": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
"prebuild": "node scripts/check-graphql-server.js",
|
"build": "npm run codegen && vite build",
|
||||||
"build": "npm run codegen:all && vite build",
|
|
||||||
"serve": "vite preview",
|
"serve": "vite preview",
|
||||||
"lint": "biome check . --fix",
|
"lint": "biome check . --fix",
|
||||||
"format": "biome format . --write",
|
"format": "biome format . --write",
|
||||||
"typecheck": "tsc --noEmit",
|
"typecheck": "tsc --noEmit",
|
||||||
"codegen": "graphql-codegen --config codegen.ts",
|
"codegen": "graphql-codegen --config codegen.ts"
|
||||||
"codegen:all": "npm run codegen"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@biomejs/biome": "^2.2.4",
|
"@biomejs/biome": "^2.2.4",
|
||||||
@@ -38,4 +36,4 @@
|
|||||||
"overrides": {
|
"overrides": {
|
||||||
"vite": "^7.1.7"
|
"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