refactor(server): auth (#5895)

Remove `next-auth` and implement our own Authorization/Authentication system from scratch.

## Server

- [x] tokens
  - [x] function
  - [x] encryption

- [x] AuthController
  - [x] /api/auth/sign-in
  - [x] /api/auth/sign-out
  - [x] /api/auth/session
  - [x] /api/auth/session (WE SUPPORT MULTI-ACCOUNT!)

- [x] OAuthPlugin
  - [x] OAuthController
  - [x] /oauth/login
  - [x] /oauth/callback
  - [x] Providers
    - [x] Google
    - [x] GitHub

## Client

- [x] useSession
- [x] cloudSignIn
- [x] cloudSignOut

## NOTE:

Tests will be adding in the future
This commit is contained in:
liuyi
2024-03-12 10:00:09 +00:00
parent af49e8cc41
commit fb3a0e7b8f
148 changed files with 3407 additions and 2851 deletions

View File

@@ -1,13 +1,14 @@
import { ServerFeature } from '../../core/config';
import { FeatureModule } from '../../core/features';
import { OptionalModule } from '../../fundamentals';
import { Plugin } from '../registry';
import { SubscriptionResolver, UserSubscriptionResolver } from './resolver';
import { ScheduleManager } from './schedule';
import { SubscriptionService } from './service';
import { StripeProvider } from './stripe';
import { StripeWebhook } from './webhook';
@OptionalModule({
@Plugin({
name: 'payment',
imports: [FeatureModule],
providers: [
ScheduleManager,

View File

@@ -21,8 +21,8 @@ import type { User, UserInvoice, UserSubscription } from '@prisma/client';
import { PrismaClient } from '@prisma/client';
import { groupBy } from 'lodash-es';
import { Auth, CurrentUser, Public } from '../../core/auth';
import { UserType } from '../../core/users';
import { CurrentUser, Public } from '../../core/auth';
import { UserType } from '../../core/user';
import { Config } from '../../fundamentals';
import { decodeLookupKey, SubscriptionService } from './service';
import {
@@ -155,7 +155,6 @@ class CreateCheckoutSessionInput {
idempotencyKey!: string;
}
@Auth()
@Resolver(() => UserSubscriptionType)
export class SubscriptionResolver {
constructor(
@@ -217,7 +216,7 @@ export class SubscriptionResolver {
description: 'Create a subscription checkout link of stripe',
})
async checkout(
@CurrentUser() user: User,
@CurrentUser() user: CurrentUser,
@Args({ name: 'recurring', type: () => SubscriptionRecurring })
recurring: SubscriptionRecurring,
@Args('idempotencyKey') idempotencyKey: string
@@ -241,7 +240,7 @@ export class SubscriptionResolver {
description: 'Create a subscription checkout link of stripe',
})
async createCheckoutSession(
@CurrentUser() user: User,
@CurrentUser() user: CurrentUser,
@Args({ name: 'input', type: () => CreateCheckoutSessionInput })
input: CreateCheckoutSessionInput
) {
@@ -265,13 +264,13 @@ export class SubscriptionResolver {
@Mutation(() => String, {
description: 'Create a stripe customer portal to manage payment methods',
})
async createCustomerPortal(@CurrentUser() user: User) {
async createCustomerPortal(@CurrentUser() user: CurrentUser) {
return this.service.createCustomerPortal(user.id);
}
@Mutation(() => UserSubscriptionType)
async cancelSubscription(
@CurrentUser() user: User,
@CurrentUser() user: CurrentUser,
@Args('idempotencyKey') idempotencyKey: string
) {
return this.service.cancelSubscription(idempotencyKey, user.id);
@@ -279,7 +278,7 @@ export class SubscriptionResolver {
@Mutation(() => UserSubscriptionType)
async resumeSubscription(
@CurrentUser() user: User,
@CurrentUser() user: CurrentUser,
@Args('idempotencyKey') idempotencyKey: string
) {
return this.service.resumeCanceledSubscription(idempotencyKey, user.id);
@@ -287,7 +286,7 @@ export class SubscriptionResolver {
@Mutation(() => UserSubscriptionType)
async updateSubscriptionRecurring(
@CurrentUser() user: User,
@CurrentUser() user: CurrentUser,
@Args({ name: 'recurring', type: () => SubscriptionRecurring })
recurring: SubscriptionRecurring,
@Args('idempotencyKey') idempotencyKey: string

View File

@@ -10,6 +10,7 @@ import type {
import { PrismaClient } from '@prisma/client';
import Stripe from 'stripe';
import { CurrentUser } from '../../core/auth';
import { FeatureManagementService } from '../../core/features';
import { EventEmitter } from '../../fundamentals';
import { ScheduleManager } from './schedule';
@@ -75,7 +76,7 @@ export class SubscriptionService {
redirectUrl,
idempotencyKey,
}: {
user: User;
user: CurrentUser;
recurring: SubscriptionRecurring;
plan: SubscriptionPlan;
promotionCode?: string | null;
@@ -549,7 +550,7 @@ export class SubscriptionService {
private async getOrCreateCustomer(
idempotencyKey: string,
user: User
user: CurrentUser
): Promise<UserStripeCustomer> {
const customer = await this.db.userStripeCustomer.findUnique({
where: {
@@ -649,7 +650,7 @@ export class SubscriptionService {
}
private async getAvailableCoupon(
user: User,
user: CurrentUser,
couponType: CouponType
): Promise<string | null> {
const earlyAccess = await this.features.isEarlyAccessUser(user.email);