Skip to content

Commit

Permalink
gitignore, biome, vscode
Browse files Browse the repository at this point in the history
  • Loading branch information
DexterStorey committed Oct 3, 2024
1 parent 4e5f880 commit 705921e
Show file tree
Hide file tree
Showing 9 changed files with 130 additions and 96 deletions.
17 changes: 17 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Dependency directories
node_modules/
dist
.DS_Store

# Output of 'npm pack'
*.tgz

# dotenv environment variable files
.env
.env.development.local
.env.test.local
.env.production.local
.env.local

# turbo
.turbo
21 changes: 21 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"editor.defaultFormatter": "biomejs.biome",
"editor.formatOnSave": true,
"editor.formatOnType": true,
"[typescript]": {
"editor.defaultFormatter": "biomejs.biome"
},
"[typescriptreact]": {
"editor.defaultFormatter": "biomejs.biome"
},
"[json]": {
"editor.defaultFormatter": "biomejs.biome"
},
"editor.codeActionsOnSave": {
"quickfix.biome": "explicit",
"source.organizeImports.biome": "explicit"
},
"[prisma]": {
"editor.defaultFormatter": "Prisma.prisma"
}
}
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
- [2024-10-02] [gitignore, biome, vscode](https://github.com/RubricLab/auth/commit/017182b92cbae09df53e41423db10c788ba94bf7)
- [2024-10-02] [init](https://github.com/RubricLab/auth/commit/40145b017976d9a7393063a4640e6965af45eac4)
# Changelog

3 changes: 3 additions & 0 deletions biome.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"extends": ["@rubriclab/config/biome"]
}
4 changes: 2 additions & 2 deletions index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export type {
AuthProvider,
AuthProviderConfig,
} from "./lib/types";
AuthProviderConfig
} from './lib/types'
75 changes: 33 additions & 42 deletions lib/route.ts
Original file line number Diff line number Diff line change
@@ -1,37 +1,31 @@
import { type NextRequest, NextResponse } from "next/server";
import type {
AuthProviders,
DB,
UserInfo,
AuthProvider,
AuthTokens,
} from "./types";
import { type NextRequest, NextResponse } from 'next/server'
import type { AuthProviders, DB, UserInfo, AuthProvider, AuthTokens } from './types'

async function connectAuthProvider({
userId,
userInfo,
provider,
authTokens,
db,
db
}: {
userId: string;
userInfo: UserInfo;
provider: AuthProvider;
authTokens: AuthTokens;
db: DB;
userId: string
userInfo: UserInfo
provider: AuthProvider
authTokens: AuthTokens
db: DB
}) {
await db.authProvider.upsert({
where: {
userId_provider_accountId: {
provider: provider.config.provider,
userId,
accountId: userInfo.accountId,
},
accountId: userInfo.accountId
}
},
update: {
accessToken: authTokens.accessToken,
refreshToken: authTokens.refreshToken,
expiresAt: authTokens.expiresAt ? new Date(authTokens.expiresAt) : null,
expiresAt: authTokens.expiresAt ? new Date(authTokens.expiresAt) : null
},
create: {
provider: provider.config.provider,
Expand All @@ -41,53 +35,50 @@ async function connectAuthProvider({
accessToken: authTokens.accessToken,
refreshToken: authTokens.refreshToken,
expiresAt: authTokens.expiresAt ? new Date(authTokens.expiresAt) : null,
userId,
},
});
userId
}
})
}

export function createAuthCallbackHandler({
authProviders,
db,
url,
url
}: {
authProviders: AuthProviders;
db: DB;
url: string;
authProviders: AuthProviders
db: DB
url: string
}) {
return async (
request: NextRequest,
{ params }: { params: { provider: keyof AuthProviders } },
{ params }: { params: { provider: keyof AuthProviders } }
): Promise<NextResponse> => {
const provider = authProviders[params.provider];
const provider = authProviders[params.provider]
if (!provider) {
return NextResponse.redirect(`${url}?error=InvalidProvider`);
return NextResponse.redirect(`${url}?error=InvalidProvider`)
}
const code = request.nextUrl.searchParams.get("code");
const code = request.nextUrl.searchParams.get('code')
if (!code) {
return NextResponse.redirect(`${url}?error=NoCodeProvided`);
return NextResponse.redirect(`${url}?error=NoCodeProvided`)
}

const userId = request.nextUrl.searchParams.get("state");
const userId = request.nextUrl.searchParams.get('state')
if (!userId) {
return NextResponse.redirect(`${url}?error=NoUserIdProvided`);
return NextResponse.redirect(`${url}?error=NoUserIdProvided`)
}

try {
const authTokens = await provider.getTokensFromCode({ code });
const authTokens = await provider.getTokensFromCode({ code })
const userInfo = await provider.getUserInfo({
token: authTokens.accessToken,
});
token: authTokens.accessToken
})

await connectAuthProvider({ userId, provider, authTokens, userInfo, db });
await connectAuthProvider({ userId, provider, authTokens, userInfo, db })

return NextResponse.redirect(`${url}?success=true`);
return NextResponse.redirect(`${url}?success=true`)
} catch (error) {
console.error(
`Error during ${provider.config.provider} auth callback:`,
error,
);
return NextResponse.redirect(`${url}?error=AuthFailed`);
console.error(`Error during ${provider.config.provider} auth callback:`, error)
return NextResponse.redirect(`${url}?error=AuthFailed`)
}
};
}
}
50 changes: 25 additions & 25 deletions lib/types.ts
Original file line number Diff line number Diff line change
@@ -1,49 +1,49 @@
import type { PrismaClient } from "@prisma/client";
import type { PrismaClient } from '@prisma/client'

