UNPKG

oauth2-server-grant-type-apple

Version:
75 lines (74 loc) 2.86 kB
import { AbstractGrantType, InvalidArgumentError, InvalidRequestError, InvalidTokenError } from "@node-oauth/oauth2-server"; import { createRemoteJWKSet, jwtVerify } from "jose"; //#region src/verify-token.ts const JWKS = createRemoteJWKSet(new URL("https://appleid.apple.com/auth/keys")); const ISSUER = "https://appleid.apple.com"; const verifyToken = async ({ token, audience }) => { const { payload } = await jwtVerify(token, JWKS, { algorithms: ["RS256"], issuer: ISSUER, audience }); return payload; }; //#endregion //#region src/apple-grant-type.ts var AppleGrantType = class extends AbstractGrantType { constructor(options) { super(options); this.appIds = []; if (!options.model) throw new InvalidArgumentError("Missing parameter: `model`"); if (!options.model.getUserWithApple) throw new InvalidArgumentError("Invalid argument: model does not implement `getUserWithApple()`"); if (!options.model.saveToken) throw new InvalidArgumentError("Invalid argument: model does not implement `saveToken()`"); this.model = options.model; const appId = this.model.appleGrantType?.appId; if (appId) this.appIds = Array.isArray(appId) ? appId : [appId]; if (this.appIds.length === 0) throw new InvalidArgumentError("Invalid argument: Apple valid appId must be provided in options"); this.handle = this.handle.bind(this); this.getUser = this.getUser.bind(this); this.saveToken = this.saveToken.bind(this); } async handle(request, client) { if (!request) throw new InvalidArgumentError("Missing parameter: `request`"); if (!client) throw new InvalidArgumentError("Missing parameter: `client`"); const scope = this.getScope(request); const user = await this.getUser(request); return await this.saveToken(user, client, scope); } async getUser(request) { const token = request.body.apple_token; const name = request.body.name; if (!token) throw new InvalidRequestError("Missing parameter: `apple_token`"); let data; try { data = await verifyToken({ token, audience: this.appIds }); } catch { throw new InvalidTokenError("Apple id token is invalid or expired"); } return await this.model.getUserWithApple({ name, ...data }); } async saveToken(user, client, scope) { const validatedScope = await this.validateScope(user, client, scope); const accessToken = await this.generateAccessToken(client, user, scope); const refreshToken = await this.generateRefreshToken(client, user, scope); const token = { accessToken, accessTokenExpiresAt: this.getAccessTokenExpiresAt(), refreshToken, refreshTokenExpiresAt: this.getRefreshTokenExpiresAt(), scope: validatedScope || [], user: { id: user.id }, client }; return await this.model.saveToken(token, client, user); } }; //#endregion export { AppleGrantType, verifyToken }; //# sourceMappingURL=index.js.map