<commit_before>/*
 Copyright 2017 IBM Corp.
 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at
 http://www.apache.org/licenses/LICENSE-2.0
 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
 */
"use strict";
const log4js = require("log4js");
const request = require("request");
const Q = require("q");
const constants = require('../utils/constants');
const TokenUtil = require("../utils/token-util");
const ServiceUtil = require('../utils/service-util');
const PublicKeyUtil = require("../utils/public-key-util");
const acceptLanguage = require('accept-language');
const appIdSupportedLanguagesArray = require("../data/languagesCodesArray");
acceptLanguage.languages(appIdSupportedLanguagesArray);

const STRATEGY_NAME = "appid-webapp-strategy";
const logger = log4js.getLogger(STRATEGY_NAME);

function WebAppStrategy(options) {
	logger.debug("Initializing");
	options = options || {};
	this.name = WebAppStrategy.STRATEGY_NAME;
	this.serviceConfig = new ServiceUtil.loadConfig('WebAppStrategy', [
		constants.CLIENT_ID,
		constants.TENANT_ID,
		constants.SECRET,
		constants.OAUTH_SERVER_URL,
		constants.REDIRECT_URI
	], options);
	PublicKeyUtil.setPublicKeysEndpoint(this.serviceConfig.getOAuthServerUrl());
}

WebAppStrategy.STRATEGY_NAME = STRATEGY_NAME;
WebAppStrategy.DEFAULT_SCOPE = "appid_default";
WebAppStrategy.AUTH_CONTEXT = "APPID_AUTH_CONTEXT";
WebAppStrategy.SIGN_UP = "sign_up";
WebAppStrategy.CHANGE_PASSWORD = "<PASSWORD>";
WebAppStrategy.CHANGE_DETAILS = "change_details";
WebAppStrategy.FORGOT_PASSWORD = "<PASSWORD>";
WebAppStrategy.LANGUAGE = "language";
WebAppStrategy.STATE_PARAMETER = "STATE_PARAMETER";

const AUTHORIZATION_PATH = "/authorization";
const FORGOT_PASSWORD_PATH = "/cloud_directory/forgot_password";
const CHANGE_PASSWORD_PATH = "/cloud_directory/change_password";
const CHANGE_DETAILS_PATH = "/cloud_directory/change_details";
const GENERATE_CODE_PATH = "/cloud_directory/generate_code";
const TOKEN_PATH = "/token";
const USERNAME = "username";
const PASSWORD = "password";
const POST_METHOD = "POST";
const INVALID_GRANT = "invalid_grant";
const FORBIDDEN = "FORBIDDEN";
const CLOUD_DIRECTORY = "cloud_directory";
const LOCALE_PARAM_NAME = "language";

WebAppStrategy.logout = function (req) {
	delete req.session.returnTo;
	delete req.session[WebAppStrategy.AUTH_CONTEXT];
	delete req.session[WebAppStrategy.STATE_PARAMETER];
	req.logout();
};

WebAppStrategy.prototype.setPreferredLocale = function (req, language) {

	// Check that express-session is enabled
	if (!req.session) {
		logger.error("Can't find req.session. Ensure express-session middleware is in use. Default language will be used");
		return this.error(new Error("Can't find req.session"));
	}
	req.session[WebAppStrategy.LANGUAGE] = language;
};

WebAppStrategy.prototype.getPreferredLocale = function (req) {
	return (req.session && req.session[WebAppStrategy.LANGUAGE]) || this.serviceConfig.getPreferredLocale();
};

// .success(user, info) - call on auth success. user=object, info=object
// .fail(challenge, status) - call on auth failure. challenge=string, status=int
// .redirect(url, status) - call on redirect required. url=url, status=int
// .pass() - skip strategy processing
// .error(err) - error during strategy processing. err=Error obj

