Skip to content

Instantly share code, notes, and snippets.

@ezekg
Last active January 8, 2024 23:18
Show Gist options
  • Save ezekg/d1f87dd2c85492a2dae9af27a814605f to your computer and use it in GitHub Desktop.
Save ezekg/d1f87dd2c85492a2dae9af27a814605f to your computer and use it in GitHub Desktop.
Example of validating a node-locked license from an Electron app
<!DOCTYPE html>
<html>
<head>
<meta charset='UTF-8'>
<title>Node-locked License Validation Example</title>
</head>
<body>
<button type='button' id='validate-license'>
Validate License
</button>
<script>
const KEYGEN_ACCOUNT = 'YOUR_KEYGEN_ACCOUNT_ID'
// Make sure these npm packages are installed:
const { prompt, confirm } = require('smalltalk')
const { getMac } = require('getmac')
const sha1 = require('sha1')
// Validate license key and machine fingerprint when this button is clicked
const button = document.getElementById('validate-license')
button.addEventListener('click', event => {
event.preventDefault()
// Get the current device's MAC address
getMac((err, mac) => {
if (err) {
console.error(err)
return
}
// Hash the mac address to anonymize the fingerprint
const fingerprint = sha1(mac)
console.log(`Current device fingerprint: ${fingerprint}`)
// Prompt the current user for their license key
prompt('License Required', 'Please enter your license key:', '')
.catch(err => console.error(err))
// Validate the license key within the scope of the machine's fingerprint
.then(key => {
return fetch(`https://api.keygen.sh/v1/accounts/${KEYGEN_ACCOUNT}/licenses/actions/validate-key`, {
method: 'POST',
headers: {
'Content-Type': 'application/vnd.api+json',
'Accept': 'application/vnd.api+json'
},
body: JSON.stringify({
meta: {
scope: { fingerprint },
key
}
})
})
})
// Parse JSON response body
.then(res => res.json())
// Handle the license validation result
.then(json => {
const { meta, data, errors } = json
if (errors) {
alert('There was an error while validating your license key.')
console.error(errors)
return
}
if (meta.valid) {
alert(`License ${data.id} is valid!`)
return
}
switch (meta.constant) {
case 'NOT_FOUND': {
alert('That license key does not exist.')
break
}
case 'FINGERPRINT_SCOPE_MISMATCH': {
alert(`License ${data.id} is not valid on the current machine: ${fingerprint}.`)
break
}
case 'NO_MACHINES':
case 'NO_MACHINE': {
alert(`License ${data.id} has not been activated yet.`)
// Create a machine resource using the current fingerprint and license ID
// to "activate" the license.
break
}
default: {
alert('That license key is not valid.')
}
}
})
})
})
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment