Compare commits

..

3 Commits

Author SHA1 Message Date
pluja
cf5f3b3228 Release 202506131423 2025-06-13 14:23:14 +00:00
pluja
5a41816ac8 Release 202506131339 2025-06-13 13:39:12 +00:00
pluja
bf30a6cb2b Release 202506130639 2025-06-13 06:39:29 +00:00
11 changed files with 91 additions and 21 deletions

View File

@@ -92,7 +92,9 @@ def prompt_check_tos_review(content: str) -> TosReviewCheck:
{"role": "user", "content": content}, {"role": "user", "content": content},
] ]
result_dict = query_openai_json(messages, model="openai/gpt-4.1-mini") result_dict = query_openai_json(
messages, model="openai/gemini-2.5-flash-preview-05-20"
)
return cast(TosReviewCheck, result_dict) return cast(TosReviewCheck, result_dict)

View File

@@ -35,9 +35,11 @@ export default defineConfig({
registerType: 'autoUpdate', registerType: 'autoUpdate',
manifest: { manifest: {
name: 'KYCnot.me', name: 'KYCnot.me',
short_name: 'KYCnot.me',
description: 'Find services that respect your privacy', description: 'Find services that respect your privacy',
theme_color: '#040505', theme_color: '#040505',
background_color: '#171c1b', background_color: '#171c1b',
display: 'minimal-ui',
}, },
pwaAssets: { pwaAssets: {
image: './public/favicon.svg', image: './public/favicon.svg',

View File

@@ -0,0 +1,2 @@
-- AlterEnum
ALTER TYPE "VerificationStepStatus" ADD VALUE 'WARNING';

View File

@@ -578,6 +578,7 @@ enum VerificationStepStatus {
IN_PROGRESS IN_PROGRESS
PASSED PASSED
FAILED FAILED
WARNING
} }
model VerificationStep { model VerificationStep {

View File

@@ -126,7 +126,8 @@ export const adminServiceActions = {
verificationSummary: input.verificationSummary, verificationSummary: input.verificationSummary,
verificationProofMd: input.verificationProofMd, verificationProofMd: input.verificationProofMd,
acceptedCurrencies: input.acceptedCurrencies, acceptedCurrencies: input.acceptedCurrencies,
referral: input.referral, // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
referral: input.referral || null,
serviceVisibility: input.serviceVisibility, serviceVisibility: input.serviceVisibility,
slug: input.slug, slug: input.slug,
overallScore: input.overallScore, overallScore: input.overallScore,
@@ -244,7 +245,8 @@ export const adminServiceActions = {
verificationSummary: input.verificationSummary, verificationSummary: input.verificationSummary,
verificationProofMd: input.verificationProofMd, verificationProofMd: input.verificationProofMd,
acceptedCurrencies: input.acceptedCurrencies, acceptedCurrencies: input.acceptedCurrencies,
referral: input.referral, // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
referral: input.referral || null,
serviceVisibility: input.serviceVisibility, serviceVisibility: input.serviceVisibility,
slug: input.slug, slug: input.slug,
overallScore: input.overallScore, overallScore: input.overallScore,

View File

@@ -108,7 +108,11 @@ const ogImageUrl = makeOgImageUrl(ogImage, Astro.url)
<DynamicFavicon /> <DynamicFavicon />
<!-- Components --> <!-- Components -->
<ClientRouter /> {
!Astro.url.pathname.startsWith('/admin') && (
<ClientRouter />
) /* Disable to prevent bugs in important admin forms */
}
<LoadingIndicator color="green" /> <LoadingIndicator color="green" />
<TailwindJsPluggin /> <TailwindJsPluggin />
{htmx && <HtmxScript />} {htmx && <HtmxScript />}

View File

@@ -29,7 +29,15 @@
font-family: cursive; font-family: cursive;
font-size: 2rem; font-size: 2rem;
font-weight: bold; font-weight: bold;
background: repeating-linear-gradient(90deg, #14ffe9 0%, #ffc800 16.66666%, #ff00e0 33.33333%, #14ffe9 50.0%) -100%/ 200%; background: repeating-linear-gradient(
90deg,
#d97706 0%,
#f59e0b 20%,
#f97316 40%,
#ea580c 60%,
#f97316 80%,
#f59e0b 100%
) -100%/ 200%;
-webkit-background-clip: text; -webkit-background-clip: text;
background-clip: text; background-clip: text;
color: transparent; color: transparent;

View File

@@ -44,4 +44,8 @@
void updateSW(true) void updateSW(true)
} }
} }
window.addEventListener('beforeinstallprompt', (event) => {
event.preventDefault()
})
</script> </script>

View File

@@ -3,6 +3,7 @@ import { Icon } from 'astro-icon/components'
import { differenceInDays, isPast } from 'date-fns' import { differenceInDays, isPast } from 'date-fns'
import { verificationStatusesByValue } from '../constants/verificationStatus' import { verificationStatusesByValue } from '../constants/verificationStatus'
import { verificationStepStatusesByValue } from '../constants/verificationStepStatus'
import { cn } from '../lib/cn' import { cn } from '../lib/cn'
import TimeFormatted from './TimeFormatted.astro' import TimeFormatted from './TimeFormatted.astro'
@@ -67,7 +68,7 @@ const wasRecentlyAdded = isPast(listedDate) && differenceInDays(new Date(), list
</span> </span>
</div> </div>
) : wasRecentlyAdded ? ( ) : wasRecentlyAdded ? (
<div class="mb-3 rounded-md bg-red-900/50 p-2 text-sm text-red-400"> <div class="mb-3 rounded-md bg-yellow-900/50 p-2 text-sm text-yellow-400">
This service was {service.listedAt === null ? 'added ' : 'listed '}{' '} This service was {service.listedAt === null ? 'added ' : 'listed '}{' '}
<TimeFormatted date={listedDate} daysUntilDate={RECENTLY_ADDED_DAYS} /> <TimeFormatted date={listedDate} daysUntilDate={RECENTLY_ADDED_DAYS} />
{service.verificationStatus !== 'VERIFICATION_SUCCESS' && ' and it is not verified'}. Proceed with {service.verificationStatus !== 'VERIFICATION_SUCCESS' && ' and it is not verified'}. Proceed with
@@ -98,14 +99,29 @@ const wasRecentlyAdded = isPast(listedDate) && differenceInDays(new Date(), list
{ {
service.verificationStatus !== 'VERIFICATION_FAILED' && service.verificationStatus !== 'VERIFICATION_FAILED' &&
service.verificationSteps.some((step) => step.status === 'FAILED') && ( service.verificationSteps.some((step) => step.status === 'FAILED') && (
<div class="mb-3 flex items-center gap-2 rounded-md bg-red-900/50 p-2 text-sm text-red-400"> <a
href="#verification"
class="mb-3 flex items-center gap-2 rounded-md bg-red-900/50 p-2 text-sm text-red-400 transition-colors hover:bg-red-900/60"
>
<Icon <Icon
name={verificationStatusesByValue.VERIFICATION_FAILED.icon} name={verificationStatusesByValue.VERIFICATION_FAILED.icon}
class={cn('size-5', verificationStatusesByValue.VERIFICATION_FAILED.classNames.icon)} class={cn('size-5', verificationStatusesByValue.VERIFICATION_FAILED.classNames.icon)}
/> />
<span> <span>Some verification steps failed. Please review the details below.</span>
This service has failed one or more verification steps. Review the verification details carefully. </a>
</span> )
</div> }
{
service.verificationStatus !== 'VERIFICATION_FAILED' &&
!service.verificationSteps.some((step) => step.status === 'FAILED') &&
service.verificationSteps.some((step) => step.status === 'WARNING') && (
<a
href="#verification"
class="mb-3 flex items-center gap-2 rounded-md bg-yellow-600/30 p-2 text-sm text-yellow-200 transition-colors hover:bg-yellow-600/40"
>
<Icon name={verificationStepStatusesByValue.WARNING.icon} class={cn('size-5 text-yellow-400')} />
<span>Some verification steps are marked as warnings.</span>
</a>
) )
} }

View File

@@ -42,6 +42,12 @@ export const {
icon: 'ri:alert-line', icon: 'ri:alert-line',
color: 'red', color: 'red',
}, },
{
value: 'WARNING',
label: 'Warning',
icon: 'ri:alert-line',
color: 'yellow',
},
{ {
value: 'PENDING', value: 'PENDING',
label: 'Pending', label: 'Pending',

View File

@@ -294,6 +294,8 @@ const statusIcon = {
APPROVED: undefined, APPROVED: undefined,
}[service.verificationStatus] }[service.verificationStatus]
const isScam = service.verificationStatus === 'VERIFICATION_FAILED'
const shuffledLinks = { const shuffledLinks = {
clearnet: shuffle(service.serviceUrls), clearnet: shuffle(service.serviceUrls),
onion: shuffle(service.onionUrls), onion: shuffle(service.onionUrls),
@@ -385,6 +387,13 @@ const getVerificationStepStatusInfo = (status: VerificationStepStatus) => {
color: 'red', color: 'red',
timelineIconClass: 'text-red-400', timelineIconClass: 'text-red-400',
} as const } as const
case VerificationStepStatus.WARNING:
return {
text: 'Warning',
icon: 'ri:alert-line',
color: 'yellow',
timelineIconClass: 'text-yellow-400',
} as const
default: default:
return { return {
text: 'Unknown', text: 'Unknown',
@@ -756,11 +765,18 @@ const activeEventToShow =
<ul aria-label="Service links" class="xs:justify-start mt-4 flex flex-wrap justify-center gap-2"> <ul aria-label="Service links" class="xs:justify-start mt-4 flex flex-wrap justify-center gap-2">
{shownLinks.map((url) => ( {shownLinks.map((url) => (
<li> <li>
<ServiceLinkButton {isScam ? (
url={url} <span class="2xs:text-sm 2xs:h-8 2xs:gap-2 2xs:px-4 bg-day-800 inline-flex h-6 items-center gap-1 rounded-full px-2 text-xs whitespace-nowrap text-red-400">
referral={service.referral} <Icon name="ri:alert-line" class="size-4 text-red-400" />
enableMinWidth={shuffledLinks.onion.length + shuffledLinks.i2p.length > 0} {urlDomain(url)}
/> </span>
) : (
<ServiceLinkButton
url={url}
referral={service.referral}
enableMinWidth={shuffledLinks.onion.length + shuffledLinks.i2p.length > 0}
/>
)}
</li> </li>
))} ))}
@@ -784,11 +800,18 @@ const activeEventToShow =
{hiddenLinks.map((url) => ( {hiddenLinks.map((url) => (
<li class="hidden peer-checked:block"> <li class="hidden peer-checked:block">
<ServiceLinkButton {isScam ? (
url={url} <span class="2xs:text-sm 2xs:h-8 2xs:gap-2 2xs:px-4 bg-day-800 inline-flex h-6 items-center gap-1 rounded-full px-2 text-xs whitespace-nowrap text-red-400">
referral={service.referral} <Icon name="ri:alert-line" class="size-4 text-red-400" />
enableMinWidth={shuffledLinks.onion.length + shuffledLinks.i2p.length > 0} {urlDomain(url)}
/> </span>
) : (
<ServiceLinkButton
url={url}
referral={service.referral}
enableMinWidth={shuffledLinks.onion.length + shuffledLinks.i2p.length > 0}
/>
)}
</li> </li>
))} ))}
</ul> </ul>