mirror of
https://github.com/stack-auth/stack.git
synced 2026-06-13 21:01:21 +08:00
add storage
This commit is contained in:
parent
2c6bb4b4ee
commit
25c05014b5
@ -19,6 +19,7 @@ import { InternalProjectsCrud, ProjectsCrud } from './crud/projects';
|
||||
import { SessionsCrud } from './crud/sessions';
|
||||
import { TeamInvitationCrud } from './crud/team-invitation';
|
||||
import { TeamMemberProfilesCrud } from './crud/team-member-profiles';
|
||||
import { ProjectPermissionsCrud } from './crud/project-permissions';
|
||||
import { TeamPermissionsCrud } from './crud/team-permissions';
|
||||
import { TeamsCrud } from './crud/teams';
|
||||
|
||||
@ -1183,6 +1184,21 @@ export class StackClientInterface {
|
||||
return result.items;
|
||||
}
|
||||
|
||||
async listCurrentUserProjectPermissions(
|
||||
options: {
|
||||
recursive: boolean,
|
||||
},
|
||||
session: InternalSession
|
||||
): Promise<ProjectPermissionsCrud['Client']['Read'][]> {
|
||||
const response = await this.sendClientRequest(
|
||||
`/project-permissions?user_id=me&recursive=${options.recursive}`,
|
||||
{},
|
||||
session,
|
||||
);
|
||||
const result = await response.json() as ProjectPermissionsCrud['Client']['List'];
|
||||
return result.items;
|
||||
}
|
||||
|
||||
async listCurrentUserTeams(session: InternalSession): Promise<TeamsCrud["Client"]["Read"][]> {
|
||||
const response = await this.sendClientRequest(
|
||||
"/teams?user_id=me",
|
||||
|
||||
@ -15,6 +15,7 @@ import { SessionsCrud } from "./crud/sessions";
|
||||
import { TeamInvitationCrud } from "./crud/team-invitation";
|
||||
import { TeamMemberProfilesCrud } from "./crud/team-member-profiles";
|
||||
import { TeamMembershipsCrud } from "./crud/team-memberships";
|
||||
import { ProjectPermissionsCrud } from "./crud/project-permissions";
|
||||
import { TeamPermissionsCrud } from "./crud/team-permissions";
|
||||
import { TeamsCrud } from "./crud/teams";
|
||||
import { UsersCrud } from "./crud/users";
|
||||
@ -195,6 +196,25 @@ export class StackServerInterface extends StackClientInterface {
|
||||
return result.items;
|
||||
}
|
||||
|
||||
async listServerProjectPermissions(
|
||||
options: {
|
||||
userId?: string,
|
||||
recursive: boolean,
|
||||
},
|
||||
session: InternalSession | null,
|
||||
): Promise<ProjectPermissionsCrud['Server']['Read'][]> {
|
||||
const response = await this.sendServerRequest(
|
||||
`/project-permissions?${new URLSearchParams(filterUndefined({
|
||||
user_id: options.userId,
|
||||
recursive: options.recursive.toString(),
|
||||
}))}`,
|
||||
{},
|
||||
session,
|
||||
);
|
||||
const result = await response.json() as ProjectPermissionsCrud['Server']['List'];
|
||||
return result.items;
|
||||
}
|
||||
|
||||
async listServerUsers(options: {
|
||||
cursor?: string,
|
||||
limit?: number,
|
||||
|
||||
@ -46,6 +46,7 @@ let isReactServer = false;
|
||||
// IF_PLATFORM next
|
||||
import * as sc from "@stackframe/stack-sc";
|
||||
import { cookies } from '@stackframe/stack-sc';
|
||||
import { ProjectPermissionsCrud } from "@stackframe/stack-shared/dist/interface/crud/project-permissions";
|
||||
isReactServer = sc.isReactServer;
|
||||
|
||||
// NextNavigation.useRouter does not exist in react-server environments and some bundlers try to be helpful and throw a warning. Ignore the warning.
|
||||
@ -115,6 +116,12 @@ export class _StackClientAppImplIncomplete<HasTokenStore extends boolean, Projec
|
||||
>(async (session, [teamId, recursive]) => {
|
||||
return await this._interface.listCurrentUserTeamPermissions({ teamId, recursive }, session);
|
||||
});
|
||||
private readonly _currentUserProjectPermissionsCache = createCacheBySession<
|
||||
[boolean],
|
||||
ProjectPermissionsCrud['Client']['Read'][]
|
||||
>(async (session, [recursive]) => {
|
||||
return await this._interface.listCurrentUserProjectPermissions({ recursive }, session);
|
||||
});
|
||||
private readonly _currentUserTeamsCache = createCacheBySession(async (session) => {
|
||||
return await this._interface.listCurrentUserTeams(session);
|
||||
});
|
||||
@ -584,7 +591,7 @@ export class _StackClientAppImplIncomplete<HasTokenStore extends boolean, Projec
|
||||
};
|
||||
}
|
||||
|
||||
protected _clientTeamPermissionFromCrud(crud: TeamPermissionsCrud['Client']['Read']): TeamPermission {
|
||||
protected _clientTeamPermissionFromCrud(crud: TeamPermissionsCrud['Client']['Read'] | ProjectPermissionsCrud['Client']['Read']): TeamPermission {
|
||||
return {
|
||||
id: crud.id,
|
||||
};
|
||||
@ -868,18 +875,32 @@ export class _StackClientAppImplIncomplete<HasTokenStore extends boolean, Projec
|
||||
const permissions = Result.orThrow(await app._currentUserPermissionsCache.getOrWait([session, scope.id, recursive], "write-only"));
|
||||
return permissions.map((crud) => app._clientTeamPermissionFromCrud(crud));
|
||||
},
|
||||
async listProjectPermissions(options?: { recursive?: boolean }): Promise<TeamPermission[]> {
|
||||
const recursive = options?.recursive ?? true;
|
||||
const permissions = Result.orThrow(await app._currentUserProjectPermissionsCache.getOrWait([session, recursive], "write-only"));
|
||||
return permissions.map((crud) => app._clientTeamPermissionFromCrud(crud));
|
||||
},
|
||||
// IF_PLATFORM react-like
|
||||
usePermissions(scope: Team, options?: { recursive?: boolean }): TeamPermission[] {
|
||||
const recursive = options?.recursive ?? true;
|
||||
const permissions = useAsyncCache(app._currentUserPermissionsCache, [session, scope.id, recursive] as const, "user.usePermissions()");
|
||||
return useMemo(() => permissions.map((crud) => app._clientTeamPermissionFromCrud(crud)), [permissions]);
|
||||
},
|
||||
useProjectPermissions(options?: { recursive?: boolean }): TeamPermission[] {
|
||||
const recursive = options?.recursive ?? true;
|
||||
const permissions = useAsyncCache(app._currentUserProjectPermissionsCache, [session, recursive] as const, "user.useProjectPermissions()");
|
||||
return useMemo(() => permissions.map((crud) => app._clientTeamPermissionFromCrud(crud)), [permissions]);
|
||||
},
|
||||
// END_PLATFORM
|
||||
// IF_PLATFORM react-like
|
||||
usePermission(scope: Team, permissionId: string): TeamPermission | null {
|
||||
const permissions = this.usePermissions(scope);
|
||||
return useMemo(() => permissions.find((p) => p.id === permissionId) ?? null, [permissions, permissionId]);
|
||||
},
|
||||
useProjectPermission(permissionId: string): TeamPermission | null {
|
||||
const permissions = this.useProjectPermissions();
|
||||
return useMemo(() => permissions.find((p) => p.id === permissionId) ?? null, [permissions, permissionId]);
|
||||
},
|
||||
// END_PLATFORM
|
||||
async getPermission(scope: Team, permissionId: string): Promise<TeamPermission | null> {
|
||||
const permissions = await this.listPermissions(scope);
|
||||
@ -888,6 +909,13 @@ export class _StackClientAppImplIncomplete<HasTokenStore extends boolean, Projec
|
||||
async hasPermission(scope: Team, permissionId: string): Promise<boolean> {
|
||||
return (await this.getPermission(scope, permissionId)) !== null;
|
||||
},
|
||||
async getProjectPermission(permissionId: string): Promise<TeamPermission | null> {
|
||||
const permissions = await this.listProjectPermissions();
|
||||
return permissions.find((p) => p.id === permissionId) ?? null;
|
||||
},
|
||||
async hasProjectPermission(permissionId: string): Promise<boolean> {
|
||||
return (await this.getProjectPermission(permissionId)) !== null;
|
||||
},
|
||||
async update(update) {
|
||||
return await app._updateClientUser(update, session);
|
||||
},
|
||||
|
||||
@ -3,7 +3,7 @@ import { ContactChannelsCrud } from "@stackframe/stack-shared/dist/interface/cru
|
||||
import { TeamInvitationCrud } from "@stackframe/stack-shared/dist/interface/crud/team-invitation";
|
||||
import { TeamMemberProfilesCrud } from "@stackframe/stack-shared/dist/interface/crud/team-member-profiles";
|
||||
import { TeamPermissionDefinitionsCrud, TeamPermissionsCrud } from "@stackframe/stack-shared/dist/interface/crud/team-permissions";
|
||||
import { ProjectPermissionDefinitionsCrud } from "@stackframe/stack-shared/dist/interface/crud/project-permissions";
|
||||
import { ProjectPermissionDefinitionsCrud, ProjectPermissionsCrud } from "@stackframe/stack-shared/dist/interface/crud/project-permissions";
|
||||
import { TeamsCrud } from "@stackframe/stack-shared/dist/interface/crud/teams";
|
||||
import { UsersCrud } from "@stackframe/stack-shared/dist/interface/crud/users";
|
||||
import { InternalSession } from "@stackframe/stack-shared/dist/sessions";
|
||||
@ -61,6 +61,12 @@ export class _StackServerAppImplIncomplete<HasTokenStore extends boolean, Projec
|
||||
>(async ([teamId, userId, recursive]) => {
|
||||
return await this._interface.listServerTeamPermissions({ teamId, userId, recursive }, null);
|
||||
});
|
||||
private readonly _serverUserProjectPermissionsCache = createCache<
|
||||
[string, boolean],
|
||||
ProjectPermissionsCrud['Server']['Read'][]
|
||||
>(async ([userId, recursive]) => {
|
||||
return await this._interface.listServerProjectPermissions({ userId, recursive }, null);
|
||||
});
|
||||
private readonly _serverUserOAuthConnectionAccessTokensCache = createCache<[string, string, string], { accessToken: string } | null>(
|
||||
async ([userId, providerId, scope]) => {
|
||||
try {
|
||||
@ -341,6 +347,31 @@ export class _StackServerAppImplIncomplete<HasTokenStore extends boolean, Projec
|
||||
async hasPermission(scope: Team, permissionId: string): Promise<boolean> {
|
||||
return await this.getPermission(scope, permissionId) !== null;
|
||||
},
|
||||
async listProjectPermissions(options?: { recursive?: boolean }): Promise<AdminTeamPermission[]> {
|
||||
const recursive = options?.recursive ?? true;
|
||||
const permissions = Result.orThrow(await app._serverUserProjectPermissionsCache.getOrWait([crud.id, recursive], "write-only"));
|
||||
return permissions.map((crud) => app._serverPermissionFromCrud(crud));
|
||||
},
|
||||
// IF_PLATFORM react-like
|
||||
useProjectPermissions(options?: { recursive?: boolean }): AdminTeamPermission[] {
|
||||
const recursive = options?.recursive ?? true;
|
||||
const permissions = useAsyncCache(app._serverUserProjectPermissionsCache, [crud.id, recursive] as const, "user.useProjectPermissions()");
|
||||
return useMemo(() => permissions.map((crud) => app._serverPermissionFromCrud(crud)), [permissions]);
|
||||
},
|
||||
// END_PLATFORM
|
||||
async getProjectPermission(permissionId: string): Promise<AdminTeamPermission | null> {
|
||||
const permissions = await this.listProjectPermissions();
|
||||
return permissions.find((p) => p.id === permissionId) ?? null;
|
||||
},
|
||||
// IF_PLATFORM react-like
|
||||
useProjectPermission(permissionId: string): AdminTeamPermission | null {
|
||||
const permissions = this.useProjectPermissions();
|
||||
return useMemo(() => permissions.find((p) => p.id === permissionId) ?? null, [permissions, permissionId]);
|
||||
},
|
||||
// END_PLATFORM
|
||||
async hasProjectPermission(permissionId: string): Promise<boolean> {
|
||||
return await this.getProjectPermission(permissionId) !== null;
|
||||
},
|
||||
async update(update: ServerUserUpdateOptions) {
|
||||
await app._updateServerUser(crud.id, update);
|
||||
},
|
||||
@ -626,7 +657,7 @@ export class _StackServerAppImplIncomplete<HasTokenStore extends boolean, Projec
|
||||
}
|
||||
// END_PLATFORM
|
||||
|
||||
_serverPermissionFromCrud(crud: TeamPermissionsCrud['Server']['Read']): AdminTeamPermission {
|
||||
_serverPermissionFromCrud(crud: TeamPermissionsCrud['Server']['Read'] | ProjectPermissionsCrud['Server']['Read']): AdminTeamPermission {
|
||||
return {
|
||||
id: crud.id,
|
||||
};
|
||||
|
||||
@ -187,6 +187,13 @@ export type UserExtra = {
|
||||
// END_PLATFORM
|
||||
|
||||
hasPermission(scope: Team, permissionId: string): Promise<boolean>,
|
||||
getProjectPermission(permissionId: string): Promise<TeamPermission | null>,
|
||||
hasProjectPermission(permissionId: string): Promise<boolean>,
|
||||
listProjectPermissions(options?: { recursive?: boolean }): Promise<TeamPermission[]>,
|
||||
// IF_PLATFORM react-like
|
||||
useProjectPermissions(options?: { recursive?: boolean }): TeamPermission[],
|
||||
useProjectPermission(permissionId: string): TeamPermission | null,
|
||||
// END_PLATFORM
|
||||
|
||||
readonly selectedTeam: Team | null,
|
||||
setSelectedTeam(team: Team | null): Promise<void>,
|
||||
@ -269,6 +276,14 @@ export type ServerBaseUser = {
|
||||
|
||||
grantPermission(scope: Team, permissionId: string): Promise<void>,
|
||||
revokePermission(scope: Team, permissionId: string): Promise<void>,
|
||||
|
||||
getProjectPermission(permissionId: string): Promise<TeamPermission | null>,
|
||||
hasProjectPermission(permissionId: string): Promise<boolean>,
|
||||
listProjectPermissions(options?: { recursive?: boolean }): Promise<TeamPermission[]>,
|
||||
// IF_PLATFORM react-like
|
||||
useProjectPermissions(options?: { recursive?: boolean }): TeamPermission[],
|
||||
useProjectPermission(permissionId: string): TeamPermission | null,
|
||||
// END_PLATFORM
|
||||
|
||||
/**
|
||||
* Creates a new session object with a refresh token for this user. Can be used to impersonate them.
|
||||
|
||||
Loading…
Reference in New Issue
Block a user