Rebrand product as Manyangles and add Authentik

This commit is contained in:
2026-09-08 09:17:25 -04:00
parent 27e2f196eb
commit f5702caaea
37 changed files with 630 additions and 237 deletions
+3 -5
View File
@@ -26,7 +26,8 @@ import { getPlatformRole } from "@/server/roles";
import { resolveGroupQuota } from "@/server/entitlements";
import { countGroupOwners } from "@/server/membership";
import { writeAudit } from "@/server/audit";
import { hashToken, newInviteCode, newToken } from "@/server/tokens";
import { hashToken, newToken } from "@/server/tokens";
import { createInviteCode } from "@/server/invites";
import { sendStaffInviteEmail } from "@album/email";
import { publicAppOrigin } from "@/server/public-app-url";
import { GROUP_COOKIE, serializeCookie } from "@/server/cookies";
@@ -265,10 +266,7 @@ export const groupRouter = createTRPCRouter({
platformRole,
);
requireGroupPermission(access.permissions, GROUP_PERMISSIONS.PEOPLE_MANAGE);
const code = newInviteCode();
await getDb().insert(invites).values({
kind: "code",
tokenHash: hashToken(code),
const code = await createInviteCode({
reusable: input.reusable ?? false,
maxUses: input.maxUses ?? 1,
groupId: input.groupId,
+26 -1
View File
@@ -3,9 +3,22 @@ import { createTRPCRouter, protectedProcedure, publicProcedure } from "../trpc";
import { findInviteByToken, redeemInviteForUser } from "@/server/invites";
import { TRPCError } from "@trpc/server";
import { getDeploymentSettings } from "@/server/settings";
import { consumeRateLimit } from "@/server/rate-limit";
export const invitesRouter = createTRPCRouter({
preview: publicProcedure.input(redeemInviteInputSchema).query(async ({ input }) => {
preview: publicProcedure.input(redeemInviteInputSchema).query(async ({ ctx, input }) => {
const limit = await consumeRateLimit({
namespace: "invite-preview",
identifier: ctx.clientIdentifier,
limit: 12,
windowMs: 5 * 60 * 1000,
});
if (!limit.allowed) {
throw new TRPCError({
code: "TOO_MANY_REQUESTS",
message: "Too many invite attempts. Try again shortly.",
});
}
const invite = await findInviteByToken(input.token);
if (!invite) {
throw new TRPCError({ code: "NOT_FOUND", message: "Invite not found" });
@@ -23,6 +36,18 @@ export const invitesRouter = createTRPCRouter({
redeem: protectedProcedure
.input(redeemInviteInputSchema)
.mutation(async ({ ctx, input }) => {
const limit = await consumeRateLimit({
namespace: "invite-redeem",
identifier: `${ctx.session.user.id}:${ctx.clientIdentifier}`,
limit: 12,
windowMs: 5 * 60 * 1000,
});
if (!limit.allowed) {
throw new TRPCError({
code: "TOO_MANY_REQUESTS",
message: "Too many invite attempts. Try again shortly.",
});
}
return redeemInviteForUser({
token: input.token,
userId: ctx.session.user.id,
+2 -6
View File
@@ -26,8 +26,7 @@ import { hasPlatformPermission } from "@/server/roles";
import { getDeploymentSettings } from "@/server/settings";
import { grantEntitlement, resolveGroupQuota } from "@/server/entitlements";
import { writeAudit } from "@/server/audit";
import { hashToken, newInviteCode } from "@/server/tokens";
import { invites } from "@album/database";
import { createInviteCode } from "@/server/invites";
export const platformRouter = createTRPCRouter({
settings: platformPermissionProcedure(PLATFORM_PERMISSIONS.SETTINGS_MANAGE).query(
@@ -200,10 +199,7 @@ export const platformRouter = createTRPCRouter({
createCode: platformPermissionProcedure(PLATFORM_PERMISSIONS.ENTITLEMENTS_MANAGE)
.input(createInviteCodeInputSchema)
.mutation(async ({ ctx, input }) => {
const code = newInviteCode();
await getDb().insert(invites).values({
kind: "code",
tokenHash: hashToken(code),
const code = await createInviteCode({
reusable: input.reusable ?? true,
maxUses: input.maxUses ?? 100,
groupId: input.groupId ?? null,