WebAppStrategy.prototype.authenticate = function (req, options) {
	options = options || {};

	if (options.successRedirect) {
		req.session.returnTo = options.successRedirect;
	}

	// Check that express-session is enabled
	if (!req.session) {
		logger.error("Can't find req.session. Ensure express-session middleware is in use");
		return this.error(new Error("Can't find req.session"));
	}
	// RoP flow
	if (req.method === POST_METHOD) {
		if (req.body && Object.prototype.hasOwnProperty.call(req.body, USERNAME) && Object.prototype.hasOwnProperty.call(req.body, PASSWORD)) {
			return handleRopFlow(options, req, this);
		}
	}
	if (options.show === WebAppStrategy.CHANGE_PASSWORD) {
		return handleChangePassword(req, options, this);
	}
	if (options.show === WebAppStrategy.CHANGE_DETAILS) {
		return handleChangeDetails(req, options, this);
	}
	if (options.show === WebAppStrategy.FORGOT_PASSWORD) {
		return handleForgotPassword(req, options, this);
	}
	if (req.query && req.query.error) {
		// Handle possible errors returned in callback
		logger.warn("Error returned in callback ::", req.query.error);
		return this.fail(req.query.error);
	} else if (req.query && req.query.code) {
		// Handle grant code in callback
		return handleCallback(req, options, this);
	} else if (req.query && req.query.flow && (req.query.flow === WebAppStrategy.SIGN_UP || req.query.flow === WebAppStrategy.FORGOT_PASSWORD)) {
		logger.debug("Finished " + req.query.flow + "flow");
		var url = req.session.returnTo || "/";
		delete req.session.returnTo;
		return this.redirect(url);
	} else {
		// Handle authorization request
		return handleAuthorization(req, options, this);
	}
};

