Skip to content

Commit

Permalink
Add browser support (#36)
Browse files Browse the repository at this point in the history
Co-authored-by: Sindre Sorhus <sindresorhus@gmail.com>
  • Loading branch information
Richienb and sindresorhus committed Nov 20, 2020
1 parent f2a688e commit dcf33df
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 4 deletions.
68 changes: 68 additions & 0 deletions browser.js
@@ -0,0 +1,68 @@
/* eslint-env browser */
'use strict';
import pEvent from 'p-event';
import isIp from 'is-ip';

const getIp = async ({isSecondTry = false} = {}) => {
try {
const peerConnection = new RTCPeerConnection({iceServers: []});

peerConnection.createDataChannel('');
peerConnection.createOffer(peerConnection.setLocalDescription.bind(peerConnection), () => {});

const {candidate} = await pEvent(peerConnection, 'icecandidate', {
timeout: 10000
});

peerConnection.close();

if (candidate && candidate.candidate) {
const result = candidate.candidate.split(' ')[4];
if (result.endsWith('.local')) {
if (isSecondTry) {
return;
}

const inputDevices = await navigator.mediaDevices.enumerateDevices();
const inputDeviceTypes = new Set(inputDevices.map(({kind}) => kind));

const constraints = {};

if (inputDeviceTypes.has('audioinput')) {
constraints.audio = true;
} else if (inputDeviceTypes.has('videoinput')) {
constraints.video = true;
} else {
return;
}

const mediaStream = await navigator.mediaDevices.getUserMedia(constraints);
for (const track of mediaStream.getTracks()) {
track.stop();
}

return await getIp({isSecondTry: true});
}

return result;
}
} catch {}
};

export const v4 = async () => {
const result = await getIp();
if (isIp.v4(result)) {
return result;
}
};

v4.sync = () => undefined;

export const v6 = async () => {
const result = await getIp();
if (isIp.v6(result)) {
return result;
}
};

v6.sync = () => undefined;
14 changes: 11 additions & 3 deletions package.json
Expand Up @@ -18,8 +18,13 @@
},
"files": [
"index.js",
"index.d.ts"
"index.d.ts",
"browser.js"
],
"exports": {
"browser": "./browser.js",
"default": "./index.js"
},
"keywords": [
"ip",
"ipv6",
Expand All @@ -34,11 +39,14 @@
],
"dependencies": {
"default-gateway": "^6.0.0",
"ipaddr.js": "^1.9.1"
"ipaddr.js": "^1.9.1",
"is-ip": "^3.1.0",
"p-event": "^4.2.0"
},
"devDependencies": {
"ava": "^2.4.0",
"tsd": "^0.13.1",
"xo": "^0.32.1"
}
},
"browser": "browser.js"
}
2 changes: 1 addition & 1 deletion readme.md
Expand Up @@ -30,7 +30,7 @@ console.log(internalIp.v4.sync())

The module returns the address of the internet-facing interface, as determined from the default gateway. When the address cannot be determined for any reason, `undefined` will be returned.

The module relies on operating systems tools. On Linux and Android, the `ip` command must be available, which depending on distribution might not be installed by default. It is usually provided by the `iproute2` package.
The module relies on operating systems tools. On Linux and Android, the `ip` command must be available, which depending on distribution might not be installed by default. It is usually provided by the `iproute2` package. `.v4.sync()` and `.v6.sync()` are not supported in browsers and just return `undefined`.

## Related

Expand Down

0 comments on commit dcf33df

Please sign in to comment.