Files
FTStore/web/package.json
T
Felitendo 03f6ef7c8b feat(web): sign the Manager build the landing page hands out
The page used to append the seed to the Manager IPA and hand that
straight to the visitor. iOS verifies a bundle's code signature before
an over-the-air install completes, so that build was refused at the
install sheet and everyone needed a second signing tool to finish the
job.

The install endpoint now takes the certificate, the provisioning
profile and the password, seeds the IPA, signs it with zsign, and parks
the result in a slot the phone collects over itms-services. Ordering
matters: the seed goes in before signing, because signing is what seals
the bundle.

The certificate exists only as files in a temp directory removed in a
finally block, and the signed build that embeds it expires after
minutes and is swept on every write. The slot token is the only way to
reach it, and anything else answers 404.

zsign is compiled from the monorepo's own manager/Zsign in a build
stage, so the server signs with the same code the Manager signs with on
device. That moves the app image's build context to the repository
root; a root .dockerignore keeps the context to web/ and manager/Zsign,
and the workflows rebuild when either changes. Dockerfile.worker still
builds from web/ and signs nothing.
2026-08-05 08:31:15 +02:00

65 lines
1.6 KiB
JSON

{
"name": "ftstore-admin",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "eslint",
"db:generate": "prisma generate",
"db:migrate": "prisma migrate dev",
"db:push": "prisma db push",
"db:seed": "tsx prisma/seed.ts",
"worker": "tsx worker/index.ts"
},
"prisma": {
"seed": "tsx prisma/seed.ts"
},
"dependencies": {
"@dnd-kit/core": "^6.3.1",
"@dnd-kit/sortable": "^10.0.0",
"@dnd-kit/utilities": "^3.2.2",
"@octokit/rest": "^22.0.1",
"@prisma/client": "^6.19.2",
"@types/qrcode": "^1.5.6",
"bplist-parser": "^0.3.2",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"date-fns": "^4.1.0",
"lucide-react": "^0.575.0",
"motion": "^12.43.0",
"next": "16.1.6",
"next-themes": "^0.4.6",
"plist": "^3.1.0",
"prebuilt-tdlib": "^0.1008033.1",
"prisma": "^6.19.2",
"qrcode": "^1.5.4",
"radix-ui": "^1.4.3",
"react": "19.2.3",
"react-dom": "19.2.3",
"recharts": "^3.7.0",
"sonner": "^2.0.7",
"tailwind-merge": "^3.5.0",
"tdl": "^8.0.2",
"yaml": "^2.8.2",
"yauzl": "^3.2.0",
"zod": "^4.3.6"
},
"devDependencies": {
"@tailwindcss/postcss": "^4",
"@types/node": "^20",
"@types/plist": "^3.0.5",
"@types/react": "^19",
"@types/react-dom": "^19",
"@types/yauzl": "^2.10.3",
"eslint": "^9",
"eslint-config-next": "16.1.6",
"shadcn": "^3.8.5",
"tailwindcss": "^4",
"tsx": "^4.21.0",
"tw-animate-css": "^1.4.0",
"typescript": "^5"
}
}