UNPKG

oauth2-server-grant-type-apple

Version:
171 lines (139 loc) 4.59 kB
import { AbstractGrantType, InvalidArgumentError, InvalidRequestError, InvalidTokenError } from 'oauth2-server'; import jwt from 'jsonwebtoken'; import jwksRsaClient from 'jwks-rsa'; function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; } const _excluded = ["token", "audience"]; const jwksClient = jwksRsaClient({ cache: true, jwksUri: 'https://appleid.apple.com/auth/keys' }); const getKey = (header, callback) => { jwksClient.getSigningKey(header.kid).then(key => { const signingKey = key.getPublicKey(); callback(null, signingKey); }).catch(err => { callback(err); }); }; const ISSUER = 'https://appleid.apple.com'; // jwt only supports callback now // https://github.com/auth0/node-jsonwebtoken/issues/111 const verifyToken = _ref => { let { token, audience } = _ref, rest = _objectWithoutPropertiesLoose(_ref, _excluded); return new Promise((resolve, reject) => { jwt.verify(token, getKey, _extends({ algorithms: ['RS256'], issuer: ISSUER, audience }, rest), (err, data) => { if (err) { return reject(err); } resolve(data); }); }); }; class AppleGrantType extends AbstractGrantType { constructor(options) { var _this$model$appleGran; super(options); this.model = void 0; this.appIds = void 0; this.model = options.model; if (!options.model) { throw new InvalidArgumentError('Missing parameter: `model`'); } if (!options.model.getUserWithApple) { throw new InvalidArgumentError('Invalid argument: model does not implement `getUserWithApple()`'); } const appId = (_this$model$appleGran = this.model.appleGrantType) == null ? void 0 : _this$model$appleGran.appId; this.appIds = appId ? Array.isArray(appId) ? appId : Array(appId) : []; if (!this.appIds.length) { throw new InvalidArgumentError('Invalid argument: Apple valid appId must be provided in grant type options'); } if (!options.model.saveToken) { throw new InvalidArgumentError('Invalid argument: model does not implement `saveToken()`'); } 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 (err) { console.error(err); throw new InvalidTokenError('Apple token is invalid or expired'); } return await this.model.getUserWithApple(_extends({ name }, data)); } async saveToken(user, client, scope) { const scopeData = await this.validateScope(user, client, scope); const accessToken = await this.generateAccessToken(client, user, scope); const refreshToken = await this.generateRefreshToken(client, user, scope); const accessTokenExpiresAt = this.getAccessTokenExpiresAt(); const refreshTokenExpiresAt = await this.getRefreshTokenExpiresAt(); const token = { accessToken, accessTokenExpiresAt, refreshToken, refreshTokenExpiresAt, scope: scopeData || [], user, client }; return await this.model.saveToken(token, client, user); } } export { AppleGrantType as default }; //# sourceMappingURL=oauth2-server-grant-type-apple.modern.mjs.map