Initial commit: auth
This commit is contained in:
commit
372e71c8f5
11 changed files with 500 additions and 0 deletions
40
src/ip-check.js
Normal file
40
src/ip-check.js
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
import dns from 'dns/promises'
|
||||
|
||||
// OFFICE_IP_CHECK supports: static IP, CIDR range, DDNS hostname, or 'disabled'
|
||||
const config = process.env.OFFICE_IP_CHECK || 'disabled'
|
||||
let cachedIP = null
|
||||
let cacheExpiry = 0
|
||||
|
||||
function ipInCidr(ip, cidr) {
|
||||
const [range, bits] = cidr.split('/')
|
||||
const mask = ~(2 ** (32 - parseInt(bits)) - 1) >>> 0
|
||||
const toInt = s => s.split('.').reduce((a, o) => (a << 8) + parseInt(o), 0) >>> 0
|
||||
return (toInt(ip) & mask) === (toInt(range) & mask)
|
||||
}
|
||||
|
||||
async function getOfficeIP() {
|
||||
if (config === 'disabled') return null
|
||||
if (Date.now() < cacheExpiry && cachedIP) return cachedIP
|
||||
|
||||
const isHostname = /[a-zA-Z]/.test(config) && !config.includes('/')
|
||||
if (isHostname) {
|
||||
try {
|
||||
const addrs = await dns.resolve4(config)
|
||||
cachedIP = addrs[0]
|
||||
cacheExpiry = Date.now() + 5 * 60 * 1000 // 5 min TTL
|
||||
} catch {
|
||||
// DNS failed — keep last known good IP rather than locking everyone out
|
||||
}
|
||||
} else {
|
||||
cachedIP = config
|
||||
cacheExpiry = Infinity
|
||||
}
|
||||
return cachedIP
|
||||
}
|
||||
|
||||
export async function isOnsite(requestIP) {
|
||||
if (config === 'disabled') return true
|
||||
const officeIP = await getOfficeIP()
|
||||
if (!officeIP) return true
|
||||
return officeIP.includes('/') ? ipInCidr(requestIP, officeIP) : requestIP === officeIP
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue