Last active
August 19, 2022 11:18
-
-
Save malys/85e5a2276210bea3ebb770bc71d7289a to your computer and use it in GitHub Desktop.
[BBox] API router auto configuration #nodejs #api #router #bbox #configuration #bouygues #telecom
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// npm i fetch-cookie debug node-fetch chalk | |
// Remote configuration for BBox router (Bouygues telecom) | |
// set password in admin console (xxxxx) | |
// TODO waiting OpenAPI descriptor to generate client automatically | |
/**************** | |
* Please contribute supporting new methods including them in methods.js | |
* see https://api.bbox.fr/doc/apirouter/index.html | |
* or open chrome dev tools and see the network tab and export the request in fetch format | |
*****************/ | |
import { IP } from "./ip.js"; | |
import * as M from "./methods.js"; | |
import chalk from 'chalk'; | |
const log = console.log; | |
chalk.level = 1; | |
function displayStatus(text, status) { | |
log(chalk.gray.bold(text) + ' ' + (status ? chalk.green('OK') : chalk.red('KO'))) | |
} | |
// Authentication | |
displayStatus('Login', await M.init("xxxxx")) | |
// Mask | |
if (M.getMyBBox() !== 'https://192.168.0.254') { | |
displayStatus('Mask modified', await M.setNetworkMask('192.168.0.254')) | |
// Will reboot | |
log(chalk.red("BBox will reboot. Please run again remote configuration script")) | |
process.exit(1) | |
} | |
// IP/MAC | |
for (let i = 0; i < IP.length; i++) { | |
let target = IP[i] | |
displayStatus('IP/MAC for ' + target.hostname + ' modified', | |
await M.setIPMAC(target.device, | |
target.ipaddress, | |
target.macaddress, | |
target.hostname)) | |
} | |
// DHCP | |
displayStatus('DHCP modified', await M.setDHCP('192.168.0.60', '192.168.0.199')) | |
// DNS | |
displayStatus('DNS modified', await M.setDNSPrimary('1.1.1.3') && await M.setDNSecondary('1.0.0.3')) | |
// Wifi | |
displayStatus('Wifi SSID modified', await M.setWIFI('zzz', 'yyyy')) | |
// Wifi scheduler | |
displayStatus('Wifi scheduler modified', await M.setWIFISchedule(1)) | |
let WORKING_DAYS = [ | |
"Sunday", | |
"Monday", | |
"Tuesday", | |
"Wednesday", | |
"Thursday", | |
"Friday", | |
"Saturday" | |
] | |
for (let i = 0; i < WORKING_DAYS.length; i++) { | |
let day = WORKING_DAYS[i] | |
let start = day + ' 0:00' | |
let end = day + ' 6:00' | |
displayStatus('Wifi scheduler slot (' + start + ',' + end + ')', await M.setWIFIDisabler(start, end)) | |
} | |
log(chalk.green('Remote configuration done!')) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export const IP = [ | |
{ | |
"device": "toto", | |
"hostname": "Google-Home-Mini", | |
"macaddress": "zzzzzzzz", | |
"ipaddress": "192.168.0.22", | |
}] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// https://lafibre.info/bbox-ftth/bbox-fibre-wifi6/1188/ | |
// API : https://api.bbox.fr/doc/apirouter/index.html | |
// Quick and dirty API calls | |
// set NODE_DEBUG=http to debug | |
import nodeFetch from 'node-fetch' | |
import fetchCookie from 'fetch-cookie' | |
const fetch = fetchCookie(nodeFetch) | |
import Debug from 'debug' | |
const debug = Debug.debug('bbox') | |
import { networkInterfaces } from 'os'; | |
import chalk from 'chalk'; | |
const log = console.log; | |
chalk.level = 1; | |
const ip = Object.values(networkInterfaces()).flat().find(i => i.family == 'IPv4' && !i.internal && i.address && i.address.startsWith('192')).address; | |
log(chalk.green('My IP: ' + ip)) | |
let tab = ip.split('.') | |
const MY_BBOX = 'https://' + tab[0] + '.' + tab[1] + '.' + tab[2] + '.' + '254'//'https://mabbox.bytel.fr' | |
log(chalk.green('Bbox IP : ' + MY_BBOX)) | |
const URL = MY_BBOX + '/api/v1' | |
const HEADER = { | |
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:103.0) Gecko/20100101 Firefox/103.0", | |
"Accept": "*/*", | |
"Accept-Language": "fr,fr-FR;q=0.8,en-US;q=0.5,en;q=0.3", | |
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", | |
"X-Requested-With": "XmlHttpRequest", | |
"Sec-Fetch-Dest": "empty", | |
"Sec-Fetch-Mode": "cors", | |
"Sec-Fetch-Site": "same-origin", | |
"Pragma": "no-cache", | |
"Cache-Control": "no-cache" | |
} | |
function getHeader() { | |
return HEADER | |
} | |
function getReferrer(html) { | |
return MY_BBOX + html; | |
} | |
async function returnJSON(response) { | |
try { | |
let json = await response.json(); | |
debug("JSON", json) | |
return json | |
} catch (e) { | |
return "is yet inserted" | |
} | |
} | |
async function returnText(response) { | |
let text = await response.text(); | |
debug("text", text) | |
return text | |
} | |
async function returnStatus(response) { | |
let text = await response.ok; | |
debug("status", text) | |
return text | |
} | |
export function getMyBBox() { | |
return MY_BBOX | |
} | |
export async function init(password) { | |
let response = await fetch(URL + "/login", { | |
"credentials": "omit", | |
"headers": getHeader(), | |
"referrer": getReferrer("indexeole.html"), | |
"body": "password=" + password + "&remember=0", | |
"method": "POST", | |
"mode": "cors" | |
}); | |
let data = await returnStatus(response) | |
return data | |
} | |
async function login() { | |
let result = await fetch(URL + "/login", { | |
"credentials": "include", | |
"headers": getHeader(), | |
"referrer": getReferrer("dhcp.html"), | |
"method": "PUT", | |
"mode": "cors" | |
}); | |
return await returnText(result) | |
} | |
export async function getNATRules() { | |
let response = await fetch(URL + "/nat/rules", | |
{ | |
"credentials": "include", | |
"headers": getHeader(), | |
"referrer": getReferrer("indexeole.html"), | |
"method": "GET", | |
"mode": "cors" | |
}); | |
let data = await returnJSON(response) | |
return data | |
} | |
export async function getHosts() { | |
let response = await fetch(URL + "/hosts", | |
{ | |
"credentials": "include", | |
"headers": getHeader(), | |
"referrer": getReferrer("indexeole.html"), | |
"method": "GET", | |
"mode": "cors" | |
}); | |
let data = await returnJSON(response) | |
return data[0].hosts.list | |
} | |
//Define wifi | |
export async function setWIFI(ssid, passphrase) { | |
let response = await fetch(URL + "/wireless/common", { | |
"credentials": "include", | |
"headers": getHeader(), | |
"referrer": getReferrer("wifi.html"), | |
"body": "security24=WPA2&ssid24=" + ssid + "&passphrase24=" + passphrase, | |
"method": "PUT", | |
"mode": "cors" | |
}); | |
let data = await returnStatus(response) | |
return data | |
} | |
//Define wifi scheduler | |
export async function setWIFISchedule(value) { | |
let response = await fetch(URL + "/wireless/scheduler", { | |
"credentials": "include", | |
"headers": getHeader(), | |
"referrer": getReferrer("wifi.html"), | |
"body": "enable=" + value, | |
"method": "PUT", | |
"mode": "cors" | |
}); | |
let data = await returnStatus(response) | |
return data | |
} | |
// Masque reseau | |
export async function setNetworkMask(ipaddress) { | |
let response = await fetch(URL + "/lan", { | |
"credentials": "include", | |
"headers": getHeader(), | |
"referrer": getReferrer("dhcp.html"), | |
"body": "ipaddress=" + ipaddress, | |
"method": "PUT", | |
"mode": "cors" | |
}); | |
let data = await returnJSON(response) | |
return data | |
} | |
// DHCP | |
export async function setDHCP(min, max) { | |
let response = await fetch(URL + "/dhcp", { | |
"credentials": "include", | |
"headers": getHeader(), | |
"referrer": getReferrer("dhcp.html"), | |
"body": "enable=1&minaddress=" + min + "&maxaddress=" + max + "&leasetime=86400", | |
"method": "PUT", | |
"mode": "cors" | |
}); | |
let data = await returnStatus(response) | |
return data | |
} | |
//DNS | |
export async function setDNSPrimary(dns) { | |
let response = await fetch(URL + "/dns/servers/primary", { | |
"credentials": "include", | |
"headers": getHeader(), | |
"referrer": getReferrer("dhcp.html"), | |
"body": "primary=" + dns, | |
"method": "PUT", | |
"mode": "cors" | |
}); | |
let data = await returnStatus(response) | |
return data | |
} | |
export async function setDNSecondary(dns) { | |
let response = await fetch(URL + "/dns/servers/secondary", { | |
"credentials": "include", | |
"headers": getHeader(), | |
"referrer": getReferrer("dhcp.html"), | |
"body": "secondary=" + dns, | |
"method": "PUT", | |
"mode": "cors" | |
}); | |
let data = await returnStatus(response) | |
return data | |
} | |
//IP | |
async function getToken() { | |
// await login() | |
let response = await fetch(URL + "/device/token", { | |
"credentials": "include", | |
"headers": getHeader(), | |
"referrer": getReferrer("dhcp.html"), | |
"method": "GET", | |
"mode": "cors" | |
}); | |
let data = await returnJSON(response) | |
return data[0].device.token | |
} | |
export async function setIPMAC(device, ipaddress, macaddress, hostname) { | |
if (!device) device = hostname | |
if (!ipaddress || !macaddress) { | |
return 'Missing parameter(s) ' + device + ' ' + ipaddress + ' ' + macaddress + ' ' + hostname | |
} | |
if (!hostname) hostname = macaddress | |
let token = await getToken() | |
let response = await fetch(URL + "/dhcp/clients?btoken=" + token, { | |
"credentials": "include", | |
"headers": getHeader(), | |
"referrer": getReferrer("dhcp.html"), | |
"body": "enable=1&device=" + device + "&ipaddress=" + ipaddress + "&macaddress=" + encodeURI(macaddress) + "&hostname=" + hostname, | |
"method": "POST", | |
"mode": "cors" | |
}); | |
try { | |
return returnStatus(response) | |
} catch (e) { | |
return "Failed to insert" + device + " " + ipaddress + " " + macaddress + " " + hostname | |
} | |
} | |
export async function getIPMAC() { | |
let response = await fetch(URL + "/dhcp/clients", { | |
"credentials": "include", | |
"headers": getHeader(), | |
"referrer": getReferrer("dhcp.html"), | |
"method": "GET", | |
"mode": "cors" | |
}); | |
try { | |
return returnJSON(response) | |
} catch (e) { | |
return "Failed to insert" + device + " " + ipaddress + " " + macaddress + " " + hostname | |
} | |
} | |
export async function removeIPMAC(id) { | |
let response = await fetch(URL + "/dhcp/clients/" + id, { | |
"credentials": "include", | |
"headers": getHeader(), | |
"referrer": getReferrer("dhcp.html"), | |
"method": "delete", | |
"mode": "cors" | |
}); | |
try { | |
return returnStatus(response) | |
} catch (e) { | |
return "Failed to insert" + device + " " + ipaddress + " " + macaddress + " " + hostname | |
} | |
} | |
export async function setWIFIDisabler(start, end) { | |
// "body": "enable=1&start=Monday%200%3A00&end=Monday%201%3A00&occurency=0", | |
let token = await getToken() | |
let response = await fetch(URL + "/wireless/scheduler?btoken=" + token, { | |
"credentials": "include", | |
"headers": getHeader(), | |
"referrer": getReferrer("wifi.html"), | |
"body": "enable=1&start=" + encodeURI(start) + "&end=" + encodeURI(end) + "&occurency=0", | |
"method": "POST", | |
"mode": "cors" | |
}); | |
return returnStatus(response) | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment