Initial commit from monorepo
This commit is contained in:
40
server/api/auth/debug-session.get.ts
Normal file
40
server/api/auth/debug-session.get.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
import { defineEventHandler, createError } from 'h3'
|
||||
import type LogtoClient from '@logto/node'
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
const client = event.context.logtoClient as LogtoClient | undefined
|
||||
const user = event.context.logtoUser
|
||||
|
||||
if (!client) {
|
||||
return {
|
||||
authenticated: false,
|
||||
user: null,
|
||||
idToken: null,
|
||||
refreshToken: null
|
||||
}
|
||||
}
|
||||
|
||||
let idToken = null
|
||||
let refreshToken = null
|
||||
|
||||
try {
|
||||
idToken = await client.getIdToken()
|
||||
}
|
||||
catch {
|
||||
// Ignore
|
||||
}
|
||||
|
||||
try {
|
||||
refreshToken = await client.getRefreshToken()
|
||||
}
|
||||
catch {
|
||||
// Ignore
|
||||
}
|
||||
|
||||
return {
|
||||
authenticated: true,
|
||||
user,
|
||||
idToken,
|
||||
refreshToken: refreshToken ? `${refreshToken.substring(0, 20)}...` : null
|
||||
}
|
||||
})
|
||||
18
server/api/auth/id-token-claims.get.ts
Normal file
18
server/api/auth/id-token-claims.get.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import { defineEventHandler, createError } from 'h3'
|
||||
import type LogtoClient from '@logto/node'
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
const client = event.context.logtoClient as LogtoClient | undefined
|
||||
|
||||
if (!client) {
|
||||
throw createError({ statusCode: 401, message: 'Not authenticated' })
|
||||
}
|
||||
|
||||
try {
|
||||
const claims = await client.getIdTokenClaims()
|
||||
return { claims }
|
||||
}
|
||||
catch {
|
||||
return { claims: null }
|
||||
}
|
||||
})
|
||||
18
server/api/auth/id-token.get.ts
Normal file
18
server/api/auth/id-token.get.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import { defineEventHandler, createError } from 'h3'
|
||||
import type LogtoClient from '@logto/node'
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
const client = event.context.logtoClient as LogtoClient | undefined
|
||||
|
||||
if (!client) {
|
||||
throw createError({ statusCode: 401, message: 'Not authenticated' })
|
||||
}
|
||||
|
||||
try {
|
||||
const idToken = await client.getIdToken()
|
||||
return { id_token: idToken }
|
||||
}
|
||||
catch {
|
||||
return { id_token: null }
|
||||
}
|
||||
})
|
||||
76
server/api/auth/refresh.post.ts
Normal file
76
server/api/auth/refresh.post.ts
Normal file
@@ -0,0 +1,76 @@
|
||||
import { defineEventHandler, createError } from 'h3'
|
||||
import type LogtoClient from '@logto/node'
|
||||
|
||||
const RESOURCES = {
|
||||
teams: 'https://teams.optovia.ru',
|
||||
exchange: 'https://exchange.optovia.ru',
|
||||
orders: 'https://orders.optovia.ru',
|
||||
kyc: 'https://kyc.optovia.ru',
|
||||
billing: 'https://billing.optovia.ru'
|
||||
} as const
|
||||
|
||||
export type ResourceKey = keyof typeof RESOURCES
|
||||
|
||||
export interface TokenInfo {
|
||||
token: string
|
||||
expiresAt: number
|
||||
}
|
||||
|
||||
export interface RefreshResponse {
|
||||
tokens: Partial<Record<ResourceKey, TokenInfo>>
|
||||
}
|
||||
|
||||
function decodeTokenExpiry(token: string): number {
|
||||
try {
|
||||
const payload = token.split('.')[1]
|
||||
if (payload) {
|
||||
const decoded = JSON.parse(Buffer.from(payload, 'base64').toString('utf8'))
|
||||
if (decoded.exp) {
|
||||
return decoded.exp * 1000
|
||||
}
|
||||
}
|
||||
}
|
||||
catch {
|
||||
// ignore
|
||||
}
|
||||
return Date.now() + 3600 * 1000 // default 1 hour
|
||||
}
|
||||
|
||||
/**
|
||||
* Refresh all access tokens for all resources.
|
||||
* Gets organizationId from logtoUser (first organization).
|
||||
* Returns tokens with expiry timestamps.
|
||||
*/
|
||||
export default defineEventHandler(async (event): Promise<RefreshResponse> => {
|
||||
const client = event.context.logtoClient as LogtoClient | undefined
|
||||
const logtoUser = event.context.logtoUser as { organizations?: string[] } | undefined
|
||||
|
||||
if (!client) {
|
||||
throw createError({ statusCode: 401, message: 'Not authenticated' })
|
||||
}
|
||||
|
||||
// Get first organization from Logto user
|
||||
const organizationId = logtoUser?.organizations?.[0]
|
||||
|
||||
const tokens: Partial<Record<ResourceKey, TokenInfo>> = {}
|
||||
|
||||
// Fetch all tokens in parallel with organization context
|
||||
await Promise.all(
|
||||
(Object.entries(RESOURCES) as [ResourceKey, string][]).map(async ([key, resource]) => {
|
||||
try {
|
||||
const token = await client.getAccessToken(resource, organizationId)
|
||||
if (token) {
|
||||
tokens[key] = {
|
||||
token,
|
||||
expiresAt: decodeTokenExpiry(token)
|
||||
}
|
||||
}
|
||||
}
|
||||
catch {
|
||||
// Token not available for this resource, skip
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
return { tokens }
|
||||
})
|
||||
Reference in New Issue
Block a user