feat(release): prepare 1.1.0 candidate
This commit is contained in:
parent
5a34f66981
commit
5205dcdfa9
736 changed files with 115667 additions and 12203 deletions
|
|
@ -18,16 +18,20 @@ export function PortalButton(): React.ReactElement {
|
|||
try {
|
||||
const supabase = getSupabaseBrowserClient()
|
||||
const {
|
||||
data: { session }
|
||||
data: { session },
|
||||
error: sessionError
|
||||
} = await supabase.auth.getSession()
|
||||
|
||||
if (!session) {
|
||||
if (sessionError || !session) {
|
||||
setError('로그인이 필요합니다')
|
||||
return
|
||||
}
|
||||
|
||||
const baseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL?.trim()
|
||||
if (!baseUrl) throw new Error('결제 서버 설정이 완료되지 않았습니다')
|
||||
|
||||
const response = await fetch(
|
||||
`${process.env.NEXT_PUBLIC_SUPABASE_URL}/functions/v1/stripe-portal`,
|
||||
new URL('/functions/v1/stripe-portal', baseUrl).toString(),
|
||||
{
|
||||
method: 'POST',
|
||||
headers: {
|
||||
|
|
@ -40,15 +44,14 @@ export function PortalButton(): React.ReactElement {
|
|||
}
|
||||
)
|
||||
|
||||
if (!response.ok) {
|
||||
const txt = await response.text()
|
||||
throw new Error(`Portal 열기 실패: ${response.status} ${txt}`)
|
||||
}
|
||||
|
||||
const data = (await response.json()) as { url?: string }
|
||||
if (data.url) {
|
||||
window.location.href = data.url
|
||||
const data = await response.json().catch(() => null) as { url?: unknown } | null
|
||||
if (!response.ok) throw new Error('Stripe 구독 관리 페이지를 열지 못했습니다')
|
||||
if (typeof data?.url !== 'string') throw new Error('구독 관리 URL을 받지 못했습니다')
|
||||
const portalUrl = new URL(data.url)
|
||||
if (portalUrl.protocol !== 'https:' || portalUrl.hostname !== 'billing.stripe.com') {
|
||||
throw new Error('구독 관리 URL을 신뢰할 수 없습니다')
|
||||
}
|
||||
window.location.assign(portalUrl.toString())
|
||||
} catch (e) {
|
||||
setError(e instanceof Error ? e.message : 'Unknown error')
|
||||
} finally {
|
||||
|
|
@ -61,6 +64,7 @@ export function PortalButton(): React.ReactElement {
|
|||
<Button
|
||||
variant="outlined"
|
||||
size="small"
|
||||
data-testid="stripe-portal-open"
|
||||
startIcon={busy ? <CircularProgress size={14} /> : <SettingsIcon />}
|
||||
onClick={() => void handleOpenPortal()}
|
||||
disabled={busy}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue