Skip to content

Instantly share code, notes, and snippets.

@daisycamber
Last active September 4, 2023 03:14
Show Gist options
  • Save daisycamber/294e73f7359c1a86ae38570951a0f3f2 to your computer and use it in GitHub Desktop.
Save daisycamber/294e73f7359c1a86ae38570951a0f3f2 to your computer and use it in GitHub Desktop.
NFC Security for Django
{% extends 'base.html' %}
{% block content %}
<legend>NFC Verification</legend>
<p>Place the NFC device near the back of the phone. <a href="{% url 'security:mrz' %}" title="Use MRZ instead">Use MRZ instead</a></p>
<form action="{{ request.path }}{% if request.GET.generate %}?generate=t{% endif %}" id="nfc-form" method="POST" class="hide">
{{ form }}
</form>
<p class="text-center" style="font-size: 40px" id="signal"><i class="bi bi-reception-1"></i></p>
<p id="errors">Tap the screen to enable NFC.</p>
{% endblock %}
{% block javascript %}
var form = document.getElementById('nfc-form');
var signal = document.getElementById('signal');
function readTag() {
var successfulWrite = false;
var successfulRead = false;
if ("NDEFReader" in window) {
const ndef = new NDEFReader();
document.getElementById('errors').innerHtml = 'Initialized.';
try {
ndef.scan().then(() => {
document.getElementById('errors').innerHTML = 'Scanning.';
signal.innerHTML = '<i class="bi bi-reception-2"></i>';
ndef.onreading = (event) => {
try {
if(successfulWrite) { return; }
if(successfulRead) { return; }
document.getElementById('errors').innerHTML= 'Read tag.';
signal.innerHTML = '<i class="bi bi-reception-3"></i>';
const decoder = new TextDecoder();
for (const record of event.message.records) {
if(decoder.decode(record.data) == '{{ base_url }}') continue;
document.getElementById('errors').innerHTML= 'Record detected.';
document.getElementById('id_nfc_data_read').value = decoder.decode(record.data);
document.getElementById('id_nfc_id').value = event.serialNumber;
successfulRead = true;
}
var toWrite = {records: [{
recordType: "text",
data: "{{ nfc_data }}"
}, {
recordType: "url",
data: "{{ base_url }}"
}],};
ndef.write(toWrite).then(function() {
successfulWrite = true;
signal.innerHTML = '<i class="bi bi-reception-4"></i>';
document.getElementById('errors').innerHTML= 'Data written, confirming.';
document.getElementById('id_nfc_data_written').value = "{{ nfc_data }}";
var formData = new FormData(form);
$.ajax({
url: '{{ request.path }}{% if request.GET.generate %}?generate=t{% endif %}',
data: formData,
method: 'POST',
timeout: 60 * 1000,
cache: false,
contentType: false,
processData: false,
error: function(xhr, textStatus, errorThrown) {
successfulRead = false;
successfulWrite = false;
document.getElementById('errors').innerHTML = errorThrown.message;
},
success: function(response) {
if(response == 'y') {
document.getElementById('errors').innerHTML= 'Redirecting.';
window.navigator.vibrate({{ default_vibration }});
window.location.href = '{% if request.GET.next %}{{ request.GET.next }}{% else %}/go/{% endif %}';
} else {
successfulRead = false;
successfulWrite = false;
document.getElementById('errors').innerHTML = 'Invalid tag.';
}
}
});
});
} catch(error) {
document.getElementById('errors').innerHTML= error.message;
}
};
});
} catch(error) {
document.getElementById('errors').innerHTML= error.message;
}
}
}
var reading = false;
function initialize() {
if(!reading) {
window.navigator.vibrate({{ default_vibration }});
reading = true;
readTag();
}
}
document.body.addEventListener('click', function(event) {
initialize();
});
document.body.addEventListener('touchmove', function(event) {
initialize();
});
{% if not request.GET.generate %}
setInterval(function() {
$.ajax({
url: "{% url 'security:modal' %}",
method: 'POST',
success: function(data){
if(data == 'y') {
window.location.href = '{% if request.GET.next %}{{ request.GET.next }}{% else %}/go/{% endif %}';
}
}
});
}, 15 * 1000);
{% endif %}
{% endblock %}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment