Files
netris-nestri/packages/functions/src/api/auth.ts
Wanjohi 47e61599bb feat(api): Add payments with Polar.sh (#264)
## Description
<!-- Briefly describe the purpose and scope of your changes -->


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Introduced a new subscription API endpoint for managing subscriptions
and products.
- Enhanced subscription management with new entities and
functionalities.
- Added functionality to retrieve current timestamps in both local and
UTC formats.
- Added Polar.sh integration with customer portal and checkout session
creation APIs.

- **Refactor**
- Redesigned team details to now present members and subscription
information instead of a plan type.
  - Enhanced member management by incorporating role assignments.
- Streamlined user data handling and removed legacy subscription event
logic.
  - Simplified error handling in actor functions for better clarity.
  - Updated plan types and UI labels to reflect new subscription tiers.
  - Improved database indexing for Steam user data.

- **Chores**
- Updated the database schema with new tables and fields to support
subscription, team, and member enhancements.
  - Extended identifier prefixes to broaden system integration.
- Added new secrets related to pricing plans in infrastructure
configuration.
  - Configured API and auth routing with new domain and routing rules.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-04-18 14:24:19 +03:00

63 lines
1.7 KiB
TypeScript

import { Resource } from "sst";
import { subjects } from "../subjects";
import { type MiddlewareHandler } from "hono";
import { useActor, withActor } from "@nestri/core/actor";
import { createClient } from "@openauthjs/openauth/client";
import { ErrorCodes, VisibleError } from "@nestri/core/error";
const client = createClient({
issuer: Resource.Auth.url,
clientID: "api",
});
export const notPublic: MiddlewareHandler = async (c, next) => {
const actor = useActor();
if (actor.type === "public")
throw new VisibleError(
"authentication",
ErrorCodes.Authentication.UNAUTHORIZED,
"Missing authorization header",
);
return next();
};
export const auth: MiddlewareHandler = async (c, next) => {
const authHeader =
c.req.query("authorization") ?? c.req.header("authorization");
if (!authHeader) return withActor({ type: "public", properties: {} }, next);
const match = authHeader.match(/^Bearer (.+)$/);
if (!match) {
throw new VisibleError(
"authentication",
ErrorCodes.Authentication.INVALID_TOKEN,
"Invalid personal access token",
);
}
const bearerToken = match[1];
let result = await client.verify(subjects, bearerToken!);
if (result.err) {
throw new VisibleError(
"authentication",
ErrorCodes.Authentication.INVALID_TOKEN,
"Invalid bearer token",
);
}
if (result.subject.type === "user") {
const teamID = c.req.header("x-nestri-team");
if (!teamID) return withActor(result.subject, next);
return withActor(
{
type: "system",
properties: {
teamID,
},
},
async () =>
withActor(
result.subject,
next,
)
);
}
};