oauth2-server-grant-type-apple
Version:
Apple grant type for oauth2-server
178 lines (143 loc) • 4.94 kB
JavaScript
;
var oauth2Server = require('oauth2-server');
var jwt = require('jsonwebtoken');
var jwksRsaClient = require('jwks-rsa');
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
var jwt__default = /*#__PURE__*/_interopDefaultLegacy(jwt);
var jwksRsaClient__default = /*#__PURE__*/_interopDefaultLegacy(jwksRsaClient);
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__default["default"]({
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__default["default"].verify(token, getKey, _extends({
algorithms: ['RS256'],
issuer: ISSUER,
audience
}, rest), (err, data) => {
if (err) {
return reject(err);
}
resolve(data);
});
});
};
class AppleGrantType extends oauth2Server.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 oauth2Server.InvalidArgumentError('Missing parameter: `model`');
}
if (!options.model.getUserWithApple) {
throw new oauth2Server.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 oauth2Server.InvalidArgumentError('Invalid argument: Apple valid appId must be provided in grant type options');
}
if (!options.model.saveToken) {
throw new oauth2Server.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 oauth2Server.InvalidArgumentError('Missing parameter: `request`');
}
if (!client) {
throw new oauth2Server.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 oauth2Server.InvalidRequestError('Missing parameter: `apple_token`');
}
let data;
try {
data = await verifyToken({
token,
audience: this.appIds
});
} catch (err) {
console.error(err);
throw new oauth2Server.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);
}
}
module.exports = AppleGrantType;
//# sourceMappingURL=oauth2-server-grant-type-apple.js.map