@youngshand/payload-auth-plugin
Version:
A temporary fork for testing of Authentication plugin for Payload CMS, use @payload-auth-plugin
141 lines (129 loc) • 3.74 kB
text/typescript
import { BasePayload, JsonObject, PayloadRequest, TypeWithID } from "payload"
import { AccountInfo, AuthenticationStrategy } from "../../types.js"
import { UserNotFoundAPIError } from "../errors/apiErrors.js"
import {
createSessionCookies,
invalidateOAuthCookies,
} from "../utils/cookies.js"
import { sessionResponse } from "../utils/session.js"
import { APP_COOKIE_SUFFIX } from "../../constants.js"
export class AppSession {
constructor(
private appName: string,
private collections: {
usersCollection: string
accountsCollection: string
},
private allowAutoSignUp: boolean,
private authenticationStrategy: AuthenticationStrategy,
private secret: string,
) {}
private async oauthAccountMutations(
userId: string,
oauthAccountInfo: AccountInfo,
scope: string,
issuerName: string,
payload: BasePayload,
): Promise<JsonObject & TypeWithID> {
const data: Record<string, unknown> = {
scope,
name: oauthAccountInfo.name,
picture: oauthAccountInfo.picture,
issuerName,
}
const accountRecords = await payload.find({
collection: this.collections.accountsCollection,
where: {
sub: { equals: oauthAccountInfo.sub },
},
})
if (accountRecords.docs && accountRecords.docs.length === 1) {
return await payload.update({
collection: this.collections.accountsCollection,
id: accountRecords.docs[0].id,
data,
})
} else {
data["sub"] = oauthAccountInfo.sub
data["user"] = userId
return await payload.create({
collection: this.collections.accountsCollection,
data,
})
}
}
async oauthSessionCallback(
oauthAccountInfo: AccountInfo,
scope: string,
issuerName: string,
request: PayloadRequest,
clientOrigin: string,
) {
const { payload } = request
const userRecords = await payload.find({
collection: this.collections.usersCollection,
where: {
email: {
equals: oauthAccountInfo.email,
},
},
})
let userRecord: JsonObject & TypeWithID
if (userRecords.docs.length === 1) {
userRecord = userRecords.docs[0]
} else if (this.allowAutoSignUp) {
const userRecords = await payload.create({
collection: this.collections.usersCollection,
data: {
email: oauthAccountInfo.email,
},
})
userRecord = userRecords
} else {
throw new UserNotFoundAPIError()
}
await this.oauthAccountMutations(
userRecord["id"] as string,
oauthAccountInfo,
scope,
issuerName,
payload,
)
let cookies: string[] = []
if (this.authenticationStrategy === "Cookie") {
cookies = [
...(await createSessionCookies(
`__${this.appName}-${APP_COOKIE_SUFFIX}`,
this.secret,
{
id: userRecord["id"],
email: oauthAccountInfo.email,
collection: this.collections.usersCollection,
},
)),
]
cookies = invalidateOAuthCookies(cookies)
}
return sessionResponse(cookies, clientOrigin)
}
async passwordSessionCallback(
user: Pick<AccountInfo, "email"> & { id: string },
) {
let cookies: string[] = []
if (this.authenticationStrategy === "Cookie") {
cookies = [
...(await createSessionCookies(
`__${this.appName}-${APP_COOKIE_SUFFIX}`,
this.secret,
{
id: user.id,
email: user.email,
collection: this.collections.usersCollection,
},
)),
]
cookies = invalidateOAuthCookies(cookies)
}
return sessionResponse(cookies)
}
}