Compare commits

..

7 Commits

Author SHA1 Message Date
dependabot[bot]
e8d1b779cc Bump docker/login-action from 4.0.0 to 4.1.0
Bumps [docker/login-action](https://github.com/docker/login-action) from 4.0.0 to 4.1.0.
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](b45d80f862...4907a6ddec)

---
updated-dependencies:
- dependency-name: docker/login-action
  dependency-version: 4.1.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-06 01:35:40 +00:00
Owen Schwartz
3436105bec Merge pull request #2784 from fosrl/dev
Try to prevent deadlocks
2026-04-03 23:01:09 -04:00
Owen Schwartz
4b3375ab8e Merge pull request #2783 from fosrl/dev
Fix 1.17.0
2026-04-03 22:42:03 -04:00
Owen Schwartz
6ce165bfd5 Merge pull request #2780 from fosrl/dev
1.17.0
2026-04-03 18:19:40 -04:00
Owen Schwartz
035644eaf7 Merge pull request #2778 from fosrl/dev
1.17.0-s.2
2026-04-03 12:35:03 -04:00
Owen Schwartz
16e7233a3e Merge pull request #2777 from fosrl/dev
1.17.0-s.1
2026-04-03 12:19:23 -04:00
Owen Schwartz
1f74e1b320 Merge pull request #2776 from fosrl/dev
1.17.0-s.0
2026-04-03 11:39:35 -04:00
10 changed files with 44 additions and 77 deletions

1
.github/CODEOWNERS vendored
View File

@@ -1 +0,0 @@
* @oschwartz10612 @miloschwartz

View File

@@ -77,7 +77,7 @@ jobs:
fi fi
- name: Log in to Docker Hub - name: Log in to Docker Hub
uses: docker/login-action@b45d80f862d83dbcd57f89517bcf500b2ab88fb2 # v4.0.0 uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0
with: with:
registry: docker.io registry: docker.io
username: ${{ secrets.DOCKER_HUB_USERNAME }} username: ${{ secrets.DOCKER_HUB_USERNAME }}
@@ -149,7 +149,7 @@ jobs:
fi fi
- name: Log in to Docker Hub - name: Log in to Docker Hub
uses: docker/login-action@b45d80f862d83dbcd57f89517bcf500b2ab88fb2 # v4.0.0 uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0
with: with:
registry: docker.io registry: docker.io
username: ${{ secrets.DOCKER_HUB_USERNAME }} username: ${{ secrets.DOCKER_HUB_USERNAME }}
@@ -204,7 +204,7 @@ jobs:
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Log in to Docker Hub - name: Log in to Docker Hub
uses: docker/login-action@b45d80f862d83dbcd57f89517bcf500b2ab88fb2 # v4.0.0 uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0
with: with:
registry: docker.io registry: docker.io
username: ${{ secrets.DOCKER_HUB_USERNAME }} username: ${{ secrets.DOCKER_HUB_USERNAME }}
@@ -407,7 +407,7 @@ jobs:
shell: bash shell: bash
- name: Login to GitHub Container Registry (for cosign) - name: Login to GitHub Container Registry (for cosign)
uses: docker/login-action@b45d80f862d83dbcd57f89517bcf500b2ab88fb2 # v4.0.0 uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0
with: with:
registry: ghcr.io registry: ghcr.io
username: ${{ github.actor }} username: ${{ github.actor }}

View File

@@ -2116,7 +2116,6 @@
"domainPickerFreeProvidedDomain": "Free Provided Domain", "domainPickerFreeProvidedDomain": "Free Provided Domain",
"domainPickerVerified": "Verified", "domainPickerVerified": "Verified",
"domainPickerUnverified": "Unverified", "domainPickerUnverified": "Unverified",
"domainPickerManual": "Manual",
"domainPickerInvalidSubdomainStructure": "This subdomain contains invalid characters or structure. It will be sanitized automatically when you save.", "domainPickerInvalidSubdomainStructure": "This subdomain contains invalid characters or structure. It will be sanitized automatically when you save.",
"domainPickerError": "Error", "domainPickerError": "Error",
"domainPickerErrorLoadDomains": "Failed to load organization domains", "domainPickerErrorLoadDomains": "Failed to load organization domains",

View File

