Skip to content

Commit

Permalink
refactor(server): auth
Browse files Browse the repository at this point in the history
  • Loading branch information
forehalo authored and darkskygit committed Feb 29, 2024
1 parent 752c858 commit 3437fc3
Show file tree
Hide file tree
Showing 105 changed files with 2,394 additions and 2,006 deletions.
22 changes: 0 additions & 22 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,6 @@ const createPattern = packageName => [
message: 'Use `useNavigateHelper` instead',
importNames: ['useNavigate'],
},
{
group: ['next-auth/react'],
message: "Import hooks from 'use-current-user.tsx'",
// useSession is type unsafe
importNames: ['useSession'],
},
{
group: ['next-auth/react'],
message: "Import hooks from 'cloud-utils.ts'",
importNames: ['signIn', 'signOut'],
},
{
group: ['yjs'],
message: 'Do not use this API because it has a bug',
Expand Down Expand Up @@ -179,17 +168,6 @@ const config = {
message: 'Use `useNavigateHelper` instead',
importNames: ['useNavigate'],
},
{
group: ['next-auth/react'],
message: "Import hooks from 'use-current-user.tsx'",
// useSession is type unsafe
importNames: ['useSession'],
},
{
group: ['next-auth/react'],
message: "Import hooks from 'cloud-utils.ts'",
importNames: ['signIn', 'signOut'],
},
{
group: ['yjs'],
message: 'Do not use this API because it has a bug',
Expand Down
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,6 @@
"unbox-primitive": "npm:@nolyfill/unbox-primitive@latest",
"which-boxed-primitive": "npm:@nolyfill/which-boxed-primitive@latest",
"which-typed-array": "npm:@nolyfill/which-typed-array@latest",
"next-auth@^4.24.5": "patch:next-auth@npm%3A4.24.5#~/.yarn/patches/next-auth-npm-4.24.5-8428e11927.patch",
"@reforged/maker-appimage/@electron-forge/maker-base": "7.3.0",
"macos-alias": "npm:@napi-rs/macos-alias@latest",
"fs-xattr": "npm:@napi-rs/xattr@latest",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
-- DropForeignKey
ALTER TABLE "accounts" DROP CONSTRAINT "accounts_user_id_fkey";

-- DropForeignKey
ALTER TABLE "sessions" DROP CONSTRAINT "sessions_user_id_fkey";

-- CreateTable
CREATE TABLE "user_connected_accounts" (
"id" VARCHAR(36) NOT NULL,
"user_id" VARCHAR(36) NOT NULL,
"provider" VARCHAR NOT NULL,
"provider_account_id" VARCHAR NOT NULL,
"scope" TEXT,
"access_token" TEXT,
"refresh_token" TEXT,
"expires_at" TIMESTAMPTZ(6),
"created_at" TIMESTAMPTZ(6) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMPTZ(6) NOT NULL,

CONSTRAINT "user_connected_accounts_pkey" PRIMARY KEY ("id")
);

-- CreateTable
CREATE TABLE "multiple_users_sessions" (
"id" VARCHAR(36) NOT NULL,
"expires_at" TIMESTAMPTZ(6),
"created_at" TIMESTAMPTZ(6) NOT NULL DEFAULT CURRENT_TIMESTAMP,

CONSTRAINT "multiple_users_sessions_pkey" PRIMARY KEY ("id")
);

-- CreateTable
CREATE TABLE "user_sessions" (
"id" VARCHAR(36) NOT NULL,
"session_id" VARCHAR(36) NOT NULL,
"user_id" VARCHAR(36) NOT NULL,
"expires_at" TIMESTAMPTZ(6),
"created_at" TIMESTAMPTZ(6) NOT NULL DEFAULT CURRENT_TIMESTAMP,

CONSTRAINT "user_sessions_pkey" PRIMARY KEY ("id")
);

-- CreateTable
CREATE TABLE "verification_tokens" (
"token" VARCHAR(36) NOT NULL,
"type" SMALLINT NOT NULL,
"credential" TEXT,
"expiresAt" TIMESTAMPTZ(6) NOT NULL
);

-- CreateIndex
CREATE INDEX "user_connected_accounts_user_id_idx" ON "user_connected_accounts"("user_id");

-- CreateIndex
CREATE INDEX "user_connected_accounts_provider_account_id_idx" ON "user_connected_accounts"("provider_account_id");

-- CreateIndex
CREATE UNIQUE INDEX "user_sessions_session_id_user_id_key" ON "user_sessions"("session_id", "user_id");

-- CreateIndex
CREATE UNIQUE INDEX "verification_tokens_type_token_key" ON "verification_tokens"("type", "token");

-- AddForeignKey
ALTER TABLE "user_connected_accounts" ADD CONSTRAINT "user_connected_accounts_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE "user_sessions" ADD CONSTRAINT "user_sessions_session_id_fkey" FOREIGN KEY ("session_id") REFERENCES "multiple_users_sessions"("id") ON DELETE CASCADE ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE "user_sessions" ADD CONSTRAINT "user_sessions_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE;
1 change: 0 additions & 1 deletion packages/backend/server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,6 @@
"nanoid": "^5.0.6",
"nest-commander": "^3.12.5",
"nestjs-throttler-storage-redis": "^0.4.1",
"next-auth": "^4.24.5",
"nodemailer": "^6.9.10",
"on-headers": "^1.0.2",
"parse-duration": "^1.1.0",
Expand Down
81 changes: 65 additions & 16 deletions packages/backend/server/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -10,28 +10,80 @@ datasource db {
}

model User {
id String @id @default(uuid()) @db.VarChar
name String
email String @unique
emailVerified DateTime? @map("email_verified")
// image field is for the next-auth
avatarUrl String? @map("avatar_url") @db.VarChar
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(6)
id String @id @default(uuid()) @db.VarChar
name String
email String @unique
emailVerifiedAt DateTime? @map("email_verified")
avatarUrl String? @map("avatar_url") @db.VarChar
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(6)
/// Not available if user signed up through OAuth providers
password String? @db.VarChar
password String? @db.VarChar
accounts Account[]
sessions Session[]
features UserFeatures[]
customer UserStripeCustomer?
subscription UserSubscription?
invoices UserInvoice[]
workspacePermissions WorkspaceUserPermission[]
pagePermissions WorkspacePageUserPermission[]
connectedAccounts ConnectedAccount[]
sessions UserSession[]
@@map("users")
}

model ConnectedAccount {
id String @id @default(uuid()) @db.VarChar(36)
userId String @map("user_id") @db.VarChar(36)
provider String @db.VarChar
providerAccountId String @map("provider_account_id") @db.VarChar
scope String? @db.Text
accessToken String? @map("access_token") @db.Text
refreshToken String? @map("refresh_token") @db.Text
expiresAt DateTime? @map("expires_at") @db.Timestamptz(6)
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(6)
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz(6)
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@index([userId])
@@index([providerAccountId])
@@map("user_connected_accounts")
}

model Session {
id String @id @default(uuid()) @db.VarChar(36)
expiresAt DateTime? @map("expires_at") @db.Timestamptz(6)
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(6)
userSessions UserSession[]
@@map("multiple_users_sessions")
}

model UserSession {
id String @id @default(uuid()) @db.VarChar(36)
sessionId String @map("session_id") @db.VarChar(36)
userId String @map("user_id") @db.VarChar(36)
expiresAt DateTime? @map("expires_at") @db.Timestamptz(6)
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(6)
session Session @relation(fields: [sessionId], references: [id], onDelete: Cascade)
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@unique([sessionId, userId])
@@map("user_sessions")
}

model VerificationToken {
token String @db.VarChar(36)
type Int @db.SmallInt
credential String? @db.Text
expiresAt DateTime @db.Timestamptz(6)
@@unique([type, token])
@@map("verification_tokens")
}

model Workspace {
id String @id @default(uuid()) @db.VarChar
public Boolean
Expand Down Expand Up @@ -186,7 +238,7 @@ model Features {
@@map("features")
}

model Account {
model DeprecatedNextAuthAccount {
id String @id @default(cuid())
userId String @map("user_id")
type String
Expand All @@ -200,23 +252,20 @@ model Account {
id_token String? @db.Text
session_state String?
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@unique([provider, providerAccountId])
@@map("accounts")
}

model Session {
model DeprecatedNextAuthSession {
id String @id @default(cuid())
sessionToken String @unique @map("session_token")
userId String @map("user_id")
expires DateTime
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@map("sessions")
}

model VerificationToken {
model DeprecatedNextAuthVerificationToken {
identifier String
token String @unique
expires DateTime
Expand Down
16 changes: 10 additions & 6 deletions packages/backend/server/src/app.module.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { join } from 'node:path';

import { Logger, Module } from '@nestjs/common';
import { APP_INTERCEPTOR } from '@nestjs/core';
import { APP_GUARD, APP_INTERCEPTOR } from '@nestjs/core';
import { ScheduleModule } from '@nestjs/schedule';
import { ServeStaticModule } from '@nestjs/serve-static';
import { get } from 'lodash-es';

import { AppController } from './app.controller';
import { AuthModule } from './core/auth';
import { AuthGuard, AuthModule } from './core/auth';
import { ADD_ENABLED_FEATURES, ServerConfigModule } from './core/config';
import { DocModule } from './core/doc';
import { FeatureModule } from './core/features';
Expand All @@ -25,14 +25,14 @@ import {
} from './fundamentals/config';
import { EventModule } from './fundamentals/event';
import { GqlModule } from './fundamentals/graphql';
import { HelpersModule } from './fundamentals/helpers';
import { MailModule } from './fundamentals/mailer';
import { MetricsModule } from './fundamentals/metrics';
import { PrismaModule } from './fundamentals/prisma';
import { SessionModule } from './fundamentals/session';
import { StorageProviderModule } from './fundamentals/storage';
import { RateLimiterModule } from './fundamentals/throttler';
import { WebSocketModule } from './fundamentals/websocket';
import { pluginsMap } from './plugins';
import { REGISTERED_PLUGINS } from './plugins';

export const FunctionalityModules = [
ConfigModule.forRoot(),
Expand All @@ -42,9 +42,9 @@ export const FunctionalityModules = [
PrismaModule,
MetricsModule,
RateLimiterModule,
SessionModule,
MailModule,
StorageProviderModule,
HelpersModule,
];

export class AppModuleBuilder {
Expand Down Expand Up @@ -109,6 +109,10 @@ export class AppModuleBuilder {
provide: APP_INTERCEPTOR,
useClass: CacheInterceptor,
},
{
provide: APP_GUARD,
useClass: AuthGuard,
},
],
imports: this.modules,
controllers: this.config.isSelfhosted ? [] : [AppController],
Expand Down Expand Up @@ -157,7 +161,7 @@ function buildAppModule() {

// plugin modules
AFFiNE.plugins.enabled.forEach(name => {
const plugin = pluginsMap.get(name as AvailablePlugins);
const plugin = REGISTERED_PLUGINS.get(name as AvailablePlugins);
if (!plugin) {
throw new Error(`Unknown plugin ${name}`);
}
Expand Down
10 changes: 4 additions & 6 deletions packages/backend/server/src/config/affine.env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,10 @@ AFFiNE.ENV_MAP = {
DATABASE_URL: 'db.url',
ENABLE_CAPTCHA: ['auth.captcha.enable', 'boolean'],
CAPTCHA_TURNSTILE_SECRET: ['auth.captcha.turnstile.secret', 'string'],
OAUTH_GOOGLE_ENABLED: ['auth.oauthProviders.google.enabled', 'boolean'],
OAUTH_GOOGLE_CLIENT_ID: 'auth.oauthProviders.google.clientId',
OAUTH_GOOGLE_CLIENT_SECRET: 'auth.oauthProviders.google.clientSecret',
OAUTH_GITHUB_ENABLED: ['auth.oauthProviders.github.enabled', 'boolean'],
OAUTH_GITHUB_CLIENT_ID: 'auth.oauthProviders.github.clientId',
OAUTH_GITHUB_CLIENT_SECRET: 'auth.oauthProviders.github.clientSecret',
OAUTH_GOOGLE_CLIENT_ID: 'plugins.oauth.providers.google.clientId',
OAUTH_GOOGLE_CLIENT_SECRET: 'plugins.oauth.providers.google.clientSecret',
OAUTH_GITHUB_CLIENT_ID: 'plugins.oauth.providers.github.clientId',
OAUTH_GITHUB_CLIENT_SECRET: 'plugins.oauth.providers.github.clientSecret',
MAILER_HOST: 'mailer.host',
MAILER_PORT: ['mailer.port', 'int'],
MAILER_USER: 'mailer.auth.user',
Expand Down
1 change: 1 addition & 0 deletions packages/backend/server/src/config/affine.self.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ if (env.R2_OBJECT_STORAGE_ACCOUNT_ID) {

AFFiNE.plugins.use('redis');
AFFiNE.plugins.use('payment');
AFFiNE.plugins.use('oauth');

if (AFFiNE.deploy) {
AFFiNE.mailer = {
Expand Down
24 changes: 24 additions & 0 deletions packages/backend/server/src/config/affine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,3 +115,27 @@ AFFiNE.plugins.use('payment', {
// /* Update the provider of storages */
// AFFiNE.storage.storages.blob.provider = 'r2';
// AFFiNE.storage.storages.avatar.provider = 'r2';
//
// /* OAuth Plugin */
// AFFiNE.plugins.use('oauth', {
// providers: {
// github: {
// clientId: '',
// clientSecret: '',
// // See https://docs.github.com/en/apps/oauth-apps/building-oauth-apps/authorizing-oauth-apps
// args: {
// scope: 'user',
// },
// },
// google: {
// clientId: '',
// clientSecret: '',
// args: {
// // See https://developers.google.com/identity/protocols/oauth2
// scope: 'openid email profile',
// promot: 'select_account',
// access_type: 'offline',
// },
// },
// },
// });

0 comments on commit 3437fc3

Please sign in to comment.