export interface UserInfo {
accountId: string;
label: string;
accountId: string
label: string
}

export interface AuthProviderConfig {
provider: string;
scopes: string[];
clientId: string;
clientSecret: string;
provider: string
scopes: string[]
clientId: string
clientSecret: string
}

export interface AuthTokens {
accessToken: string;
refreshToken: string | null;
expiresAt: number | null;
accessToken: string
refreshToken: string | null
expiresAt: number | null
}

export interface AuthProvider {
config: AuthProviderConfig;
getAuthUrl: ({ userId }: { userId: string }) => string;
getTokensFromCode({ code }: { code: string }): Promise<AuthTokens>;
config: AuthProviderConfig
getAuthUrl: ({ userId }: { userId: string }) => string
getTokensFromCode({ code }: { code: string }): Promise<AuthTokens>
getAccessToken({
userId,
accountId,
accountId
}: {
userId: string;
accountId: string;
}): Promise<{ accessToken: string }>;
getUserInfo({ token }: { token: string }): Promise<UserInfo>;
userId: string
accountId: string
}): Promise<{ accessToken: string }>
getUserInfo({ token }: { token: string }): Promise<UserInfo>
}

export type AuthProviders = {
[provider in string]?: AuthProvider;
};
[provider in string]?: AuthProvider
}

export interface User {
id: string;
id: string
}

export interface WebhookInfo {
id: string;
type: string;
enabled: boolean;
id: string
type: string
enabled: boolean
}

export type DB = PrismaClient;
export type DB = PrismaClient
50 changes: 25 additions & 25 deletions lib/utils.ts
Original file line number Diff line number Diff line change
@@ -1,59 +1,59 @@
import type { Prisma } from "@prisma/client";
import type { Prisma } from '@prisma/client'

import type { AuthProviders } from "./types";
import type { AuthProviders } from './types'

export function createAuthActions({
authProviders,
db,
db
}: {
authProviders: AuthProviders;
authProviders: AuthProviders
db: {
authProvider: Prisma.AuthProviderDelegate;
};
authProvider: Prisma.AuthProviderDelegate
}
}) {
return {
async getAuthUrl({
userId,
provider,
provider
}: {
userId: string;
provider: string;
userId: string
provider: string
}) {
const authProvider = authProviders[provider];
const authProvider = authProviders[provider]

if (!authProvider) {
throw new Error(`Auth provider not found for ${provider}`);
throw new Error(`Auth provider not found for ${provider}`)
}

return authProvider.getAuthUrl({ userId });
return authProvider.getAuthUrl({ userId })
},

async getConnectedAccounts({ userId }: { userId: string }) {
const connectedAccounts = await db.authProvider.findMany({
where: { userId },
});
where: { userId }
})

return connectedAccounts;
return connectedAccounts
},

async disconnectAuthProvider({
userId,
provider,
accountId,
accountId
}: {
userId: string;
provider: string;
accountId: string;
userId: string
provider: string
accountId: string
}) {
await db.authProvider.delete({
where: {
userId_provider_accountId: {
userId,
provider,
accountId,
},
},
});
},
};
accountId
}
}
})
}
}
}
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,11 @@
"lint:fix": "bun x biome lint . --write --unsafe"
},
"name": "@rubriclab/auth",
"version": "0.0.1",
"version": "0.0.2",
"main": "index.ts",
"dependencies": {
"@rubriclab/package": "*"
"@rubriclab/package": "*",
"@rubriclab/config": "*"
},
"simple-git-hooks": {
"post-commit": "bun run rubriclab-postcommit"
Expand Down

0 comments on commit 705921e

Please sign in to comment.