@@ -235,9 +235,7 @@ export default async function migration() {
for (const row of existingUserInviteRoles) { for (const row of existingUserInviteRoles) {
await db.execute(sql` await db.execute(sql`
INSERT INTO "userInviteRoles" ("inviteId", "roleId") INSERT INTO "userInviteRoles" ("inviteId", "roleId")
SELECT ${row.inviteId}, ${row.roleId} VALUES (${row.inviteId}, ${row.roleId})
WHERE EXISTS (SELECT 1 FROM "userInvites" WHERE "inviteId" = ${row.inviteId})
AND EXISTS (SELECT 1 FROM "roles" WHERE "roleId" = ${row.roleId})
ON CONFLICT DO NOTHING ON CONFLICT DO NOTHING
`); `);
} }
@@ -260,10 +258,7 @@ export default async function migration() {
for (const row of existingUserOrgRoles) { for (const row of existingUserOrgRoles) {
await db.execute(sql` await db.execute(sql`
INSERT INTO "userOrgRoles" ("userId", "orgId", "roleId") INSERT INTO "userOrgRoles" ("userId", "orgId", "roleId")
SELECT ${row.userId}, ${row.orgId}, ${row.roleId} VALUES (${row.userId}, ${row.orgId}, ${row.roleId})
WHERE EXISTS (SELECT 1 FROM "user" WHERE "id" = ${row.userId})
AND EXISTS (SELECT 1 FROM "orgs" WHERE "orgId" = ${row.orgId})
AND EXISTS (SELECT 1 FROM "roles" WHERE "roleId" = ${row.roleId})
ON CONFLICT DO NOTHING ON CONFLICT DO NOTHING
`); `);
} }

View File

@@ -145,7 +145,7 @@ export default async function migration() {
).run(); ).run();
db.prepare( db.prepare(
`INSERT INTO '__new_userOrgs'("userId", "orgId", "isOwner", "autoProvisioned", "pamUsername") SELECT "userId", "orgId", "isOwner", "autoProvisioned", "pamUsername" FROM 'userOrgs' WHERE EXISTS (SELECT 1 FROM 'user' WHERE id = userOrgs.userId) AND EXISTS (SELECT 1 FROM 'orgs' WHERE orgId = userOrgs.orgId);` `INSERT INTO '__new_userOrgs'("userId", "orgId", "isOwner", "autoProvisioned", "pamUsername") SELECT "userId", "orgId", "isOwner", "autoProvisioned", "pamUsername" FROM 'userOrgs';`
).run(); ).run();
db.prepare(`DROP TABLE 'userOrgs';`).run(); db.prepare(`DROP TABLE 'userOrgs';`).run();
db.prepare( db.prepare(
@@ -246,15 +246,12 @@ export default async function migration() {
// Re-insert the preserved invite role assignments into the new userInviteRoles table // Re-insert the preserved invite role assignments into the new userInviteRoles table
if (existingUserInviteRoles.length > 0) { if (existingUserInviteRoles.length > 0) {
const insertUserInviteRole = db.prepare( const insertUserInviteRole = db.prepare(
`INSERT OR IGNORE INTO 'userInviteRoles' ("inviteId", "roleId") `INSERT OR IGNORE INTO 'userInviteRoles' ("inviteId", "roleId") VALUES (?, ?)`
SELECT ?, ?
WHERE EXISTS (SELECT 1 FROM 'userInvites' WHERE inviteId = ?)
AND EXISTS (SELECT 1 FROM 'roles' WHERE roleId = ?)`
); );
const insertAll = db.transaction(() => { const insertAll = db.transaction(() => {
for (const row of existingUserInviteRoles) { for (const row of existingUserInviteRoles) {
insertUserInviteRole.run(row.inviteId, row.roleId, row.inviteId, row.roleId); insertUserInviteRole.run(row.inviteId, row.roleId);
} }
}); });
@@ -268,16 +265,12 @@ export default async function migration() {
// Re-insert the preserved role assignments into the new userOrgRoles table // Re-insert the preserved role assignments into the new userOrgRoles table
if (existingUserOrgRoles.length > 0) { if (existingUserOrgRoles.length > 0) {
const insertUserOrgRole = db.prepare( const insertUserOrgRole = db.prepare(
`INSERT OR IGNORE INTO 'userOrgRoles' ("userId", "orgId", "roleId") `INSERT OR IGNORE INTO 'userOrgRoles' ("userId", "orgId", "roleId") VALUES (?, ?, ?)`
SELECT ?, ?, ?
WHERE EXISTS (SELECT 1 FROM 'user' WHERE id = ?)
AND EXISTS (SELECT 1 FROM 'orgs' WHERE orgId = ?)
AND EXISTS (SELECT 1 FROM 'roles' WHERE roleId = ?)`
); );
const insertAll = db.transaction(() => { const insertAll = db.transaction(() => {
for (const row of existingUserOrgRoles) { for (const row of existingUserOrgRoles) {
insertUserOrgRole.run(row.userId, row.orgId, row.roleId, row.userId, row.orgId, row.roleId); insertUserOrgRole.run(row.userId, row.orgId, row.roleId);
} }
}); });

View File

@@ -10,7 +10,6 @@ import { authCookieHeader } from "@app/lib/api/cookies";
import { GetDNSRecordsResponse } from "@server/routers/domain"; import { GetDNSRecordsResponse } from "@server/routers/domain";
import DNSRecordsTable from "@app/components/DNSRecordTable"; import DNSRecordsTable from "@app/components/DNSRecordTable";
import DomainCertForm from "@app/components/DomainCertForm"; import DomainCertForm from "@app/components/DomainCertForm";
import { build } from "@server/build";
interface DomainSettingsPageProps { interface DomainSettingsPageProps {
params: Promise<{ domainId: string; orgId: string }>; params: Promise<{ domainId: string; orgId: string }>;
@@ -66,14 +65,12 @@ export default async function DomainSettingsPage({
)} )}
</div> </div>
<div className="space-y-6"> <div className="space-y-6">
{build != "oss" && env.flags.usePangolinDns ? ( <DomainInfoCard
<DomainInfoCard failed={domain.failed}
failed={domain.failed} verified={domain.verified}
verified={domain.verified} type={domain.type}
type={domain.type} errorMessage={domain.errorMessage}
errorMessage={domain.errorMessage} />
/>
) : null}
<DNSRecordsTable records={dnsRecords} type={domain.type} /> <DNSRecordsTable records={dnsRecords} type={domain.type} />

View File

@@ -154,7 +154,7 @@ export default function CreateDomainForm({
const punycodePreview = useMemo(() => { const punycodePreview = useMemo(() => {
if (!baseDomain) return ""; if (!baseDomain) return "";
const punycode = toPunycode(baseDomain.toLowerCase()); const punycode = toPunycode(baseDomain);
return punycode !== baseDomain.toLowerCase() ? punycode : ""; return punycode !== baseDomain.toLowerCase() ? punycode : "";
}, [baseDomain]); }, [baseDomain]);
@@ -239,24 +239,21 @@ export default function CreateDomainForm({
className="space-y-4" className="space-y-4"
id="create-domain-form" id="create-domain-form"
> >
{build != "oss" && env.flags.usePangolinDns ? ( <FormField
<FormField control={form.control}
control={form.control} name="type"
name="type" render={({ field }) => (
render={({ field }) => ( <FormItem>
<FormItem> <StrategySelect
<StrategySelect options={domainOptions}
options={domainOptions} defaultValue={field.value}
defaultValue={field.value} onChange={field.onChange}
onChange={field.onChange} cols={1}
cols={1} />
/> <FormMessage />
<FormMessage /> </FormItem>
</FormItem> )}
)} />
/>
) : null}
<FormField <FormField
control={form.control} control={form.control}
name="baseDomain" name="baseDomain"

View File

@@ -509,11 +509,9 @@ export default function DomainPicker({
<span className="truncate"> <span className="truncate">
{selectedBaseDomain.domain} {selectedBaseDomain.domain}
</span> </span>
{selectedBaseDomain.verified && {selectedBaseDomain.verified && (
selectedBaseDomain.domainType !== <CheckCircle2 className="h-3 w-3 text-green-500 shrink-0" />
"wildcard" && ( )}
<CheckCircle2 className="h-3 w-3 text-green-500 shrink-0" />
)}
</div> </div>
) : ( ) : (
t("domainPickerSelectBaseDomain") t("domainPickerSelectBaseDomain")
@@ -576,23 +574,14 @@ export default function DomainPicker({
} }
</span> </span>
<span className="text-xs text-muted-foreground"> <span className="text-xs text-muted-foreground">
{orgDomain.type === {orgDomain.type.toUpperCase()}{" "}
"wildcard" {" "}
{orgDomain.verified
? t( ? t(
"domainPickerManual" "domainPickerVerified"
) )
: ( : t(
<> "domainPickerUnverified"
{orgDomain.type.toUpperCase()}{" "}
{" "}
{orgDomain.verified
? t(
"domainPickerVerified"
)
: t(
"domainPickerUnverified"
)}
</>
)} )}
</span> </span>
</div> </div>

View File

@@ -333,8 +333,7 @@ export default function PendingSitesTable({
"jupiter", "jupiter",
"saturn", "saturn",
"uranus", "uranus",
"neptune", "neptune"
"pluto"
].includes(originalRow.exitNodeName.toLowerCase()); ].includes(originalRow.exitNodeName.toLowerCase());
if (isCloudNode) { if (isCloudNode) {

View File

@@ -342,8 +342,7 @@ export default function SitesTable({
"jupiter", "jupiter",
"saturn", "saturn",
"uranus", "uranus",
"neptune", "neptune"
"pluto"
].includes(originalRow.exitNodeName.toLowerCase()); ].includes(originalRow.exitNodeName.toLowerCase());
if (isCloudNode) { if (isCloudNode) {