mirror of
https://github.com/PretendoNetwork/account.git
synced 2026-09-14 22:37:22 -05:00
Added travis.yml, and ESLint rules
This commit is contained in:
39
.eslintrc.json
Normal file
39
.eslintrc.json
Normal file
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"env": {
|
||||
"node": true,
|
||||
"commonjs": true,
|
||||
"es6": true
|
||||
},
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 2017
|
||||
},
|
||||
"extends": "eslint:recommended",
|
||||
"rules": {
|
||||
"no-console": "off",
|
||||
"prefer-const": "error",
|
||||
"no-var": "error",
|
||||
"one-var": [
|
||||
"error",
|
||||
"never"
|
||||
],
|
||||
"indent": [
|
||||
"error",
|
||||
"tab",
|
||||
{
|
||||
"SwitchCase": 1
|
||||
}
|
||||
],
|
||||
"linebreak-style": [
|
||||
"error",
|
||||
"windows"
|
||||
],
|
||||
"quotes": [
|
||||
"error",
|
||||
"single"
|
||||
],
|
||||
"semi": [
|
||||
"error",
|
||||
"always"
|
||||
]
|
||||
}
|
||||
}
|
||||
10
.travis.yml
Normal file
10
.travis.yml
Normal file
@@ -0,0 +1,10 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- "7"
|
||||
- "8"
|
||||
- "9"
|
||||
|
||||
sudo: false
|
||||
|
||||
script:
|
||||
- "npm run lint"
|
||||
56
constants.js
56
constants.js
@@ -1,29 +1,29 @@
|
||||
module.exports = {
|
||||
URL_ENDPOINTS: {
|
||||
mii: 'http://mii-secure.account.riiu.net/'
|
||||
},
|
||||
LATEST_SYSTEM_VERSION: '0230',
|
||||
MINIMUN_SYSTEM_VERSION: '0209',
|
||||
PID_SORT_LIST: '0123456789',
|
||||
VALID_CLIENT_ID_SECRET_PAIRS: {
|
||||
// 'Key' is the client ID, 'Value' is the client secret
|
||||
'a2efa818a34fa16b8afbc8a74eba3eda': 'c91cdb5658bd4954ade78533a339cf9a', // Possibly WiiU exclusive?
|
||||
'daf6227853bcbdce3d75baee8332b': '3eff548eac636e2bf45bb7b375e7b6b0', // Possibly 3DS exclusive?
|
||||
'ea25c66c26b403376b4c5ed94ab9cdea': 'd137be62cb6a2b831cad8c013b92fb55', // Possibly 3DS exclusive?
|
||||
},
|
||||
REGEX: {
|
||||
HEADER_FORMATS: {
|
||||
DEVICE_ID: /^\d{10}$/g,
|
||||
REGION: /^\d+$/g,
|
||||
SYSTEM_VERSION: /^\d+$/g,
|
||||
}
|
||||
},
|
||||
REGION_CODES_NUM: {
|
||||
'4': 'EUR',
|
||||
'2': 'US'
|
||||
},
|
||||
REGION_CODES_STR: {
|
||||
EUR: 4,
|
||||
US: 2
|
||||
},
|
||||
}
|
||||
URL_ENDPOINTS: {
|
||||
mii: 'http://mii-secure.account.riiu.net/'
|
||||
},
|
||||
LATEST_SYSTEM_VERSION: '0230',
|
||||
MINIMUN_SYSTEM_VERSION: '0209',
|
||||
PID_SORT_LIST: '0123456789',
|
||||
VALID_CLIENT_ID_SECRET_PAIRS: {
|
||||
// 'Key' is the client ID, 'Value' is the client secret
|
||||
'a2efa818a34fa16b8afbc8a74eba3eda': 'c91cdb5658bd4954ade78533a339cf9a', // Possibly WiiU exclusive?
|
||||
'daf6227853bcbdce3d75baee8332b': '3eff548eac636e2bf45bb7b375e7b6b0', // Possibly 3DS exclusive?
|
||||
'ea25c66c26b403376b4c5ed94ab9cdea': 'd137be62cb6a2b831cad8c013b92fb55', // Possibly 3DS exclusive?
|
||||
},
|
||||
REGEX: {
|
||||
HEADER_FORMATS: {
|
||||
DEVICE_ID: /^\d{10}$/g,
|
||||
REGION: /^\d+$/g,
|
||||
SYSTEM_VERSION: /^\d+$/g,
|
||||
}
|
||||
},
|
||||
REGION_CODES_NUM: {
|
||||
'4': 'EUR',
|
||||
'2': 'US'
|
||||
},
|
||||
REGION_CODES_STR: {
|
||||
EUR: 4,
|
||||
US: 2
|
||||
},
|
||||
};
|
||||
24
db.js
24
db.js
@@ -1,23 +1,23 @@
|
||||
const mongoist = require('mongoist');
|
||||
const config = require('./config.json');
|
||||
const user_database_collection_name = 'users';
|
||||
const database = config.mongo.database
|
||||
const hostname = config.mongo.hostname
|
||||
const port = config.mongo.port
|
||||
const auth = config.mongo.authentication
|
||||
const database = config.mongo.database;
|
||||
const hostname = config.mongo.hostname;
|
||||
const port = config.mongo.port;
|
||||
const auth = config.mongo.authentication;
|
||||
|
||||
let connection_string = '';
|
||||
|
||||
if(config.mongo.use_authentication) {
|
||||
connection_string = `mongodb://${auth.username}:${auth.password}@${hostname}:${port}/${database}?authSource=${auth.authentication_database}`
|
||||
}else {
|
||||
connection_string = `mongodb://${hostname}:${port}/${database}`
|
||||
if (config.mongo.use_authentication) {
|
||||
connection_string = `mongodb://${auth.username}:${auth.password}@${hostname}:${port}/${database}?authSource=${auth.authentication_database}`;
|
||||
} else {
|
||||
connection_string = `mongodb://${hostname}:${port}/${database}`;
|
||||
}
|
||||
|
||||
user_database = mongoist(connection_string);
|
||||
user_collection = user_database.collection(user_database_collection_name);
|
||||
const user_database = mongoist(connection_string);
|
||||
const user_collection = user_database.collection(user_database_collection_name);
|
||||
|
||||
module.exports = {
|
||||
user_database: user_database,
|
||||
user_collection: user_collection
|
||||
user_database: user_database,
|
||||
user_collection: user_collection
|
||||
};
|
||||
|
||||
78
debugger.js
78
debugger.js
@@ -1,59 +1,59 @@
|
||||
let ms = require('ms'),
|
||||
colors = require('colors');
|
||||
const ms = require('ms');
|
||||
require('colors');
|
||||
|
||||
class Debugger {
|
||||
constructor(title) {
|
||||
this.title = title;
|
||||
this.previous_time = new Date();
|
||||
}
|
||||
constructor(title) {
|
||||
this.title = title;
|
||||
this.previous_time = new Date();
|
||||
}
|
||||
|
||||
success(input) {
|
||||
let current_time = new Date(),
|
||||
time_taken = ms(ms(current_time - this.previous_time)),
|
||||
suffix = '';
|
||||
success(input) {
|
||||
const current_time = new Date();
|
||||
const time_taken = ms(ms(current_time - this.previous_time));
|
||||
let suffix = '';
|
||||
|
||||
if (time_taken > 0) {
|
||||
suffix = '-> '.green + (time_taken + 'ms').magenta;
|
||||
}
|
||||
if (time_taken > 0) {
|
||||
suffix = '-> '.green + (time_taken + 'ms').magenta;
|
||||
}
|
||||
|
||||
let message = (this.title + ':').green.bold + ' ' + input.yellow.bold + ' ' + suffix.bold;
|
||||
const message = (this.title + ':').green.bold + ' ' + input.yellow.bold + ' ' + suffix.bold;
|
||||
|
||||
console.log(message);
|
||||
console.log(message);
|
||||
|
||||
this.previous_time = current_time;
|
||||
}
|
||||
this.previous_time = current_time;
|
||||
}
|
||||
|
||||
error(input) {
|
||||
let current_time = new Date(),
|
||||
time_taken = ms(ms(current_time - this.previous_time)),
|
||||
suffix = '';
|
||||
error(input) {
|
||||
const current_time = new Date();
|
||||
const time_taken = ms(ms(current_time - this.previous_time));
|
||||
let suffix = '';
|
||||
|
||||
if (time_taken > 0) {
|
||||
suffix = '-> '.green + (time_taken + 'ms').magenta;
|
||||
}
|
||||
if (time_taken > 0) {
|
||||
suffix = '-> '.green + (time_taken + 'ms').magenta;
|
||||
}
|
||||
|
||||
let message = (this.title + ':').red.bold + ' ' + input.yellow.bold + ' ' + suffix.bold;
|
||||
const message = (this.title + ':').red.bold + ' ' + input.yellow.bold + ' ' + suffix.bold;
|
||||
|
||||
console.log(message);
|
||||
console.log(message);
|
||||
|
||||
this.previous_time = current_time;
|
||||
}
|
||||
this.previous_time = current_time;
|
||||
}
|
||||
|
||||
log(input) {
|
||||
let current_time = new Date(),
|
||||
time_taken = ms(ms(current_time - this.previous_time)),
|
||||
suffix = '';
|
||||
log(input) {
|
||||
const current_time = new Date();
|
||||
const time_taken = ms(ms(current_time - this.previous_time));
|
||||
let suffix = '';
|
||||
|
||||
if (time_taken > 0) {
|
||||
suffix = '-> '.green + (time_taken + 'ms').magenta;
|
||||
}
|
||||
if (time_taken > 0) {
|
||||
suffix = '-> '.green + (time_taken + 'ms').magenta;
|
||||
}
|
||||
|
||||
let message = (this.title + ':').cyan.bold + ' ' + input.yellow.bold + ' ' + suffix.bold;
|
||||
const message = (this.title + ':').cyan.bold + ' ' + input.yellow.bold + ' ' + suffix.bold;
|
||||
|
||||
console.log(message);
|
||||
console.log(message);
|
||||
|
||||
this.previous_time = current_time;
|
||||
}
|
||||
this.previous_time = current_time;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Debugger;
|
||||
360
helpers.js
360
helpers.js
@@ -6,247 +6,245 @@ const constants = require('./constants');
|
||||
const database = require('./db');
|
||||
|
||||
async function generatePID() {
|
||||
// Quick, dirty fix for PIDs
|
||||
const pid = Math.floor(Math.random() * (4294967295 - 1000000000) + 1000000000);
|
||||
let does_pid_inuse = await database.user_collection.findOne({
|
||||
pid: pid
|
||||
});
|
||||
// Quick, dirty fix for PIDs
|
||||
const pid = Math.floor(Math.random() * (4294967295 - 1000000000) + 1000000000);
|
||||
const does_pid_inuse = await database.user_collection.findOne({
|
||||
pid: pid
|
||||
});
|
||||
|
||||
if (does_pid_inuse) {
|
||||
return await generatePID();
|
||||
}
|
||||
if (does_pid_inuse) {
|
||||
return await generatePID();
|
||||
}
|
||||
|
||||
return pid;
|
||||
return pid;
|
||||
}
|
||||
|
||||
function generateRandID(length = 10) {
|
||||
let id = '';
|
||||
let id = '';
|
||||
|
||||
for (var i=0;i<length;i++) {
|
||||
id += constants.PID_SORT_LIST.charAt(Math.floor(Math.random() * constants.PID_SORT_LIST.length));
|
||||
}
|
||||
for (let i=0;i<length;i++) {
|
||||
id += constants.PID_SORT_LIST.charAt(Math.floor(Math.random() * constants.PID_SORT_LIST.length));
|
||||
}
|
||||
|
||||
return id;
|
||||
return id;
|
||||
}
|
||||
|
||||
async function generateEmailToken() {
|
||||
const token = randtoken.generate(32);
|
||||
let user = await database.user_collection.findOne({
|
||||
'sensitive.email_confirms.token': token
|
||||
});
|
||||
|
||||
if (user) {
|
||||
return await generateEmailToken();
|
||||
}
|
||||
const token = randtoken.generate(32);
|
||||
const user = await database.user_collection.findOne({
|
||||
'sensitive.email_confirms.token': token
|
||||
});
|
||||
|
||||
if (user) {
|
||||
return await generateEmailToken();
|
||||
}
|
||||
|
||||
return token;
|
||||
return token;
|
||||
}
|
||||
|
||||
async function generateEmailCode() {
|
||||
const code = generateRandID(6);
|
||||
const code = generateRandID(6);
|
||||
const user = await database.user_collection.findOne({
|
||||
'sensitive.email_confirms.code': code
|
||||
});
|
||||
|
||||
if (user) {
|
||||
return await generateEmailCode();
|
||||
}
|
||||
|
||||
let user = await database.user_collection.findOne({
|
||||
'sensitive.email_confirms.code': code
|
||||
});
|
||||
|
||||
if (user) {
|
||||
return await generateEmailCode();
|
||||
}
|
||||
|
||||
return code;
|
||||
return code;
|
||||
}
|
||||
|
||||
function generateNintendoHashedPWrd(password, pid) {
|
||||
let buff1 = pythonStruct.pack('<I', pid);
|
||||
let buff2 = Buffer.from(password).toString('ascii');
|
||||
const buff1 = pythonStruct.pack('<I', pid);
|
||||
const buff2 = Buffer.from(password).toString('ascii');
|
||||
|
||||
let unpacked = new Buffer(bufferToHex(buff1) + '\x02eCF' + buff2, 'ascii'),
|
||||
hashed = crypto.createHash('sha256').update(unpacked).digest().toString('hex');
|
||||
const unpacked = new Buffer(bufferToHex(buff1) + '\x02eCF' + buff2, 'ascii');
|
||||
const hashed = crypto.createHash('sha256').update(unpacked).digest().toString('hex');
|
||||
|
||||
return hashed;
|
||||
return hashed;
|
||||
}
|
||||
|
||||
function bufferToHex(buff) {
|
||||
let result = '',
|
||||
arr = buff.toString('hex').match(/.{1,2}/g);
|
||||
for (var i=0;i<arr.length;i++) {
|
||||
let char = arr[i],
|
||||
char_code = char.charCodeAt();
|
||||
result += String.fromCharCode(parseInt(char, 16));
|
||||
}
|
||||
result.replace(/\\/g, '\');
|
||||
return result;
|
||||
let result = '';
|
||||
const arr = buff.toString('hex').match(/.{1,2}/g);
|
||||
for (let i=0;i<arr.length;i++) {
|
||||
const char = arr[i];
|
||||
result += String.fromCharCode(parseInt(char, 16));
|
||||
}
|
||||
result.replace(/\\/g, '\');
|
||||
return result;
|
||||
}
|
||||
|
||||
async function doesUserExist(username) {
|
||||
let user = await database.user_collection.findOne({
|
||||
username: username.toLowerCase()
|
||||
});
|
||||
|
||||
if (user) {
|
||||
return true;
|
||||
}
|
||||
const user = await database.user_collection.findOne({
|
||||
username: username.toLowerCase()
|
||||
});
|
||||
|
||||
if (user) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
async function getUser(token) {
|
||||
let user = await database.user_collection.findOne({
|
||||
'sensitive.tokens.access.token': token
|
||||
});
|
||||
|
||||
if (user) {
|
||||
return user;
|
||||
}
|
||||
const user = await database.user_collection.findOne({
|
||||
'sensitive.tokens.access.token': token
|
||||
});
|
||||
|
||||
if (user) {
|
||||
return user;
|
||||
}
|
||||
|
||||
return null;
|
||||
return null;
|
||||
}
|
||||
|
||||
async function getUserBasic(token, email) {
|
||||
let unpacked_token = Buffer.from(token, 'base64').toString().split(' ');
|
||||
let user = await database.user_collection.findOne({
|
||||
user_id_flat: unpacked_token[0].toLowerCase()
|
||||
});
|
||||
const unpacked_token = Buffer.from(token, 'base64').toString().split(' ');
|
||||
const user = await database.user_collection.findOne({
|
||||
user_id_flat: unpacked_token[0].toLowerCase()
|
||||
});
|
||||
|
||||
if (!user) {
|
||||
return null;
|
||||
}
|
||||
if (!user) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (user.email.address.address !== email) {
|
||||
return null;
|
||||
}
|
||||
if (user.email.address.address !== email) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let hashed_password = generateNintendoHashedPWrd(unpacked_token[1], user.pid);
|
||||
const hashed_password = generateNintendoHashedPWrd(unpacked_token[1], user.pid);
|
||||
|
||||
|
||||
if (!bcrypt.compareSync(hashed_password, user.sensitive.password)) {
|
||||
return null;
|
||||
}
|
||||
if (!bcrypt.compareSync(hashed_password, user.sensitive.password)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return user;
|
||||
return user;
|
||||
}
|
||||
|
||||
function generateAccessToken(payload) {
|
||||
let token = crypto.createHash('md5').update(JSON.stringify(payload)).digest('hex');
|
||||
const token = crypto.createHash('md5').update(JSON.stringify(payload)).digest('hex');
|
||||
|
||||
return token;
|
||||
return token;
|
||||
}
|
||||
|
||||
function generateRefreshToken(payload) {
|
||||
let token = crypto.createHash('md5').update(JSON.stringify(payload)).digest('hex');
|
||||
const token = crypto.createHash('md5').update(JSON.stringify(payload)).digest('hex');
|
||||
|
||||
return token;
|
||||
return token;
|
||||
}
|
||||
|
||||
function mapUser(user) {
|
||||
let accounts = [];
|
||||
let device_attributes = [];
|
||||
const accounts = [];
|
||||
const device_attributes = [];
|
||||
|
||||
user.accounts.forEach(account => {
|
||||
account = account.account
|
||||
let attributes = [];
|
||||
user.accounts.forEach(account => {
|
||||
account = account.account;
|
||||
const attributes = [];
|
||||
|
||||
account.attributes.forEach(attribute => {
|
||||
attribute = attribute.attribute;
|
||||
attributes.push({
|
||||
attribute: {
|
||||
id: attribute.id,
|
||||
name: attribute.name,
|
||||
updated_by: attribute.updated_by,
|
||||
value: attribute.value,
|
||||
}
|
||||
});
|
||||
});
|
||||
account.attributes.forEach(attribute => {
|
||||
attribute = attribute.attribute;
|
||||
attributes.push({
|
||||
attribute: {
|
||||
id: attribute.id,
|
||||
name: attribute.name,
|
||||
updated_by: attribute.updated_by,
|
||||
value: attribute.value,
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
accounts.push({
|
||||
account: {
|
||||
attributes: attributes,
|
||||
domain: account.domain,
|
||||
type: account.type,
|
||||
username: account.username
|
||||
}
|
||||
})
|
||||
});
|
||||
accounts.push({
|
||||
account: {
|
||||
attributes: attributes,
|
||||
domain: account.domain,
|
||||
type: account.type,
|
||||
username: account.username
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
user.device_attributes.device_attribute.forEach(device_attribute => {
|
||||
let attribute = {
|
||||
name: device_attribute.name,
|
||||
value: device_attribute.value
|
||||
};
|
||||
user.device_attributes.device_attribute.forEach(device_attribute => {
|
||||
const attribute = {
|
||||
name: device_attribute.name,
|
||||
value: device_attribute.value
|
||||
};
|
||||
|
||||
if (device_attribute.created_date) {
|
||||
attribute.created_date = device_attribute.created_date;
|
||||
}
|
||||
if (device_attribute.created_date) {
|
||||
attribute.created_date = device_attribute.created_date;
|
||||
}
|
||||
|
||||
device_attributes.push({
|
||||
device_attribute: attribute
|
||||
});
|
||||
});
|
||||
device_attributes.push({
|
||||
device_attribute: attribute
|
||||
});
|
||||
});
|
||||
|
||||
let person = {
|
||||
person: {
|
||||
accounts: accounts,
|
||||
active_flag: user.active_flag,
|
||||
birth_date: user.birth_date,
|
||||
country: user.country,
|
||||
create_date: user.create_date,
|
||||
device_attributes: device_attributes,
|
||||
gender: user.gender,
|
||||
language: user.language,
|
||||
updated: user.updated,
|
||||
marketing_flag: user.marketing_flag,
|
||||
off_device_flag: user.off_device_flag,
|
||||
pid: user.pid,
|
||||
email: {
|
||||
address: user.email.address.address,
|
||||
id: user.email.id,
|
||||
parent: user.email.address.parent,
|
||||
primary: user.email.address.primary,
|
||||
reachable: user.email.reachable,
|
||||
type: user.email.address.type,
|
||||
updated_by: user.email.updated_by,
|
||||
validated: user.email.address.validated,
|
||||
validated_date: user.updated
|
||||
},
|
||||
mii: {
|
||||
status: user.mii.status,
|
||||
data: user.mii.data.replace('\r\n', ''),
|
||||
id: user.mii.id,
|
||||
mii_hash: user.mii.mii_hash,
|
||||
mii_images: [
|
||||
{
|
||||
mii_image: {
|
||||
cached_url: user.mii.mii_images[0].cached_url,
|
||||
id: user.mii.mii_images[0].id,
|
||||
url: user.mii.mii_images[0].url,
|
||||
type: user.mii.mii_images[0].type
|
||||
}
|
||||
}
|
||||
],
|
||||
name: user.mii.name,
|
||||
primary: user.mii.primary
|
||||
},
|
||||
region: user.region,
|
||||
tz_name: user.tz_name,
|
||||
user_id: user.user_id,
|
||||
utc_offset: user.utc_offset
|
||||
}
|
||||
}
|
||||
const person = {
|
||||
person: {
|
||||
accounts: accounts,
|
||||
active_flag: user.active_flag,
|
||||
birth_date: user.birth_date,
|
||||
country: user.country,
|
||||
create_date: user.create_date,
|
||||
device_attributes: device_attributes,
|
||||
gender: user.gender,
|
||||
language: user.language,
|
||||
updated: user.updated,
|
||||
marketing_flag: user.marketing_flag,
|
||||
off_device_flag: user.off_device_flag,
|
||||
pid: user.pid,
|
||||
email: {
|
||||
address: user.email.address.address,
|
||||
id: user.email.id,
|
||||
parent: user.email.address.parent,
|
||||
primary: user.email.address.primary,
|
||||
reachable: user.email.reachable,
|
||||
type: user.email.address.type,
|
||||
updated_by: user.email.updated_by,
|
||||
validated: user.email.address.validated,
|
||||
validated_date: user.updated
|
||||
},
|
||||
mii: {
|
||||
status: user.mii.status,
|
||||
data: user.mii.data.replace('\r\n', ''),
|
||||
id: user.mii.id,
|
||||
mii_hash: user.mii.mii_hash,
|
||||
mii_images: [
|
||||
{
|
||||
mii_image: {
|
||||
cached_url: user.mii.mii_images[0].cached_url,
|
||||
id: user.mii.mii_images[0].id,
|
||||
url: user.mii.mii_images[0].url,
|
||||
type: user.mii.mii_images[0].type
|
||||
}
|
||||
}
|
||||
],
|
||||
name: user.mii.name,
|
||||
primary: user.mii.primary
|
||||
},
|
||||
region: user.region,
|
||||
tz_name: user.tz_name,
|
||||
user_id: user.user_id,
|
||||
utc_offset: user.utc_offset
|
||||
}
|
||||
};
|
||||
|
||||
return person;
|
||||
return person;
|
||||
}
|
||||
|
||||
|
||||
module.exports = {
|
||||
generatePID: generatePID,
|
||||
generateRandID: generateRandID,
|
||||
generateNintendoHashedPWrd: generateNintendoHashedPWrd,
|
||||
doesUserExist: doesUserExist,
|
||||
generateAccessToken: generateAccessToken,
|
||||
generateRefreshToken: generateRefreshToken,
|
||||
getUser: getUser,
|
||||
getUserBasic: getUserBasic,
|
||||
mapUser: mapUser,
|
||||
generateEmailToken: generateEmailToken,
|
||||
generateEmailCode: generateEmailCode,
|
||||
}
|
||||
generatePID: generatePID,
|
||||
generateRandID: generateRandID,
|
||||
generateNintendoHashedPWrd: generateNintendoHashedPWrd,
|
||||
doesUserExist: doesUserExist,
|
||||
generateAccessToken: generateAccessToken,
|
||||
generateRefreshToken: generateRefreshToken,
|
||||
getUser: getUser,
|
||||
getUserBasic: getUserBasic,
|
||||
mapUser: mapUser,
|
||||
generateEmailToken: generateEmailToken,
|
||||
generateEmailCode: generateEmailCode,
|
||||
};
|
||||
40
mailer.js
40
mailer.js
@@ -2,11 +2,11 @@ const nodemailer = require('nodemailer');
|
||||
const config = require('./config.json');
|
||||
|
||||
const transporter = nodemailer.createTransport({
|
||||
service: 'gmail',
|
||||
auth: {
|
||||
user: config.email.address,
|
||||
pass: config.email.password
|
||||
}
|
||||
service: 'gmail',
|
||||
auth: {
|
||||
user: config.email.address,
|
||||
pass: config.email.password
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
@@ -16,22 +16,22 @@ const transporter = nodemailer.createTransport({
|
||||
* @param {String} message The body of the email
|
||||
*/
|
||||
function send(email, subject = 'No email subject provided', message = 'No email body provided') {
|
||||
let options = {
|
||||
from: config.email.address,
|
||||
to: email,
|
||||
subject: subject,
|
||||
html: message
|
||||
}
|
||||
const options = {
|
||||
from: config.email.address,
|
||||
to: email,
|
||||
subject: subject,
|
||||
html: message
|
||||
};
|
||||
|
||||
transporter.sendMail(options, (error, info) => {
|
||||
if (error) {
|
||||
console.log(error);
|
||||
} else {
|
||||
console.log(info);
|
||||
}
|
||||
});
|
||||
transporter.sendMail(options, (error, info) => {
|
||||
if (error) {
|
||||
console.log(error);
|
||||
} else {
|
||||
console.log(info);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
send: send
|
||||
}
|
||||
send: send
|
||||
};
|
||||
|
||||
935
package-lock.json
generated
935
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -4,6 +4,7 @@
|
||||
"description": "",
|
||||
"main": "server.js",
|
||||
"scripts": {
|
||||
"lint": "./node_modules/.bin/eslint .",
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"start": "NODE_ENV=production node server.js",
|
||||
"start:dev": "NODE_ENV=development node server.js"
|
||||
@@ -14,6 +15,7 @@
|
||||
"bcryptjs": "^2.4.3",
|
||||
"cli-table": "^0.3.1",
|
||||
"colors": "^1.1.2",
|
||||
"eslint": "^4.18.2",
|
||||
"express": "^4.16.2",
|
||||
"express-rate-limit": "^2.11.0",
|
||||
"express-subdomain": "^1.0.5",
|
||||
|
||||
@@ -10,61 +10,43 @@ route_debugger.success('Loading \'account\' API routes');
|
||||
* Description: Verifies a user email via token
|
||||
*/
|
||||
routes.get('/email-confirmation', async (request, response) => {
|
||||
let _GET = request.query;
|
||||
const _GET = request.query;
|
||||
|
||||
console.log(_GET)
|
||||
if (!_GET.token) {
|
||||
return response.send('ERROR: Invalid token');
|
||||
}
|
||||
|
||||
if (!_GET.token) {
|
||||
return response.send('ERROR: Invalid token');
|
||||
}
|
||||
const user = await database.user_collection.findOne({
|
||||
'sensitive.email_confirms.token': _GET.token
|
||||
});
|
||||
|
||||
console.log(2)
|
||||
if (!user) {
|
||||
return response.send('ERROR: Invalid token');
|
||||
}
|
||||
|
||||
let user = await database.user_collection.findOne({
|
||||
'sensitive.email_confirms.token': _GET.token
|
||||
});
|
||||
user.email.reachable = 'Y';
|
||||
user.email.validated = 'Y';
|
||||
|
||||
console.log(3)
|
||||
await database.user_collection.update({
|
||||
pid: user.pid
|
||||
}, {
|
||||
$set: {
|
||||
email: user.email
|
||||
}
|
||||
});
|
||||
|
||||
if (!user) {
|
||||
return response.send('ERROR: Invalid token');
|
||||
}
|
||||
user.sensitive.email_confirms.token = null;
|
||||
user.sensitive.email_confirms.code = null;
|
||||
|
||||
console.log(4)
|
||||
await database.user_collection.update({
|
||||
pid: user.pid
|
||||
}, {
|
||||
$set: {
|
||||
sensitive: user.sensitive
|
||||
}
|
||||
});
|
||||
|
||||
user.email.reachable = 'Y';
|
||||
user.email.validated = 'Y';
|
||||
|
||||
console.log(5)
|
||||
|
||||
await database.user_collection.update({
|
||||
pid: user.pid
|
||||
}, {
|
||||
$set: {
|
||||
email: user.email
|
||||
}
|
||||
});
|
||||
|
||||
console.log(6)
|
||||
|
||||
user.sensitive.email_confirms.token = null;
|
||||
user.sensitive.email_confirms.code = null;
|
||||
|
||||
console.log(7)
|
||||
|
||||
await database.user_collection.update({
|
||||
pid: user.pid
|
||||
}, {
|
||||
$set: {
|
||||
sensitive: user.sensitive
|
||||
}
|
||||
});
|
||||
|
||||
console.log(8)
|
||||
|
||||
response.send('It has been confirmed that you can receive e-mails from Pretendo. The confirmation process is now complete.');
|
||||
|
||||
console.log(9)
|
||||
response.send('It has been confirmed that you can receive e-mails from Pretendo. The confirmation process is now complete.');
|
||||
});
|
||||
|
||||
module.exports = routes;
|
||||
@@ -13,97 +13,97 @@ route_debugger.success('Loading \'admin\' API routes');
|
||||
* Description: Maps given input to expected output
|
||||
*/
|
||||
routes.all('/mapped_ids', async (request, response) => {
|
||||
response.set('Content-Type', 'text/xml');
|
||||
response.set('Server', 'Nintendo 3DS (http)');
|
||||
response.set('X-Nintendo-Date', new Date().getTime());
|
||||
response.set('Content-Type', 'text/xml');
|
||||
response.set('Server', 'Nintendo 3DS (http)');
|
||||
response.set('X-Nintendo-Date', new Date().getTime());
|
||||
|
||||
let headers = request.headers,
|
||||
_GET = request.query;
|
||||
const headers = request.headers;
|
||||
const _GET = request.query;
|
||||
|
||||
if (
|
||||
!headers['x-nintendo-client-id'] ||
|
||||
!headers['x-nintendo-client-secret'] ||
|
||||
!constants.VALID_CLIENT_ID_SECRET_PAIRS[headers['x-nintendo-client-id']] ||
|
||||
headers['x-nintendo-client-secret'] !== constants.VALID_CLIENT_ID_SECRET_PAIRS[headers['x-nintendo-client-id']]
|
||||
) {
|
||||
let error = {
|
||||
errors: {
|
||||
error: {
|
||||
cause: 'client_id',
|
||||
code: '0004',
|
||||
message: 'API application invalid or incorrect application credentials'
|
||||
}
|
||||
}
|
||||
}
|
||||
if (
|
||||
!headers['x-nintendo-client-id'] ||
|
||||
!headers['x-nintendo-client-secret'] ||
|
||||
!constants.VALID_CLIENT_ID_SECRET_PAIRS[headers['x-nintendo-client-id']] ||
|
||||
headers['x-nintendo-client-secret'] !== constants.VALID_CLIENT_ID_SECRET_PAIRS[headers['x-nintendo-client-id']]
|
||||
) {
|
||||
const error = {
|
||||
errors: {
|
||||
error: {
|
||||
cause: 'client_id',
|
||||
code: '0004',
|
||||
message: 'API application invalid or incorrect application credentials'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return response.send(json2xml(error));
|
||||
}
|
||||
return response.send(json2xml(error));
|
||||
}
|
||||
|
||||
if (
|
||||
!_GET.output_type ||
|
||||
!_GET.input_type ||
|
||||
!_GET.input ||
|
||||
_GET.input.trim() == ''
|
||||
) {
|
||||
let error = {
|
||||
errors: {
|
||||
error: {
|
||||
cause: 'Bad Request',
|
||||
code: '1600',
|
||||
message: 'Unable to process request'
|
||||
}
|
||||
}
|
||||
}
|
||||
if (
|
||||
!_GET.output_type ||
|
||||
!_GET.input_type ||
|
||||
!_GET.input ||
|
||||
_GET.input.trim() == ''
|
||||
) {
|
||||
const error = {
|
||||
errors: {
|
||||
error: {
|
||||
cause: 'Bad Request',
|
||||
code: '1600',
|
||||
message: 'Unable to process request'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return response.send(json2xml(error));
|
||||
}
|
||||
return response.send(json2xml(error));
|
||||
}
|
||||
|
||||
let output = {
|
||||
mapped_ids: [
|
||||
]
|
||||
}
|
||||
const output = {
|
||||
mapped_ids: [
|
||||
]
|
||||
};
|
||||
|
||||
_GET.input = _GET.input.split(',');
|
||||
_GET.input = _GET.input.split(',');
|
||||
|
||||
switch (true) {
|
||||
case (_GET.input_type === 'user_id' && _GET.output_type === 'pid'):
|
||||
await _GET.input.asyncForEach(async user_id => {
|
||||
let user = await database.user_collection.findOne({
|
||||
user_id_flat: user_id.toLowerCase(),
|
||||
}),
|
||||
out_id = null;
|
||||
switch (true) {
|
||||
case (_GET.input_type === 'user_id' && _GET.output_type === 'pid'):
|
||||
await _GET.input.asyncForEach(async user_id => {
|
||||
const user = await database.user_collection.findOne({
|
||||
user_id_flat: user_id.toLowerCase(),
|
||||
});
|
||||
let out_id = null;
|
||||
|
||||
if (user) {
|
||||
out_id = user.pid;
|
||||
}
|
||||
if (user) {
|
||||
out_id = user.pid;
|
||||
}
|
||||
|
||||
output.mapped_ids.push({
|
||||
mapped_id: {
|
||||
in_id: user_id,
|
||||
out_id: out_id
|
||||
}
|
||||
});
|
||||
});
|
||||
break;
|
||||
default:
|
||||
_GET.input.forEach(input => {
|
||||
output.mapped_ids.push({
|
||||
mapped_id: {
|
||||
in_id: input,
|
||||
out_id: null
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
output.mapped_ids.push({
|
||||
mapped_id: {
|
||||
in_id: user_id,
|
||||
out_id: out_id
|
||||
}
|
||||
});
|
||||
});
|
||||
break;
|
||||
default:
|
||||
_GET.input.forEach(input => {
|
||||
output.mapped_ids.push({
|
||||
mapped_id: {
|
||||
in_id: input,
|
||||
out_id: null
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
response.send(json2xml(output));
|
||||
})
|
||||
response.send(json2xml(output));
|
||||
});
|
||||
|
||||
module.exports = routes;
|
||||
|
||||
|
||||
Array.prototype.asyncForEach = async function (cb) {
|
||||
for (let i=0;i<this.length;i++) {
|
||||
await cb(this[i], i, this);
|
||||
}
|
||||
}
|
||||
for (let i=0;i<this.length;i++) {
|
||||
await cb(this[i], i, this);
|
||||
}
|
||||
};
|
||||
@@ -14,47 +14,47 @@ route_debugger.success('Loading \'content\' API routes');
|
||||
* Description: Sends the client an XML list of timezones
|
||||
*/
|
||||
routes.get('/time_zones/:region/:language', (request, response) => {
|
||||
response.set('Content-Type', 'text/xml');
|
||||
response.set('Server', 'Nintendo 3DS (http)');
|
||||
response.set('X-Nintendo-Date', new Date().getTime());
|
||||
response.set('Content-Type', 'text/xml');
|
||||
response.set('Server', 'Nintendo 3DS (http)');
|
||||
response.set('X-Nintendo-Date', new Date().getTime());
|
||||
|
||||
let headers = request.headers,
|
||||
region = request.params.region,
|
||||
language = request.params.language;
|
||||
const headers = request.headers;
|
||||
const region = request.params.region;
|
||||
const language = request.params.language;
|
||||
|
||||
if (
|
||||
!headers['x-nintendo-client-id'] ||
|
||||
!headers['x-nintendo-client-secret'] ||
|
||||
!constants.VALID_CLIENT_ID_SECRET_PAIRS[headers['x-nintendo-client-id']] ||
|
||||
headers['x-nintendo-client-secret'] !== constants.VALID_CLIENT_ID_SECRET_PAIRS[headers['x-nintendo-client-id']]
|
||||
) {
|
||||
let error = {
|
||||
errors: {
|
||||
error: {
|
||||
cause: 'client_id',
|
||||
code: '0004',
|
||||
message: 'API application invalid or incorrect application credentials'
|
||||
}
|
||||
}
|
||||
}
|
||||
if (
|
||||
!headers['x-nintendo-client-id'] ||
|
||||
!headers['x-nintendo-client-secret'] ||
|
||||
!constants.VALID_CLIENT_ID_SECRET_PAIRS[headers['x-nintendo-client-id']] ||
|
||||
headers['x-nintendo-client-secret'] !== constants.VALID_CLIENT_ID_SECRET_PAIRS[headers['x-nintendo-client-id']]
|
||||
) {
|
||||
const error = {
|
||||
errors: {
|
||||
error: {
|
||||
cause: 'client_id',
|
||||
code: '0004',
|
||||
message: 'API application invalid or incorrect application credentials'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return response.send(json2xml(error));
|
||||
}
|
||||
return response.send(json2xml(error));
|
||||
}
|
||||
|
||||
if (!fs.pathExistsSync(path.join(__dirname, 'storage', 'timezones', region, language + '.xml'))) {
|
||||
let error = {
|
||||
errors: {
|
||||
error: {
|
||||
code: '0000',
|
||||
message: 'Unknown error'
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!fs.pathExistsSync(path.join(__dirname, 'storage', 'timezones', region, language + '.xml'))) {
|
||||
const error = {
|
||||
errors: {
|
||||
error: {
|
||||
code: '0000',
|
||||
message: 'Unknown error'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return response.send(json2xml(error));
|
||||
}
|
||||
return response.send(json2xml(error));
|
||||
}
|
||||
|
||||
response.sendFile(path.join(__dirname, 'storage', 'timezones', region, language + '.xml'));
|
||||
response.sendFile(path.join(__dirname, 'storage', 'timezones', region, language + '.xml'));
|
||||
});
|
||||
|
||||
|
||||
@@ -64,73 +64,72 @@ routes.get('/time_zones/:region/:language', (request, response) => {
|
||||
* Description: Sends the client requested agreement
|
||||
*/
|
||||
routes.get('/agreements/:type/:region/:version', (request, response) => {
|
||||
response.set('Content-Type', 'text/xml');
|
||||
response.set('Server', 'Nintendo 3DS (http)');
|
||||
response.set('X-Nintendo-Date', new Date().getTime());
|
||||
response.set('Content-Type', 'text/xml');
|
||||
response.set('Server', 'Nintendo 3DS (http)');
|
||||
response.set('X-Nintendo-Date', new Date().getTime());
|
||||
|
||||
let headers = request.headers,
|
||||
type = request.params.type,
|
||||
region = request.params.region,
|
||||
version = request.params.version,
|
||||
_GET = request.query;
|
||||
const headers = request.headers;
|
||||
const type = request.params.type;
|
||||
const region = request.params.region;
|
||||
const version = request.params.version;
|
||||
|
||||
// for some reason, the 3ds won't work if you have this.
|
||||
// TODO: fix this for the 3ds
|
||||
if (
|
||||
!headers['x-nintendo-client-id'] ||
|
||||
!headers['x-nintendo-client-secret'] ||
|
||||
!constants.VALID_CLIENT_ID_SECRET_PAIRS[headers['x-nintendo-client-id']] ||
|
||||
headers['x-nintendo-client-secret'] !== constants.VALID_CLIENT_ID_SECRET_PAIRS[headers['x-nintendo-client-id']]
|
||||
) {
|
||||
let error = {
|
||||
errors: {
|
||||
error: {
|
||||
cause: 'client_id',
|
||||
code: '0004',
|
||||
message: 'API application invalid or incorrect application credentials'
|
||||
}
|
||||
}
|
||||
}
|
||||
// for some reason, the 3ds won't work if you have this.
|
||||
// TODO: fix this for the 3ds
|
||||
if (
|
||||
!headers['x-nintendo-client-id'] ||
|
||||
!headers['x-nintendo-client-secret'] ||
|
||||
!constants.VALID_CLIENT_ID_SECRET_PAIRS[headers['x-nintendo-client-id']] ||
|
||||
headers['x-nintendo-client-secret'] !== constants.VALID_CLIENT_ID_SECRET_PAIRS[headers['x-nintendo-client-id']]
|
||||
) {
|
||||
const error = {
|
||||
errors: {
|
||||
error: {
|
||||
cause: 'client_id',
|
||||
code: '0004',
|
||||
message: 'API application invalid or incorrect application credentials'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return response.send(json2xml(error));
|
||||
}
|
||||
return response.send(json2xml(error));
|
||||
}
|
||||
|
||||
if (!fs.pathExistsSync(path.join(__dirname, 'storage', 'agreements', type, region, version + '.xml'))) {
|
||||
let error = {
|
||||
errors: {
|
||||
error: {
|
||||
code: '1101',
|
||||
message: 'No stored agreement found for this country: ' + region + ' type: ' + type + ' and version: ' + version
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!fs.pathExistsSync(path.join(__dirname, 'storage', 'agreements', type, region, version + '.xml'))) {
|
||||
const error = {
|
||||
errors: {
|
||||
error: {
|
||||
code: '1101',
|
||||
message: 'No stored agreement found for this country: ' + region + ' type: ' + type + ' and version: ' + version
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return response.send(json2xml(error));
|
||||
}
|
||||
return response.send(json2xml(error));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
// ALSO NEED TO FIGURE OUT WHEN TO THROW ERROR 1102:
|
||||
let error = {
|
||||
errors: {
|
||||
error: {
|
||||
code: '1102',
|
||||
message: 'No privacy policy found for this country ' + region + ' version ' + version
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
// ALSO NEED TO FIGURE OUT WHEN TO THROW ERROR 1102:
|
||||
let error = {
|
||||
errors: {
|
||||
error: {
|
||||
code: '1102',
|
||||
message: 'No privacy policy found for this country ' + region + ' version ' + version
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return response.send(json2xml(error));
|
||||
return response.send(json2xml(error));
|
||||
|
||||
// SEEMS TO BE RELATED TO THE `X-Nintendo-Region` HEADER.
|
||||
// SETTING `X-Nintendo-Region` TO 4 (and `:region` is `US`) WHEN `:type` IS `Nintendo-Network-EULA` THROWS ERROR 1102
|
||||
*/
|
||||
// SEEMS TO BE RELATED TO THE `X-Nintendo-Region` HEADER.
|
||||
// SETTING `X-Nintendo-Region` TO 4 (and `:region` is `US`) WHEN `:type` IS `Nintendo-Network-EULA` THROWS ERROR 1102
|
||||
*/
|
||||
|
||||
response.sendFile(path.join(__dirname, 'storage', 'agreements', type, region, version + '.xml'));
|
||||
response.sendFile(path.join(__dirname, 'storage', 'agreements', type, region, version + '.xml'));
|
||||
});
|
||||
|
||||
module.exports = routes;
|
||||
|
||||
Array.prototype.contains = function(el) { // polyfill custom Array method
|
||||
return this.indexOf(el) > -1;
|
||||
}
|
||||
return this.indexOf(el) > -1;
|
||||
};
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
const routes = require('express').Router();
|
||||
const path = require('path');
|
||||
const fs = require('fs-extra');
|
||||
const json2xml = require('json2xml');
|
||||
const debug = require('../../debugger');
|
||||
const constants = require('../../constants');
|
||||
@@ -14,32 +12,32 @@ route_debugger.success('Loading \'devices\' API routes');
|
||||
* Description: Unknown use
|
||||
*/
|
||||
routes.get('/@current/status', (request, response) => {
|
||||
response.set('Content-Type', 'text/xml');
|
||||
response.set('Server', 'Nintendo 3DS (http)');
|
||||
response.set('X-Nintendo-Date', new Date().getTime());
|
||||
response.set('Content-Type', 'text/xml');
|
||||
response.set('Server', 'Nintendo 3DS (http)');
|
||||
response.set('X-Nintendo-Date', new Date().getTime());
|
||||
|
||||
let headers = request.headers;
|
||||
const headers = request.headers;
|
||||
|
||||
if (
|
||||
!headers['x-nintendo-client-id'] ||
|
||||
!headers['x-nintendo-client-secret'] ||
|
||||
!constants.VALID_CLIENT_ID_SECRET_PAIRS[headers['x-nintendo-client-id']] ||
|
||||
headers['x-nintendo-client-secret'] !== constants.VALID_CLIENT_ID_SECRET_PAIRS[headers['x-nintendo-client-id']]
|
||||
) {
|
||||
let error = {
|
||||
errors: {
|
||||
error: {
|
||||
cause: 'client_id',
|
||||
code: '0004',
|
||||
message: 'API application invalid or incorrect application credentials'
|
||||
}
|
||||
}
|
||||
}
|
||||
if (
|
||||
!headers['x-nintendo-client-id'] ||
|
||||
!headers['x-nintendo-client-secret'] ||
|
||||
!constants.VALID_CLIENT_ID_SECRET_PAIRS[headers['x-nintendo-client-id']] ||
|
||||
headers['x-nintendo-client-secret'] !== constants.VALID_CLIENT_ID_SECRET_PAIRS[headers['x-nintendo-client-id']]
|
||||
) {
|
||||
const error = {
|
||||
errors: {
|
||||
error: {
|
||||
cause: 'client_id',
|
||||
code: '0004',
|
||||
message: 'API application invalid or incorrect application credentials'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return response.send(json2xml(error));
|
||||
}
|
||||
return response.send(json2xml(error));
|
||||
}
|
||||
|
||||
return response.send(json2xml({device: null}));
|
||||
return response.send(json2xml({device: null}));
|
||||
});
|
||||
|
||||
module.exports = routes;
|
||||
@@ -11,184 +11,183 @@ route_debugger.log('Loading \'oauth20\' API routes');
|
||||
/**
|
||||
* [GET]
|
||||
* Replacement for: https://account.nintendo.net/v1/api/oauth20/access_token/generate
|
||||
* Description: Unknown use
|
||||
* Description: Generates user access tokens
|
||||
*/
|
||||
routes.all('/access_token/generate', async (request, response) => {
|
||||
let POST = request.body;
|
||||
|
||||
if (
|
||||
!POST ||
|
||||
!POST.grant_type ||
|
||||
!['password', 'refresh_token'].includes(POST.grant_type)
|
||||
) {
|
||||
let error = {
|
||||
errors: {
|
||||
error: {
|
||||
cause: 'grant_type',
|
||||
code: '0004',
|
||||
message: 'Invalid Grant Type'
|
||||
}
|
||||
}
|
||||
}
|
||||
const POST = request.body;
|
||||
|
||||
return response.send(json2xml(error));
|
||||
}
|
||||
if (
|
||||
!POST ||
|
||||
!POST.grant_type ||
|
||||
!['password', 'refresh_token'].includes(POST.grant_type)
|
||||
) {
|
||||
const error = {
|
||||
errors: {
|
||||
error: {
|
||||
cause: 'grant_type',
|
||||
code: '0004',
|
||||
message: 'Invalid Grant Type'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (POST.grant_type == 'password') {
|
||||
if (!POST.user_id || !POST.password) {
|
||||
let error = {
|
||||
errors: {
|
||||
error: {
|
||||
cause: 'grant_type',
|
||||
code: '0004',
|
||||
message: 'Invalid Grant Type'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return response.send(json2xml(error));
|
||||
}
|
||||
return response.send(json2xml(error));
|
||||
}
|
||||
|
||||
let user = await database.user_collection.findOne({
|
||||
user_id: POST.user_id
|
||||
});
|
||||
if (POST.grant_type == 'password') {
|
||||
if (!POST.user_id || !POST.password) {
|
||||
const error = {
|
||||
errors: {
|
||||
error: {
|
||||
cause: 'grant_type',
|
||||
code: '0004',
|
||||
message: 'Invalid Grant Type'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return response.send(json2xml(error));
|
||||
}
|
||||
|
||||
if (!user) {
|
||||
let error = {
|
||||
errors: {
|
||||
error: {
|
||||
code: '0113',
|
||||
message: 'Unauthorized device'
|
||||
}
|
||||
}
|
||||
}
|
||||
const user = await database.user_collection.findOne({
|
||||
user_id: POST.user_id
|
||||
});
|
||||
|
||||
return response.send(json2xml(error));
|
||||
}
|
||||
if (!user) {
|
||||
const error = {
|
||||
errors: {
|
||||
error: {
|
||||
code: '0113',
|
||||
message: 'Unauthorized device'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (!POST.password_type || POST.password_type.toLowerCase() !== 'hash') {
|
||||
POST.password = helpers.generateNintendoHashedPWrd(POST.password, user.pid);
|
||||
}
|
||||
return response.send(json2xml(error));
|
||||
}
|
||||
|
||||
if (!bcrypt.compareSync(POST.password, user.sensitive.password)) {
|
||||
let error = {
|
||||
errors: {
|
||||
error: {
|
||||
code: '0106',
|
||||
message: 'Invalid account ID or password.'
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!POST.password_type || POST.password_type.toLowerCase() !== 'hash') {
|
||||
POST.password = helpers.generateNintendoHashedPWrd(POST.password, user.pid);
|
||||
}
|
||||
|
||||
return response.send(json2xml(error));
|
||||
}
|
||||
|
||||
let access_token = helpers.generateAccessToken({
|
||||
pid: user.pid,
|
||||
token_salt: helpers.generateRandID(100)
|
||||
});
|
||||
//let access_token = user.pid
|
||||
if (!bcrypt.compareSync(POST.password, user.sensitive.password)) {
|
||||
const error = {
|
||||
errors: {
|
||||
error: {
|
||||
code: '0106',
|
||||
message: 'Invalid account ID or password.'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let refresh_token = helpers.generateRefreshToken({
|
||||
pid: user.pid,
|
||||
token_salt: helpers.generateRandID(100)
|
||||
});
|
||||
return response.send(json2xml(error));
|
||||
}
|
||||
|
||||
const access_token = helpers.generateAccessToken({
|
||||
pid: user.pid,
|
||||
token_salt: helpers.generateRandID(100)
|
||||
});
|
||||
|
||||
user.sensitive.tokens.refresh = refresh_token;
|
||||
user.sensitive.tokens.access.token = access_token;
|
||||
user.sensitive.tokens.access.ttl = Math.floor((Date.now() / 1000) + 3600);
|
||||
const refresh_token = helpers.generateRefreshToken({
|
||||
pid: user.pid,
|
||||
token_salt: helpers.generateRandID(100)
|
||||
});
|
||||
|
||||
await database.user_collection.update({
|
||||
pid: user.pid
|
||||
}, {
|
||||
$set: {
|
||||
sensitive: user.sensitive
|
||||
}
|
||||
});
|
||||
|
||||
response.send(json2xml({
|
||||
OAuth20: {
|
||||
access_token: {
|
||||
token: access_token,
|
||||
refresh_token: refresh_token,
|
||||
expires_in: 3600,
|
||||
}
|
||||
}
|
||||
}));
|
||||
} else if (POST.grant_type == 'refresh_token') {
|
||||
if (!POST.refresh_token) {
|
||||
let error = {
|
||||
errors: {
|
||||
error: {
|
||||
cause: 'refresh_token',
|
||||
code: '0106',
|
||||
message: 'Invalid Refresh Token'
|
||||
}
|
||||
}
|
||||
}
|
||||
user.sensitive.tokens.refresh = refresh_token;
|
||||
user.sensitive.tokens.access.token = access_token;
|
||||
user.sensitive.tokens.access.ttl = Math.floor((Date.now() / 1000) + 3600);
|
||||
|
||||
return response.send(json2xml(error));
|
||||
}
|
||||
await database.user_collection.update({
|
||||
pid: user.pid
|
||||
}, {
|
||||
$set: {
|
||||
sensitive: user.sensitive
|
||||
}
|
||||
});
|
||||
|
||||
response.send(json2xml({
|
||||
OAuth20: {
|
||||
access_token: {
|
||||
token: access_token,
|
||||
refresh_token: refresh_token,
|
||||
expires_in: 3600,
|
||||
}
|
||||
}
|
||||
}));
|
||||
} else if (POST.grant_type == 'refresh_token') {
|
||||
if (!POST.refresh_token) {
|
||||
const error = {
|
||||
errors: {
|
||||
error: {
|
||||
cause: 'refresh_token',
|
||||
code: '0106',
|
||||
message: 'Invalid Refresh Token'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let user = database.user_collection.findOne({
|
||||
sensitive: {
|
||||
tokens: {
|
||||
refresh: POST.refresh_token
|
||||
}
|
||||
}
|
||||
});
|
||||
return response.send(json2xml(error));
|
||||
}
|
||||
|
||||
if (!user || user.sensitive.tokens.refresh !== POST.refresh_token) {
|
||||
let error = {
|
||||
errors: {
|
||||
error: {
|
||||
cause: 'refresh_token',
|
||||
code: '0106',
|
||||
message: 'Invalid Refresh Token'
|
||||
}
|
||||
}
|
||||
}
|
||||
const user = database.user_collection.findOne({
|
||||
sensitive: {
|
||||
tokens: {
|
||||
refresh: POST.refresh_token
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return response.send(json2xml(error));
|
||||
}
|
||||
if (!user || user.sensitive.tokens.refresh !== POST.refresh_token) {
|
||||
const error = {
|
||||
errors: {
|
||||
error: {
|
||||
cause: 'refresh_token',
|
||||
code: '0106',
|
||||
message: 'Invalid Refresh Token'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let access_token = helpers.generateAccessToken({
|
||||
pid: user.pid,
|
||||
token_salt: helpers.generateRandID(100)
|
||||
});
|
||||
return response.send(json2xml(error));
|
||||
}
|
||||
|
||||
let refresh_token = helpers.generateRefreshToken({
|
||||
pid: user.pid,
|
||||
token_salt: helpers.generateRandID(100)
|
||||
});
|
||||
const access_token = helpers.generateAccessToken({
|
||||
pid: user.pid,
|
||||
token_salt: helpers.generateRandID(100)
|
||||
});
|
||||
|
||||
user.sensitive.tokens.refresh = refresh_token;
|
||||
user.sensitive.tokens.access.token = access_token;
|
||||
user.sensitive.tokens.access.ttl = Math.floor((Date.now() / 1000) + 3600);
|
||||
const refresh_token = helpers.generateRefreshToken({
|
||||
pid: user.pid,
|
||||
token_salt: helpers.generateRandID(100)
|
||||
});
|
||||
|
||||
await database.user_collection.update({
|
||||
sensitive: {
|
||||
tokens: {
|
||||
refresh: POST.refresh_token
|
||||
}
|
||||
}
|
||||
}, {
|
||||
$set: {
|
||||
sensitive: user.sensitive
|
||||
}
|
||||
});
|
||||
user.sensitive.tokens.refresh = refresh_token;
|
||||
user.sensitive.tokens.access.token = access_token;
|
||||
user.sensitive.tokens.access.ttl = Math.floor((Date.now() / 1000) + 3600);
|
||||
|
||||
|
||||
response.send(json2xml({
|
||||
OAuth20: {
|
||||
access_token: {
|
||||
token: access_token,
|
||||
refresh_token: refresh_token,
|
||||
expires_in: 3600,
|
||||
}
|
||||
}
|
||||
}));
|
||||
}
|
||||
await database.user_collection.update({
|
||||
sensitive: {
|
||||
tokens: {
|
||||
refresh: POST.refresh_token
|
||||
}
|
||||
}
|
||||
}, {
|
||||
$set: {
|
||||
sensitive: user.sensitive
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
response.send(json2xml({
|
||||
OAuth20: {
|
||||
access_token: {
|
||||
token: access_token,
|
||||
refresh_token: refresh_token,
|
||||
expires_in: 3600,
|
||||
}
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,4 @@
|
||||
const routes = require('express').Router();
|
||||
const RateLimit = require('express-rate-limit');
|
||||
const json2xml = require('json2xml');
|
||||
const debug = require('../../debugger');
|
||||
const route_debugger = new debug('Provider Route'.green);
|
||||
@@ -7,7 +6,7 @@ const route_debugger = new debug('Provider Route'.green);
|
||||
route_debugger.log('Loading \'provider\' API routes');
|
||||
|
||||
//The game ips and ports are stored here. When the game tries to access its specific server, it will be given the respecive ip and port.
|
||||
let gamePort = {
|
||||
const gamePort = {
|
||||
friends: {
|
||||
ip: '10.0.0.225',
|
||||
port: '1300'
|
||||
@@ -16,7 +15,7 @@ let gamePort = {
|
||||
ip: '10.0.0.225',
|
||||
port: '1301'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* [GET]
|
||||
@@ -24,15 +23,15 @@ let gamePort = {
|
||||
* Description: Gets service token
|
||||
*/
|
||||
routes.get('/service_token/@me', async (request, response) => {
|
||||
response.set('Content-Type', 'text/xml');
|
||||
response.set('Server', 'Nintendo 3DS (http)');
|
||||
response.set('Content-Type', 'text/xml');
|
||||
response.set('Server', 'Nintendo 3DS (http)');
|
||||
response.set('X-Nintendo-Date', new Date().getTime());
|
||||
|
||||
let token = {
|
||||
const token = {
|
||||
service_token: {
|
||||
token: 'pretendo_test'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return response.send(json2xml(token));
|
||||
});
|
||||
@@ -43,8 +42,8 @@ routes.get('/service_token/@me', async (request, response) => {
|
||||
* Description: Gets nex token
|
||||
*/
|
||||
routes.get('/nex_token/@me', async (request, response) => {
|
||||
response.set('Content-Type', 'text/xml');
|
||||
response.set('Server', 'Nintendo 3DS (http)');
|
||||
response.set('Content-Type', 'text/xml');
|
||||
response.set('Server', 'Nintendo 3DS (http)');
|
||||
response.set('X-Nintendo-Date', new Date().getTime());
|
||||
|
||||
let ip = null;
|
||||
@@ -67,21 +66,21 @@ routes.get('/nex_token/@me', async (request, response) => {
|
||||
break;
|
||||
}
|
||||
|
||||
if(ip==null || port==null){
|
||||
let error = {
|
||||
errors: {
|
||||
error: {
|
||||
cause: 'No game server',
|
||||
code: '9999',
|
||||
message: 'No server found'
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ip==null || port==null){
|
||||
const error = {
|
||||
errors: {
|
||||
error: {
|
||||
cause: 'No game server',
|
||||
code: '9999',
|
||||
message: 'No server found'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return response.send(json2xml(error));
|
||||
}
|
||||
|
||||
let token = {
|
||||
const token = {
|
||||
nex_token: {
|
||||
host: ip,
|
||||
nex_password: 'pretendo',
|
||||
@@ -89,7 +88,8 @@ routes.get('/nex_token/@me', async (request, response) => {
|
||||
port: port,
|
||||
token: 'pretendo_test'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return response.send(json2xml(token));
|
||||
});
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ route_debugger.log('Loading \'root/misc\' API routes');
|
||||
* Description: tests the validity of this server by returning a predefined message
|
||||
*/
|
||||
routes.get('/isthisworking', async (req, res) => {
|
||||
return res.send('{"server": "account.nintendo.net"}')
|
||||
return res.send('{"server": "account.nintendo.net"}');
|
||||
});
|
||||
|
||||
module.exports = routes
|
||||
module.exports = routes;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
const dns = require('dns');
|
||||
const routes = require('express').Router();
|
||||
const helpers = require('../../helpers');
|
||||
const constants = require('../../constants');
|
||||
const database = require('../../db');
|
||||
const json2xml = require('json2xml');
|
||||
@@ -15,82 +14,82 @@ route_debugger.log('Loading \'support\' API routes');
|
||||
* Description: Validates an email by attempting to ping it's mail server
|
||||
*/
|
||||
routes.post('/validate/email', async (request, response) => {
|
||||
response.set('Content-Type', 'text/xml');
|
||||
response.set('Server', 'Nintendo 3DS (http)');
|
||||
response.set('X-Nintendo-Date', new Date().getTime());
|
||||
response.set('Content-Type', 'text/xml');
|
||||
response.set('Server', 'Nintendo 3DS (http)');
|
||||
response.set('X-Nintendo-Date', new Date().getTime());
|
||||
|
||||
let POST = request.body,
|
||||
headers = request.headers
|
||||
email = POST.email;
|
||||
const POST = request.body;
|
||||
const headers = request.headers;
|
||||
const email = POST.email;
|
||||
|
||||
if (
|
||||
!headers['x-nintendo-client-id'] ||
|
||||
!headers['x-nintendo-client-secret'] ||
|
||||
!constants.VALID_CLIENT_ID_SECRET_PAIRS[headers['x-nintendo-client-id']] ||
|
||||
headers['x-nintendo-client-secret'] !== constants.VALID_CLIENT_ID_SECRET_PAIRS[headers['x-nintendo-client-id']]
|
||||
) {
|
||||
let error = {
|
||||
errors: {
|
||||
error: {
|
||||
cause: 'client_id',
|
||||
code: '0004',
|
||||
message: 'API application invalid or incorrect application credentials'
|
||||
}
|
||||
}
|
||||
}
|
||||
if (
|
||||
!headers['x-nintendo-client-id'] ||
|
||||
!headers['x-nintendo-client-secret'] ||
|
||||
!constants.VALID_CLIENT_ID_SECRET_PAIRS[headers['x-nintendo-client-id']] ||
|
||||
headers['x-nintendo-client-secret'] !== constants.VALID_CLIENT_ID_SECRET_PAIRS[headers['x-nintendo-client-id']]
|
||||
) {
|
||||
const error = {
|
||||
errors: {
|
||||
error: {
|
||||
cause: 'client_id',
|
||||
code: '0004',
|
||||
message: 'API application invalid or incorrect application credentials'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return response.send(json2xml(error));
|
||||
}
|
||||
return response.send(json2xml(error));
|
||||
}
|
||||
|
||||
if (
|
||||
!headers['content-type'] ||
|
||||
headers['content-type'].toLowerCase() !== 'application/x-www-form-urlencoded'
|
||||
) {
|
||||
let error = {
|
||||
errors: {
|
||||
error: {
|
||||
code: '2001',
|
||||
message: 'Internal server error'
|
||||
}
|
||||
}
|
||||
}
|
||||
if (
|
||||
!headers['content-type'] ||
|
||||
headers['content-type'].toLowerCase() !== 'application/x-www-form-urlencoded'
|
||||
) {
|
||||
const error = {
|
||||
errors: {
|
||||
error: {
|
||||
code: '2001',
|
||||
message: 'Internal server error'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return response.send(json2xml(error));
|
||||
}
|
||||
return response.send(json2xml(error));
|
||||
}
|
||||
|
||||
if (!email) {
|
||||
let error = {
|
||||
errors: {
|
||||
error: {
|
||||
cause: 'email',
|
||||
code: '0103',
|
||||
message: 'Email format is invalid'
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!email) {
|
||||
const error = {
|
||||
errors: {
|
||||
error: {
|
||||
cause: 'email',
|
||||
code: '0103',
|
||||
message: 'Email format is invalid'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return response.send(json2xml(error));
|
||||
}
|
||||
return response.send(json2xml(error));
|
||||
}
|
||||
|
||||
let domain = email.split('@')[1];
|
||||
const domain = email.split('@')[1];
|
||||
|
||||
dns.resolveMx(domain, (error, addr) => {
|
||||
if (error) {
|
||||
let error = {
|
||||
errors: {
|
||||
error: {
|
||||
code: '1126',
|
||||
message: 'The domain "' + domain + '" is not accessible.'
|
||||
}
|
||||
}
|
||||
}
|
||||
dns.resolveMx(domain, (error) => {
|
||||
if (error) {
|
||||
const error = {
|
||||
errors: {
|
||||
error: {
|
||||
code: '1126',
|
||||
message: 'The domain "' + domain + '" is not accessible.'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return response.send(json2xml(error));
|
||||
}
|
||||
return response.send(json2xml(error));
|
||||
}
|
||||
|
||||
response.status(200);
|
||||
response.end();
|
||||
});
|
||||
response.status(200);
|
||||
response.end();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -100,64 +99,65 @@ routes.post('/validate/email', async (request, response) => {
|
||||
* Description: Confirms an email
|
||||
*/
|
||||
routes.put('/email_confirmation/:pid/:code', async (request, response) => {
|
||||
response.set('Content-Type', 'text/xml');
|
||||
response.set('Server', 'Nintendo 3DS (http)');
|
||||
response.set('X-Nintendo-Date', new Date().getTime());
|
||||
response.set('Content-Type', 'text/xml');
|
||||
response.set('Server', 'Nintendo 3DS (http)');
|
||||
response.set('X-Nintendo-Date', new Date().getTime());
|
||||
|
||||
let user = await database.user_collection.findOne({
|
||||
pid: Number(request.params.pid)
|
||||
});
|
||||
const user = await database.user_collection.findOne({
|
||||
pid: Number(request.params.pid)
|
||||
});
|
||||
|
||||
if (!user) {
|
||||
let error = {
|
||||
errors: {
|
||||
error: {
|
||||
code: '0130',
|
||||
message: 'PID has not been registered yet'
|
||||
}
|
||||
}
|
||||
}
|
||||
return response.send(json2xml(error));
|
||||
}
|
||||
|
||||
if (user.sensitive.email_confirms.code !== request.params.code) {
|
||||
let error = {
|
||||
errors: {
|
||||
error: {
|
||||
code: '0116',
|
||||
message: 'Missing or invalid verification code'
|
||||
}
|
||||
}
|
||||
}
|
||||
const error = {
|
||||
errors: {
|
||||
error: {
|
||||
code: '0130',
|
||||
message: 'PID has not been registered yet'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return response.send(json2xml(error));
|
||||
}
|
||||
|
||||
user.email.reachable = 'Y';
|
||||
user.email.validated = 'Y';
|
||||
|
||||
if (user.sensitive.email_confirms.code !== request.params.code) {
|
||||
const error = {
|
||||
errors: {
|
||||
error: {
|
||||
code: '0116',
|
||||
message: 'Missing or invalid verification code'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
await database.user_collection.update({
|
||||
pid: user.pid
|
||||
}, {
|
||||
$set: {
|
||||
email: user.email
|
||||
}
|
||||
});
|
||||
return response.send(json2xml(error));
|
||||
}
|
||||
|
||||
user.email.reachable = 'Y';
|
||||
user.email.validated = 'Y';
|
||||
|
||||
user.sensitive.email_confirms.token = null;
|
||||
user.sensitive.email_confirms.code = null;
|
||||
await database.user_collection.update({
|
||||
pid: user.pid
|
||||
}, {
|
||||
$set: {
|
||||
email: user.email
|
||||
}
|
||||
});
|
||||
|
||||
await database.user_collection.update({
|
||||
pid: user.pid
|
||||
}, {
|
||||
$set: {
|
||||
sensitive: user.sensitive
|
||||
}
|
||||
});
|
||||
user.sensitive.email_confirms.token = null;
|
||||
user.sensitive.email_confirms.code = null;
|
||||
|
||||
response.send(json2xml({
|
||||
email: null
|
||||
}));
|
||||
await database.user_collection.update({
|
||||
pid: user.pid
|
||||
}, {
|
||||
$set: {
|
||||
sensitive: user.sensitive
|
||||
}
|
||||
});
|
||||
|
||||
response.send(json2xml({
|
||||
email: null
|
||||
}));
|
||||
|
||||
});
|
||||
|
||||
|
||||
131
server.js
131
server.js
@@ -1,31 +1,30 @@
|
||||
const path = require('path');
|
||||
const express = require('express');
|
||||
const subdomain = require('express-subdomain');
|
||||
const table = require('cli-table');
|
||||
const colors = require('colors');
|
||||
const morgan = require('morgan');
|
||||
const XMLMiddleware = require('./xml-middleware');
|
||||
const debug = require('./debugger');
|
||||
const config = require('./config.json')
|
||||
const config = require('./config.json');
|
||||
const app = express();
|
||||
const router = express.Router();
|
||||
const testing_env = process.env.NODE_ENV !== "production"
|
||||
const testing_env = process.env.NODE_ENV !== 'production';
|
||||
require('colors');
|
||||
|
||||
const server_debugger = new debug('Server');
|
||||
|
||||
server_debugger.log('Importing routes');
|
||||
// API routes
|
||||
const ROUTES = {
|
||||
ACCOUNT: require('./routes/account'),
|
||||
ADMIN: require('./routes/admin'),
|
||||
CONTENT: require('./routes/content'),
|
||||
DEVICES: require('./routes/devices'),
|
||||
OAUTH20: require('./routes/oauth20'),
|
||||
PEOPLE: require('./routes/people'),
|
||||
PROVIDER: require('./routes/provider'),
|
||||
SUPPORT: require('./routes/support'),
|
||||
ROOT: require('./routes/root')
|
||||
}
|
||||
ACCOUNT: require('./routes/account'),
|
||||
ADMIN: require('./routes/admin'),
|
||||
CONTENT: require('./routes/content'),
|
||||
DEVICES: require('./routes/devices'),
|
||||
OAUTH20: require('./routes/oauth20'),
|
||||
PEOPLE: require('./routes/people'),
|
||||
PROVIDER: require('./routes/provider'),
|
||||
SUPPORT: require('./routes/support'),
|
||||
ROOT: require('./routes/root')
|
||||
};
|
||||
|
||||
// START APPLICATION
|
||||
app.set('etag', false);
|
||||
@@ -36,76 +35,78 @@ app.use(morgan('dev'));
|
||||
router.use(express.json());
|
||||
router.use(XMLMiddleware());
|
||||
router.use(express.urlencoded({
|
||||
extended: true
|
||||
extended: true
|
||||
}));
|
||||
|
||||
server_debugger.log('Creating \'account\' subdomain');
|
||||
// Create subdomain
|
||||
if (testing_env === false) {
|
||||
app.use(subdomain('account', router));
|
||||
app.use(subdomain('account', router));
|
||||
} else {
|
||||
app.use(router)
|
||||
app.use(router);
|
||||
}
|
||||
|
||||
server_debugger.log('Applying imported routes');
|
||||
// Setup routes
|
||||
router.use('/account', ROUTES.ACCOUNT); // Account API routes (only used for email confirmation)
|
||||
router.use('/v1/api/admin', ROUTES.ADMIN); // Admin API routes
|
||||
router.use('/account', ROUTES.ACCOUNT); // Account API routes (only used for email confirmation)
|
||||
router.use('/v1/api/admin', ROUTES.ADMIN); // Admin API routes
|
||||
router.use('/v1/api/content', ROUTES.CONTENT); // Content API routes
|
||||
router.use('/v1/api/devices', ROUTES.DEVICES); // Device API routes
|
||||
router.use('/v1/api/oauth20', ROUTES.OAUTH20); // oAuth API routes
|
||||
router.use('/v1/api/people', ROUTES.PEOPLE); // People API routes
|
||||
router.use('/v1/api/people', ROUTES.PEOPLE); // People API routes
|
||||
router.use('/v1/api/provider', ROUTES.PROVIDER); // Provider API routes
|
||||
router.use('/v1/api/support', ROUTES.SUPPORT); // Support API routes
|
||||
router.use('/', ROUTES.ROOT); // Root/Misc routes
|
||||
router.use('/v1/api/support', ROUTES.SUPPORT); // Support API routes
|
||||
router.use('/', ROUTES.ROOT); // Root/Misc routes
|
||||
|
||||
function getRoutes(_router) {
|
||||
let routes, ret = [];
|
||||
_router.forEach(layer => {
|
||||
if (layer.name == 'router') {
|
||||
routes = layer;
|
||||
}
|
||||
});
|
||||
const ret = [];
|
||||
let routes;
|
||||
|
||||
let stack = routes.handle.stack;
|
||||
_router.forEach(layer => {
|
||||
if (layer.name == 'router') {
|
||||
routes = layer;
|
||||
}
|
||||
});
|
||||
|
||||
stack.forEach(layer => {
|
||||
if (layer.handle.stack) {
|
||||
let base = layer.regexp.toString()
|
||||
.replace('\\/?', '')
|
||||
.replace('(?=\\/|$)', '$')
|
||||
.match(/^\/\^((?:\\[.*+?^${}()|[\]\\\/]|[^.*+?^${}()|[\]\\\/])*)\$\//)[1]
|
||||
.replace(/\\(.)/g, '$1');
|
||||
const stack = routes.handle.stack;
|
||||
|
||||
layer.handle.stack.forEach(mini_layer => {
|
||||
ret.push({
|
||||
method: Object.keys(mini_layer.route.methods)[0].toUpperCase().replace('_', ''),
|
||||
path: base + mini_layer.route.path
|
||||
})
|
||||
})
|
||||
}
|
||||
});
|
||||
stack.forEach(layer => {
|
||||
if (layer.handle.stack) {
|
||||
const base = layer.regexp.toString()
|
||||
.replace('\\/?', '')
|
||||
.replace('(?=\\/|$)', '$')
|
||||
.match(/^\/\^((?:\\[.*+?^${}()|[\]\\/]|[^.*+?^${}()|[\]\\/])*)\$\//)[1]
|
||||
.replace(/\\(.)/g, '$1');
|
||||
|
||||
return ret;
|
||||
layer.handle.stack.forEach(mini_layer => {
|
||||
ret.push({
|
||||
method: Object.keys(mini_layer.route.methods)[0].toUpperCase().replace('_', ''),
|
||||
path: base + mini_layer.route.path
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
server_debugger.log('Creating 404 status handler');
|
||||
// 404 handler
|
||||
router.use((request, response) => {
|
||||
response.status(404);
|
||||
response.send();
|
||||
response.status(404);
|
||||
response.send();
|
||||
});
|
||||
|
||||
server_debugger.log('Creating non-404 status handler');
|
||||
// non-404 error handler
|
||||
router.use((error, request, response) => {
|
||||
let status = error.status || 500;
|
||||
response.status(status);
|
||||
response.json({
|
||||
app: 'api',
|
||||
status: status,
|
||||
error: error.message
|
||||
});
|
||||
const status = error.status || 500;
|
||||
response.status(status);
|
||||
response.json({
|
||||
app: 'api',
|
||||
status: status,
|
||||
error: error.message
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -113,19 +114,19 @@ router.use((error, request, response) => {
|
||||
server_debugger.log('Starting server');
|
||||
// Starts the server
|
||||
app.listen(config.http.port, () => {
|
||||
let route_table = new table({
|
||||
head: ["Method", "Path"]
|
||||
}),
|
||||
routes = getRoutes(app._router.stack);
|
||||
const route_table = new table({
|
||||
head: ['Method', 'Path']
|
||||
});
|
||||
const routes = getRoutes(app._router.stack);
|
||||
|
||||
routes.forEach(route => {
|
||||
let obj = {};
|
||||
obj[route.method] = route.path;
|
||||
routes.forEach(route => {
|
||||
const obj = {};
|
||||
obj[route.method] = route.path;
|
||||
|
||||
route_table.push(obj)
|
||||
});
|
||||
route_table.push(obj);
|
||||
});
|
||||
|
||||
console.log(route_table.toString());
|
||||
console.log(route_table.toString());
|
||||
|
||||
server_debugger.log('Started '.green + 'on port '.blue + new String(config.http.port).yellow);
|
||||
server_debugger.log('Started '.green + 'on port '.blue + new String(config.http.port).yellow);
|
||||
});
|
||||
|
||||
@@ -3,36 +3,36 @@ const XML = require('pixl-xml');
|
||||
module.exports = middleware;
|
||||
|
||||
function middleware() {
|
||||
return XMLMiddleware;
|
||||
return XMLMiddleware;
|
||||
|
||||
function XMLMiddleware(request, response, next) {
|
||||
if (request.method == 'POST' || request.method == 'PUT') {
|
||||
let headers = request.headers,
|
||||
body = '';
|
||||
|
||||
if (
|
||||
!headers['content-type'] ||
|
||||
headers['content-type'].toLowerCase() !== 'application/xml'
|
||||
) {
|
||||
return next();
|
||||
}
|
||||
function XMLMiddleware(request, response, next) {
|
||||
if (request.method == 'POST' || request.method == 'PUT') {
|
||||
const headers = request.headers;
|
||||
let body = '';
|
||||
|
||||
if (
|
||||
!headers['content-type'] ||
|
||||
headers['content-type'].toLowerCase() !== 'application/xml'
|
||||
) {
|
||||
return next();
|
||||
}
|
||||
|
||||
request.setEncoding('utf-8');
|
||||
request.on('data', (chunk) => {
|
||||
body += chunk;
|
||||
});
|
||||
request.setEncoding('utf-8');
|
||||
request.on('data', (chunk) => {
|
||||
body += chunk;
|
||||
});
|
||||
|
||||
request.on('end', () => {
|
||||
try {
|
||||
request.body = XML.parse(body);
|
||||
} catch (error) {
|
||||
return next();
|
||||
}
|
||||
request.on('end', () => {
|
||||
try {
|
||||
request.body = XML.parse(body);
|
||||
} catch (error) {
|
||||
return next();
|
||||
}
|
||||
|
||||
next();
|
||||
});
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
}
|
||||
next();
|
||||
});
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user