lookyloo/website/web/templates/capture.html

459 lines
20 KiB
HTML

{% extends "main.html" %}
{% from 'bootstrap5/utils.html' import render_messages %}
{% block title %}Capture{% endblock %}
{% block card %}
<meta property="og:title" content="Lookyloo" />
<meta property="og:type" content="website"/>
<meta
property="og:description"
content="Lookyloo captures websites and let you investigate them."
/>
<meta
property="og:image"
content="https://{{public_domain}}{{ url_for('static', filename='lookyloo.jpeg') }}"
/>
<meta
property="og:url"
content="https://{{public_domain}}"
/>
<meta name="twitter:card" content="summary_large_image">
{% endblock %}
{% block content %}
<div class="container">
<center>
<a href="{{ url_for('index') }}" title="Go back to index">
<img src="{{ url_for('static', filename='lookyloo.jpeg') }}"
alt="Lookyloo" width="25%">
</a>
</center>
{{ render_messages(container=True, dismissible=True) }}
<form role="form" action="{{ url_for('capture_web') }}" method=post enctype=multipart/form-data>
<div class="row mb-3">
<div class="col-sm-10">
<div class="form-check">
<input class="form-check-input" type="checkbox" name="listing" {% if default_public %}checked="true"{% endif %}></input>
<label for="listing" class="form-check-label">Display results on public page</label>
</div>
</div>
</div>
<!-- Submission type -->
<nav>
<div class="nav nav-tabs" id="submission-type" role="tablist">
<button class="nav-link active" id="nav-url-tab" data-bs-toggle="tab" data-bs-target="#nav-url" type="button" role="tab" aria-current="nav-url" aria-selected="true" href="#">URL(s)</button>
<button class="nav-link" id="nav-doc-tab" data-bs-toggle="tab" data-bs-target="#nav-doc" type="button" role="tab" aria-current="nav-doc" aria-selected="false" href="#">Web enabled document</button>
</div>
</nav>
<div class="tab-content" id="nav-tabContent">
</br>
<div class="tab-pane fade show active" id="nav-url" role="tabpanel" aria-labelledby="nav-url-tab">
<div class="row input-group mb-3">
<label for="url" class="col-sm-1 col-form-label">URL:</label>
<input type="text" class="form-control col-auto" name="url" id=singleCaptureField
placeholder="URL to capture" value="{{predefined_url_to_capture}}" required>
<textarea class="form-control col-auto d-none" placeholder="URLs to capture, one per line"
name="urls" id=multipleCapturesField></textarea>
<span class="col-sm-2 input-group-text">
<div class="form-check">
<input class="form-check-input" name="multipleCaptures" id="multipleCaptures" type="checkbox"
value="" aria-label="tick to enable multiple captures">
<label for="multipleCaptures" class="form-check-label">Multiple captures</label>
</div>
</span>
</div>
</div>
<div class="tab-pane fade" id="nav-doc" role="tabpanel" aria-labelledby="nav-doc-tab">
<div class="row mb-3">
<label for="document" class="col-sm-1 col-form-label">Document:</label>
<div class="col-sm-10">
<input type="file" class="form-control-file" id="document" name="document">
<div>Instead of a URL, you can upload a file. Preferably an HTML document, but it can be anything supported by a browser.</div>
</div>
</div>
</div>
</div>
<hr>
<!-- End of Submission type -->
<div>
<button class="btn btn-link" type="button" data-bs-toggle="collapse" data-bs-target="#collapseConfigBrowser"
aria-expanded="false" aria-controls="collapseConfigBrowser">
<p style="margin-left: -12px; margin-top: 12px; font-size: x-large; color: black; text-decoration: underline; text-decoration-color: blue;">
<b>Browser Configuration</b>
</p>
</button>
<div class="help-tip" title="Lookyloo uses an emulated browser for all captures, click to configure the User-Agent"></div>
</div>
<div id="collapseConfigBrowser" class="collapse d-xl-block">
<div class="card card-body">
{% if personal_ua %}
<div class="row mb-3">
<div class="col-sm-10">
<div class="form-check">
<input class="form-check-input" type="radio" id="personal_ua_select" name="user_agent_select"></input>
<label for="personal_ua_select" class="form-check-label">
Use the current <a href="https://en.wikipedia.org/wiki/User_agent">user-agent</a> of your own browser:</br>
{{ personal_ua }}
</label>
<input class="visually-hidden" type="text" id="personal_ua" name="personal_ua" value="{{ personal_ua }}" disabled></input>
</div>
</div>
</div>
<hr>
{% endif %}
<div class="row mb-3">
<div class="col-sm-10">
<div class="form-check">
<input class="form-check-input" type="radio" id="predefined_ua_select" name="user_agent_select" checked></input>
<label for="predefined_ua_select" class="form-check-label">Pick the <a href="https://en.wikipedia.org/wiki/User_agent">user-agent</a> of your choice:</label>
</div>
</div>
</div>
<div id="prefed_selector">
<div class="row mb-3">
<label for="os-type" class="col-sm-2 col-form-label">OS type:</label>
<div class="col-sm-10">
<select class="form-select" name="os-type" id="os-type" autocomplete="off">
<option value="desktop" selected>Desktop</option>
<option value="mobile">Mobile</option>
</select>
</div>
</div>
<!-- Desktops -->
<div id="desktops-list">
<div class="row mb-3">
<label for="os" class="col-sm-2 col-form-label">Operating System:</label>
<div class="col-sm-10">
<select class="form-select" name="os" id="os">
{% for os in user_agents.keys()|sort(reverse=True) %}
<!-- Select the default os -->
<option value="{{ os }}" {% if os==default['os'] %}selected{% endif %}>{{ os }}</option>
{% endfor%}
</select>
</div>
</div>
{% for os, browsers in user_agents.items() %}
<!-- Hide the browsers that aren't part of the default os -->
<div id="{{os.replace(' ', '_')}}" class="style-sub-1 row mb-3" {% if not os==default['os'] %}style="display: none;"{%endif%}>
<label for="browser" class="col-sm-2 col-form-label">Browser Type:</label>
<div class="col-sm-10">
<!-- Disable all the selects not related to the default os -->
<select class="form-select" name="browser" {% if not os==default['os'] %}disabled{%endif%}>
{% for browser in browsers.keys()|sort(reverse=True) %}
<!-- Select the default browser -->
<option value="{{ browser }}" {% if browser==default['browser'] %}selected{% endif %}>{{ browser }}</option>
{% endfor%}
</select>
</div>
</div>
{% for browser, user_agents in browsers.items() %}
<!-- Hide the user agents that aren't part of the default OS and browsers that aren't part of the default os -->
<div id="{{os.replace(' ', '_')}}_{{browser.replace(' ', '_')}}" class="style-sub-2 row mb-3" {% if not os==default['os'] or not browser==default['browser']%} style="display: none;"{%endif%}>
<label for="user_agent" class="col-sm-2 col-form-label">User-Agent:</label>
<div class="col-sm-10">
<!-- Disable all the selects, unless it is in default os and browser -->
<select class="form-select" name="user_agent" {% if not os==default['os'] or not browser==default['browser'] %}disabled{%endif%}>
{% for user_agent in user_agents %}
<!-- Select the default ua -->
<option value="{{ user_agent }}" {% if user_agent==default['useragent'] %}selected{% endif %}>{{ user_agent }}</option>
{% endfor%}
</select>
</div>
</div>
{% endfor%}
{% endfor%}
</div>
</div>
<!-- End of Desktops -->
<!-- Mobiles -->
<div id="mobiles-list" style="display:none">
<div class="row mb-3">
<label for="os" class="col-sm-2 col-form-label">Device name:</label>
<div class="col-sm-10">
<select class="form-select" name="device_name" id="device-name-mobile" disabled>
{% for device_name in devices['mobile']['default'].keys() %}
<option value="{{ device_name }}">{{ device_name }}</option>
{%endfor%}
</select>
</div>
</div>
</div>
<!-- End of Mobiles -->
<hr>
<div class="row mb-3">
<div class="col-sm-10">
<div class="form-check">
<input class="form-check-input" type="radio" id="freetext_ua_select" name="user_agent_select"></input>
<label for="freetext_ua_select" class="form-check-label">Type the <a href="https://en.wikipedia.org/wiki/User_agent">user-agent</a> of your choice:</label>
</div>
</div>
</div>
<div class="row mb-3">
<label for="freetext_ua" class="col-sm-2 col-form-label">User-Agent:</label>
<div class="col-sm-10">
<input type="text" class="form-control" name="freetext_ua" id="freetext_ua"
placeholder="String to use as a User-Agent for the capture" disabled>
</div>
</div>
</div>
</div>
<hr>
<div>
<button class="btn btn-link" type="button" data-bs-toggle="collapse" data-bs-target="#collapseConfigCapture" aria-expanded="false" aria-controls="collapseConfigCapture">
<p style="margin-left: -12px; margin-top: 12px; font-size: x-large; color: black; text-decoration: underline; text-decoration-color: blue;">
<b>Capture Configuration</b>
</p>
</button>
<div class="help-tip" title="Edit configuration options for the capture."></div>
</div>
<div id="collapseConfigCapture" class="collapse">
<div class="card card-body">
<!-- Referer -->
<div class="row mb-3">
<label for="referer" class="col-sm-2 col-form-label"><a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referer">Referer</a>:</label>
<div class="col-sm-10">
<input type="text" class="form-control" name="referer" id=referer placeholder="Pass referer of the URL">
</div>
</div>
<div class="row mb-3">
<label for="dnt" class="col-sm-2 col-form-label"><a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/DNT">Do not Track</a>:</label>
<div class="col-sm-10">
<select class="form-select" name="dnt" id="dnt" aria-label="Select a value for the Do Not Track HTTP Header">
<option value="" selected>Select a value for the DNT header (header not set otherwise)</button>
<option value="0">0 (The user prefers to allow tracking on the target site.)</option>
<option value="1">1 (The user prefers not to be tracked on the target site.)</option>
<option value="null">null (The user has not specified a preference about tracking.)</option>
</select>
</div>
</div>
<div class="row mb-3">
<label for="headers" class="col-sm-2 col-form-label">Other HTTP headers:</label>
<div class="col-sm-10">
<textarea class="form-control" name="headers" id=headers rows=3 placeholder="Accept-Language: en-US;q=0.5, fr-FR;q=0.4"></textarea>
</div>
</div>
<div class="row mb-3">
{% set local_TZ, local_UTC_offset, all_timezones = tz_info() %}
<label for="timezone_id" class="col-sm-2 col-form-label">Timezone (defaults to {{local_TZ}} - {{local_UTC_offset}}):</label>
<div class="col-sm-10">
<input class="form-control" list="tzOptions" name="timezone_id" id="timezone_id" aria-label="Pick the timezone for the capture">
<datalist id="tzOptions">
{% for tz in all_timezones %}
<option value="{{tz}}">{{tz}}</option>
{%endfor%}
</datalist>
</div>
</div>
<div class="row mb-3">
<label for="locale" class="col-sm-2 col-form-label">Locale:</label>
<div class="col-sm-10">
<input type="text" class="form-control" name="locale" id="locale" placeholder="Pass a language locale to the capture">
</div>
</div>
<div class="row mb-3">
<label for="color_scheme" class="col-sm-2 col-form-label">Color scheme:</label>
<div class="col-sm-10">
<select class="form-select" id="color_scheme" name="color_scheme" aria-label="Select a prefered color scheme">
<option value="" selected>Select a color scheme</option>
<option value="light">Light</option>
<option value="dark">Dark</option>
<option value="no-preference">No preference</option>
</select>
</div>
</div>
<div class="row mb-3">
<label for="geoloc" class="col-sm-2 col-form-label">Geolocation:</label>
<div class="col-sm-10" id="geoloc">
<div class="row g-3">
<div class="col">
<input type="number" step="any" class="form-control" name="geo_latitude" id="geo_latitude" placeholder="Latitude">
</div>
<div class="col">
<input type="number" step="any" class="form-control" name="geo_longitude" id="geo_longitude" placeholder="Longitude">
</div>
</div>
</div>
</div>
{% if not has_global_proxy %}
<div class="row mb-3">
<label for="proxy" class="col-sm-2 col-form-label">Proxy:</label>
<div class="col-sm-10">
<input type="text" class="form-control" name="proxy" id="proxy" placeholder="Expected format: [scheme]://[username]:[password]@[hostname]:[port]">
</div>
</div>
{%endif%}
<div class="row mb-3">
<label for="httpauth" class="col-sm-2 col-form-label">HTTP Authentication</label>
<div class="col-sm-10" id="httpauth">
<div class="row g-3">
<div class="col">
<input type="text" class="form-control" name="http_auth_username" id="http_auth_username" placeholder="Username">
</div>
<div class="col">
<input type="text" class="form-control" name="http_auth_password" id="http_auth_password" placeholder="Password">
</div>
</div>
<div class="alert alert-danger" role="alert">
The authentication credentials will be stored on the lookyloo instance and potentially
accessed by third parties (either because the Lookyloo instance is public,
or people other than you have access to the instance).
If that's the case, please make sure none of them can be used to login as yourself
on websites.
</div>
</div>
</div>
<div class="row mb-3">
<label for="cookies" class="col-sm-2 col-form-label">Cookies:</label>
<div class="col-sm-10">
<input type="file" class="form-control-file" id="cookies" name="cookies">
<div>The file can either be the JSON export from the Firefox plugin <a href="https://addons.mozilla.org/en-US/firefox/addon/cookie-quick-manager/">Cookie Quick Manager</a> <b>or</b> from an other Lookyloo capture.</div>
<div class="alert alert-danger" role="alert">
The cookies will be stored on the lookyloo instance and potentially
accessed by third parties (either because the Lookyloo instance is public,
or people other than you have access to the instance).
If that's the case, please make sure none of them can be used to login as yourself
on websites.
</div>
</div>
</div>
</div>
</div>
<hr>
<center>
<b>
{% if default_public %}
By default, the capture is public. If you do not want that, untick the box at the top of the form.
{% else %}
By default, the capture is private (not visible on the index page). If you want it to be public tick the box at the top of the form.
{% endif %}
</b>
</br>
</br>
<button type="submit" class="new-capture-button btn btn-primary" id="btn-looking">Start looking!</button>
</center>
</form>
</div>
{% endblock %}
{% block scripts %}
{{ super() }}
<script src='{{ url_for('static', filename='capture.js') }}'
integrity="{{get_sri('static', 'capture.js')}}"
crossorigin="anonymous"></script>
<script>
$('#nav-url-tab').on('click', function(e) {
document.getElementById("singleCaptureField").required = true;
document.getElementById("document").required = false;
$("#singleCaptureField").removeClass("d-none");
document.getElementById('multipleCaptures').checked = false;
$("#multipleCapturesField").addClass("d-none");
});
$('#nav-doc-tab').on('click', function(e) {
document.getElementById("document").required = true;
document.getElementById("multipleCapturesField").required = false;
document.getElementById("singleCaptureField").required = false;
});
</script>
<script>
$('#multipleCaptures').on('click', function(e) {
if (document.getElementById('multipleCaptures').checked == true) {
document.getElementById('singleCaptureField').value = '';
$("#singleCaptureField").addClass("d-none");
document.getElementById("singleCaptureField").required = false;
$("#multipleCapturesField").removeClass("d-none");
document.getElementById("multipleCapturesField").required = true;
}
else {
document.getElementById('multipleCapturesField').value = '';
$("#singleCaptureField").removeClass("d-none");
document.getElementById("singleCaptureField").required = true;
$("#multipleCapturesField").addClass("d-none");
document.getElementById("multipleCapturesField").required = false;
}
})
</script>
<script>
$('#personal_ua_select').on('click', function(e) {
$('#personal_ua').prop("disabled", false);
$('#freetext_ua').prop("disabled", true);
disablePredefinedUA();
});
$('#predefined_ua_select').on('click', function(e) {
$('#os-type').val('desktop').trigger('change');
$('#freetext_ua').prop("disabled", true);
$('#personal_ua').prop("disabled", true);
});
$('#freetext_ua_select').on('click', function(e) {
$('#freetext_ua').prop("disabled", false);
$('#personal_ua').prop("disabled", true);
disablePredefinedUA();
});
const disablePredefinedUA = function() {
$('#os-type').prop("disabled", true);
$('#device-name-mobile').prop("disabled", true);
$('#os').prop("disabled", true);
$('select[name="browser"]').prop("disabled", true);
$('select[name="user_agent"]').prop("disabled", true);
};
$('#os-type').on('change', function() {
$('#os-type').prop("disabled", false);
if ( this.value == "mobile")
{
$("#mobiles-list").show();
$('#device-name-mobile').prop("disabled", false);
$("#desktops-list").hide();
$('#os').prop("disabled", true);
$('select[name="browser"]').prop("disabled", true);
$('select[name="user_agent"]').prop("disabled", true);
}
else
{
$("#desktops-list").show();
$('#os').prop("disabled", false);
$('select[name="browser"]:visible').prop("disabled", false);
$('select[name="user_agent"]:visible').prop("disabled", false);
$("#mobiles-list").hide();
$('#device-name-mobile').prop("disabled", true);
}
});
</script>
{% endblock %}