WebAppStrategy.prototype.refreshTokens = function (req, refreshToken) {
	return refreshTokens(refreshToken, this).then(function (appIdAuthContext) {
		// Save authorization context to HTTP session
		req.session[WebAppStrategy.AUTH_CONTEXT] = appIdAuthContext;
	});<commit_msg>update return of error from callback<commit_after>/*
 Copyright 2017 IBM Corp.
 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at
 http://www.apache.org/licenses/LICENSE-2.0
 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
 */
"use strict";
const log4js = require("log4js");
const request = require("request");
const Q = require("q");
const constants = require('../utils/constants');
const TokenUtil = require("../utils/token-util");
const ServiceUtil = require('../utils/service-util');
const PublicKeyUtil = require("../utils/public-key-util");
const acceptLanguage = require('accept-language');
const appIdSupportedLanguagesArray = require("../data/languagesCodesArray");
acceptLanguage.languages(appIdSupportedLanguagesArray);

const STRATEGY_NAME = "appid-webapp-strategy";
const logger = log4js.getLogger(STRATEGY_NAME);

function WebAppStrategy(options) {
	logger.debug("Initializing");
	options = options || {};
	this.name = WebAppStrategy.STRATEGY_NAME;
	this.serviceConfig = new ServiceUtil.loadConfig('WebAppStrategy', [
		constants.CLIENT_ID,
		constants.TENANT_ID,
		constants.SECRET,
		constants.OAUTH_SERVER_URL,
		constants.REDIRECT_URI
	], options);
	PublicKeyUtil.setPublicKeysEndpoint(this.serviceConfig.getOAuthServerUrl());
}

WebAppStrategy.STRATEGY_NAME = STRATEGY_NAME;
WebAppStrategy.DEFAULT_SCOPE = "appid_default";
WebAppStrategy.AUTH_CONTEXT = "APPID_AUTH_CONTEXT";
WebAppStrategy.SIGN_UP = "sign_up";
WebAppStrategy.CHANGE_PASSWORD = "<PASSWORD>";
WebAppStrategy.CHANGE_DETAILS = "change_details";
WebAppStrategy.FORGOT_PASSWORD = "<PASSWORD>";
WebAppStrategy.LANGUAGE = "language";
WebAppStrategy.STATE_PARAMETER = "STATE_PARAMETER";

const AUTHORIZATION_PATH = "/authorization";
const FORGOT_PASSWORD_PATH = "/cloud_directory/forgot_password";
const CHANGE_PASSWORD_PATH = "/cloud_directory/change_password";
const CHANGE_DETAILS_PATH = "/cloud_directory/change_details";
const GENERATE_CODE_PATH = "/cloud_directory/generate_code";
const TOKEN_PATH = "/token";
const USERNAME = "username";
const PASSWORD = "password";
const POST_METHOD = "POST";
const INVALID_GRANT = "invalid_grant";
const FORBIDDEN = "FORBIDDEN";
const CLOUD_DIRECTORY = "cloud_directory";
const LOCALE_PARAM_NAME = "language";

WebAppStrategy.logout = function (req) {
	delete req.session.returnTo;
	delete req.session[WebAppStrategy.AUTH_CONTEXT];
	delete req.session[WebAppStrategy.STATE_PARAMETER];
	req.logout();
};

WebAppStrategy.prototype.setPreferredLocale = function (req, language) {

	// Check that express-session is enabled
	if (!req.session) {
		logger.error("Can't find req.session. Ensure express-session middleware is in use. Default language will be used");
		return this.error(new Error("Can't find req.session"));
	}
	req.session[WebAppStrategy.LANGUAGE] = language;
};

WebAppStrategy.prototype.getPreferredLocale = function (req) {
	return (req.session && req.session[WebAppStrategy.LANGUAGE]) || this.serviceConfig.getPreferredLocale();
};

// .success(user, info) - call on auth success. user=object, info=object
// .fail(challenge, status) - call on auth failure. challenge=string, status=int
// .redirect(url, status) - call on redirect required. url=url, status=int
// .pass() - skip strategy processing
// .error(err) - error during strategy processing. err=Error obj

WebAppStrategy.prototype.authenticate = function (req, options) {
	options = options || {};

	if (options.successRedirect) {
		req.session.returnTo = options.successRedirect;
	}

	// Check that express-session is enabled
	if (!req.session) {
		logger.error("Can't find req.session. Ensure express-session middleware is in use");
		return this.error(new Error("Can't find req.session"));
	}
	// RoP flow
	if (req.method === POST_METHOD) {
		if (req.body && Object.prototype.hasOwnProperty.call(req.body, USERNAME) && Object.prototype.hasOwnProperty.call(req.body, PASSWORD)) {
			return handleRopFlow(options, req, this);
		}
	}
	if (options.show === WebAppStrategy.CHANGE_PASSWORD) {
		return handleChangePassword(req, options, this);
	}
	if (options.show === WebAppStrategy.CHANGE_DETAILS) {
		return handleChangeDetails(req, options, this);
	}
	if (options.show === WebAppStrategy.FORGOT_PASSWORD) {
		return handleForgotPassword(req, options, this);
	}
	if (req.query && req.query.error_description) {
		// Handle possible errors returned in callback
		logger.warn("Error returned in callback ::", req.query.error_description);
		return this.fail(req.query.error_description);
	} else if (req.query && req.query.code) {
		// Handle grant code in callback
		return handleCallback(req, options, this);
	} else if (req.query && req.query.flow && (req.query.flow === WebAppStrategy.SIGN_UP || req.query.flow === WebAppStrategy.FORGOT_PASSWORD)) {
		logger.debug("Finished " + req.query.flow + "flow");
		var url = req.session.returnTo || "/";
		delete req.session.returnTo;
		return this.redirect(url);
	} else {
		// Handle authorization request
		return handleAuthorization(req, options, this);
	}
};

WebAppStrategy.prototype.refreshTokens = function (req, refreshToken) {
	return refreshTokens(refreshToken, this).then(function (appIdAuthContext) {
		// Save authorization context to HTTP session
		req.session[WebAppStrategy.AUTH_CONTEXT] = appIdAuthContext;
	});
{'fraction_non_alphanumeric': 0.12365447913886665, 'fraction_numerical': 0.0019571212525576016, 'mean_word_length': 5.446100917431193, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '502056', 'n_tokens_mistral': 3478, 'n_tokens_neox': 3401, 'n_words': 835}