const request = require("request"); const OAuth2Strategy = require("passport-oauth2").Strategy; OAuth2Strategy.prototype.userProfile = function(accessToken: string, done: (err: Error, profile?: any) => void) { request('https://api.scoolcode.com/accounts/me?access_token=' + accessToken, (error: Error, response: any, body: any) => { if(error || (response && response.statusCode !== 200)) done(new Error("Forbidden")); else { const o = JSON.parse(body); o.accessToken = accessToken; done(null, o) } }) }; function getCRMToken(accessToken: string): Promise { return new Promise((resolve, reject) => { request('https://api.scoolcode.com/accounts/me/crm-token?access_token=' + accessToken, (error: Error, response: any, body: any) => { if(error || (response && response.statusCode !== 200)) { reject(new Error("Forbidden: failed to get CRM token")) } else { const o = JSON.parse(body); resolve(o.crmToken) } }) }) } export interface ScoolcodeProfile { id: string, username: string, crmUserId: string, email: string, name: { first: string, last: string }, fullName: string, kind: { teacher: boolean, student: boolean, leadTeacher: boolean, contributor: boolean, schoolCoordinator: boolean, parent: boolean, administrator: boolean, developer: boolean, mixer: boolean, beta: boolean, xmas: boolean }, displayName: string, school: string, group: string, storage: { size: number, quota: number }, parent: string, assetGallery: string, blockGallery: string, enabled: boolean, deleted: boolean } export class ScoolcodeStrategy { constructor( { clientID, clientSecret, callbackURL, requestCRMToken, passReqToCallback }: { clientID: string, clientSecret: string, callbackURL: string, requestCRMToken?: boolean, passReqToCallback?: boolean }, handler: ( token: { scoolcode: string, crm?: string }, profile: ScoolcodeProfile, callback: (err: Error|null, profile?: any) => void, req?: any) => void) { let internalHandler; if(passReqToCallback) { internalHandler = async (req: any, accessToken: string, refreshToken: string, profile: any, cb: (err: Error | null, profile?: any) => void) => { try { if (profile && profile.username) { handler( { scoolcode: accessToken, crm: requestCRMToken ? await getCRMToken(accessToken) : undefined }, profile, cb, req ) } else { cb(new Error("Forbidden: failed to fetch profile.")) } } catch (e) { cb(e) } } } else { internalHandler = async (accessToken: string, refreshToken: string, profile: any, cb: (err: Error | null, profile?: any) => void) => { try { if (profile && profile.username) { handler( { scoolcode: accessToken, crm: requestCRMToken ? await getCRMToken(accessToken) : undefined }, profile, cb ) } else { cb(new Error("Forbidden: failed to fetch profile.")) } } catch (e) { cb(e) } } } const strategy = new OAuth2Strategy({ authorizationURL: 'https://api.scoolcode.com/oauth/authorize', tokenURL: 'https://api.scoolcode.com/oauth/token', clientID, clientSecret, callbackURL, passReqToCallback }, internalHandler ); strategy.name = "scoolcode"; return strategy } } export const Strategy = ScoolcodeStrategy;