Fix integrity check (#630)
Some checks failed
all-good: Did all the other checks pass? / all-good (push) Has been cancelled
Ensure Prisma migrations are in sync with the schema / check_prisma_migrations (22.x) (push) Has been cancelled
Docker Emulator Test / docker (push) Has been cancelled
Docker Server Build and Push / Docker Build and Push Server (push) Has been cancelled
Docker Server Test / docker (push) Has been cancelled
Runs E2E API Tests / build (22.x) (push) Has been cancelled
Lint & build / lint_and_build (latest) (push) Has been cancelled
Preview Docs / run (push) Has been cancelled
Dev Environment Test / restart-dev-and-test (push) Has been cancelled
Run setup tests / setup-tests (push) Has been cancelled
TOC Generator / TOC Generator (push) Has been cancelled

<!--

Make sure you've read the CONTRIBUTING.md guidelines:
https://github.com/stack-auth/stack-auth/blob/dev/CONTRIBUTING.md

-->

<!-- ELLIPSIS_HIDDEN -->


----

> [!IMPORTANT]
> Refactor permission handling by renaming functions and updating
references, enhance config handling, and improve domain sorting logic.
> 
>   - **Permissions**:
> - Rename `teamSystemPermissionStringToDBType` to
`systemPermissionStringToDBType` and
`teamDBTypeToSystemPermissionString` to `systemPermissionDBTypeToString`
in `permissions.tsx`.
> - Update all references to these functions in `crud.tsx`,
`team-memberships/crud.tsx`, `config.tsx`, and `projects.tsx`.
>   - **Config Handling**:
>     - Add `systemPermissionDBTypeToString` import in `config.tsx`.
> - Update `getEnvironmentConfigOverride` to include more detailed error
logging.
>   - **Miscellaneous**:
> - Change domain sorting logic in `projects.tsx` from date-based to
string-based comparison.
> 
> <sup>This description was created by </sup>[<img alt="Ellipsis"
src="https://img.shields.io/badge/Ellipsis-blue?color=175173">](https://www.ellipsis.dev?ref=stack-auth%2Fstack-auth&utm_source=github&utm_medium=referral)<sup>
for 8d0a70429b. It will automatically
update as commits are pushed.</sup>


<!-- ELLIPSIS_HIDDEN -->
This commit is contained in:
Zai Shi 2025-04-15 18:55:59 +02:00 committed by GitHub
parent 573a3d964a
commit f558769ff4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 26 additions and 18 deletions

View File

@ -1,4 +1,4 @@
import { isTeamSystemPermission, listPermissionDefinitions, teamSystemPermissionStringToDBType } from "@/lib/permissions";
import { isTeamSystemPermission, listPermissionDefinitions, systemPermissionStringToDBType } from "@/lib/permissions";
import { fullProjectInclude, projectPrismaToCrud } from "@/lib/projects";
import { ensureSharedProvider } from "@/lib/request-checks";
import { retryTransaction } from "@/prisma-client";
@ -81,7 +81,7 @@ export const projectsCrudHandlers = createLazyProxy(() => createCrudHandlers(pro
const systemPerms = defaultPerms
.filter(p => isTeamSystemPermission(p))
.map(p => teamSystemPermissionStringToDBType(p as any));
.map(p => systemPermissionStringToDBType(p as any));
await tx.projectConfig.update({
where: { id: oldProject.config.id },

View File

@ -1,4 +1,4 @@
import { isTeamSystemPermission, teamSystemPermissionStringToDBType } from "@/lib/permissions";
import { isTeamSystemPermission, systemPermissionStringToDBType } from "@/lib/permissions";
import { ensureTeamExists, ensureTeamMembershipDoesNotExist, ensureTeamMembershipExists, ensureUserExists, ensureUserTeamPermissionExists } from "@/lib/request-checks";
import { Tenancy } from "@/lib/tenancies";
import { PrismaTransaction } from "@/lib/types";
@ -30,7 +30,7 @@ export async function addUserToTeam(tx: PrismaTransaction, options: {
create: options.tenancy.config[permissionAttributeName].map((p) => {
if (isTeamSystemPermission(p.id)) {
return {
systemPermission: teamSystemPermissionStringToDBType(p.id),
systemPermission: systemPermissionStringToDBType(p.id),
};
} else {
return {

View File

@ -11,6 +11,7 @@ import { stringCompare, typedToLowercase } from "@stackframe/stack-shared/dist/u
import { generateUuid } from "@stackframe/stack-shared/dist/utils/uuids";
import * as yup from "yup";
import { RawQuery, prismaClient } from "../prisma-client";
import { systemPermissionDBTypeToString } from "./permissions";
import { DBProject, fullProjectInclude } from "./projects";
// These are placeholder types that should be replaced after the config json db migration
@ -201,7 +202,9 @@ export async function getEnvironmentConfigOverride(options: EnvironmentOptions):
configOverride['auth.otp.allowSignIn'] = true;
}
} else if (authMethodConfig.passkeyConfig) {
configOverride['auth.passkey.allowSignIn'] = true;
if (authMethodConfig.enabled) {
configOverride['auth.passkey.allowSignIn'] = true;
}
} else {
throw new StackAssertionError('Unknown auth method config', { authMethodConfig });
}
@ -293,11 +296,11 @@ export async function getEnvironmentConfigOverride(options: EnvironmentOptions):
configOverride['rbac.defaultPermissions'] = {
teamCreator: typedFromEntries([
...oldConfig.permissions.filter(perm => perm.isDefaultTeamCreatorPermission).map(perm => perm.queryableId),
...oldConfig.teamCreateDefaultSystemPermissions,
...oldConfig.teamCreateDefaultSystemPermissions.map(perm => systemPermissionDBTypeToString(perm)),
].map((id) => [id, true])),
teamMember: typedFromEntries([
...oldConfig.permissions.filter(perm => perm.isDefaultTeamMemberPermission).map(perm => perm.queryableId),
...oldConfig.teamMemberDefaultSystemPermissions,
...oldConfig.teamMemberDefaultSystemPermissions.map(perm => systemPermissionDBTypeToString(perm)),
].map((id) => [id, true])),
signUp: typedFromEntries([
...oldConfig.permissions.filter(perm => perm.isDefaultProjectPermission).map(perm => perm.queryableId),
@ -316,7 +319,12 @@ export async function getEnvironmentConfigOverride(options: EnvironmentOptions):
environmentConfigOverride: configOverride,
});
if (validationResult.status === 'error') {
throw new StackAssertionError('getEnvironmentConfigOverride returned an invalid config override: ' + validationResult.error, { validationResult });
throw new StackAssertionError('getEnvironmentConfigOverride returned an invalid config override: ' + validationResult.error, {
validationResult,
project: options.project,
branch: options.branch,
environmentConfigOverride: configOverride,
});
}
return configOverride;

View File

@ -21,15 +21,15 @@ export function isTeamSystemPermission(permission: string): permission is `$${Lo
return permission.startsWith('$') && permission.slice(1).toUpperCase() in DBTeamSystemPermission;
}
export function teamSystemPermissionStringToDBType(permission: `$${Lowercase<DBTeamSystemPermission>}`): DBTeamSystemPermission {
export function systemPermissionStringToDBType(permission: `$${Lowercase<DBTeamSystemPermission>}`): DBTeamSystemPermission {
return typedToUppercase(permission.slice(1)) as DBTeamSystemPermission;
}
export function teamDBTypeToSystemPermissionString(permission: DBTeamSystemPermission): `$${Lowercase<DBTeamSystemPermission>}` {
export function systemPermissionDBTypeToString(permission: DBTeamSystemPermission): `$${Lowercase<DBTeamSystemPermission>}` {
return '$' + typedToLowercase(permission) as `$${Lowercase<DBTeamSystemPermission>}`;
}
export type TeamSystemPermission = ReturnType<typeof teamDBTypeToSystemPermissionString>;
export type TeamSystemPermission = ReturnType<typeof systemPermissionDBTypeToString>;
const descriptionMap: Record<DBTeamSystemPermission, string> = {
"UPDATE_TEAM": "Update the team information",
@ -147,7 +147,7 @@ export async function listUserTeamPermissions(
const [userId, teamId] = JSON.parse(compositeKey) as [string, string];
const idsToProcess = [...userTeamResults.map(p =>
p.permission?.queryableId ||
(p.systemPermission ? teamDBTypeToSystemPermissionString(p.systemPermission) : null) ||
(p.systemPermission ? systemPermissionDBTypeToString(p.systemPermission) : null) ||
throwErr(new StackAssertionError(`Permission should have either queryableId or systemPermission`, { p }))
)];
@ -191,11 +191,11 @@ export async function grantTeamPermission(
tenancyId: options.tenancy.id,
projectUserId: options.userId,
teamId: options.teamId,
systemPermission: teamSystemPermissionStringToDBType(options.permissionId),
systemPermission: systemPermissionStringToDBType(options.permissionId),
},
},
create: {
systemPermission: teamSystemPermissionStringToDBType(options.permissionId),
systemPermission: systemPermissionStringToDBType(options.permissionId),
teamMember: {
connect: {
tenancyId_projectUserId_teamId: {
@ -282,7 +282,7 @@ export async function revokeTeamPermission(
tenancyId: options.tenancy.id,
projectUserId: options.userId,
teamId: options.teamId,
systemPermission: teamSystemPermissionStringToDBType(options.permissionId),
systemPermission: systemPermissionStringToDBType(options.permissionId),
},
},
});
@ -390,7 +390,7 @@ export async function createPermissionDefinition(
create: parentDbIds.map(parentDbId => {
if (isTeamSystemPermission(parentDbId)) {
return {
parentTeamSystemPermission: teamSystemPermissionStringToDBType(parentDbId),
parentTeamSystemPermission: systemPermissionStringToDBType(parentDbId),
};
} else {
return {
@ -436,7 +436,7 @@ export async function updatePermissionDefinitions(
create: parentDbIds.map(parentDbId => {
if (isTeamSystemPermission(parentDbId)) {
return {
parentTeamSystemPermission: teamSystemPermissionStringToDBType(parentDbId),
parentTeamSystemPermission: systemPermissionStringToDBType(parentDbId),
};
} else {
return {

View File

@ -416,7 +416,7 @@ export function getProjectQuery(projectId: string): RawQuery<ProjectsCrud["Admin
allow_user_api_keys: row.ProjectConfig.allowUserApiKeys,
allow_team_api_keys: row.ProjectConfig.allowTeamApiKeys,
domains: row.ProjectConfig.Domains
.sort((a: any, b: any) => new Date(a.createdAt + "Z").getTime() - new Date(b.createdAt + "Z").getTime())
.sort((a: any, b: any) => stringCompare(a.domain, b.domain))
.map((domain: any) => ({
domain: domain.domain,
handler_path: domain.handlerPath,