lookyloo/website/web/templates/capture.html

494 lines
23 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 styles %}
{{ super() }}
<link rel="stylesheet" href="{{ url_for('static', filename='index.css') }}"
{{get_sri('static', 'index.css')}}
crossorigin="anonymous">
{% endblock %}
{% block content %}
<div class="corner-ribbon top-left sticky white shadow">
<a href="https://www.lookyloo.eu/docs/main/index.html">Documentation</a>
</div>
<div class="corner-ribbon bottom-left sticky white shadow">
<a href="https://github.com/Lookyloo/lookyloo/releases/tag/v{{version}}">Changelog</br>(v{{version}})</a>
</div>
{% if show_project_page %}
<div class="corner-ribbon top-right sticky white shadow">
<a href="https://github.com/Lookyloo">Project page</a>
</div>
{% endif%}
<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) }}
{% if current_user.is_authenticated %}
<p class="lead">You are logged-in as <strong>{{ current_user.id }}</strong>
</br>
{% if user_config %}
{% if user_config['overwrite'] == true %}
The settings in your users configuration file will overwrite the settings you configure in the form below.
{% else %}
The settings in your users configuration file will only be used if you don't overwrite them in the form below.
{% endif %}
<p>
<dl class="row">
{% for key, value in user_config.items() %}
{% if key != 'overwrite' %}
<dt class="col-sm-3">{{ key }}</dt>
<dd class="col-sm-9">
{% if value is mapping %}
<dl class="row">
{% for sub_key, sub_value in value.items() %}
<dt class="col-sm-4">{{ sub_key}}</dt>
<dd class="col-sm-8">{{ sub_value }}</dd>
{% endfor %}
</dl>
{% else %}
{{ value }}
{% endif %}
<dd>
{% endif %}
{% endfor %}
<dl>
{% endif %}
{% endif %}
<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" id="listing" name="listing"
{% if default_public or predefined_settings.get('listing') is true %}checked="checked"{% endif %}>
<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_settings.get('url', '')}}" required>
<textarea class="form-control col-auto d-none" placeholder="URLs to capture, one per line"
name="urls" id=multipleCapturesField></textarea>
<div 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>
</div>
</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 show">
<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">
<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>
</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>
<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" {% if not os==default['os'] %}style="display: none;"{%endif%}>
<label class="row mb-3">
<span class="col-sm-2 col-form-label">Browser Type:</span>
<span 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>
</span>
</label>
</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" {% if not os==default['os'] or not browser==default['browser']%} style="display: none;"{%endif%}>
<label class="row mb-3">
<span class="col-sm-2 col-form-label">User-Agent:</span>
<span 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>
</span>
</label>
</div>
{% endfor%}
{% endfor%}
</div>
</div>
<!-- End of Desktops -->
<!-- Mobiles -->
<div id="mobiles-list" style="display:none">
<div class="row mb-3">
<label for="device-name-mobile" 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">
<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">
<div class="row mb-3">
<label for="allow_tracking" class="col-sm-2 col-form-check-label">Allow tracking:</label>
<div class="col-sm-10">
<div class="form-check">
<input class="form-check-input" type="checkbox" id="allow_tracking" name="allow_tracking" aria-describedby="allow_tracking_help"
{% if predefined_settings.get('allow_tracking') is true %}checked="checked"{% endif %}>
<div id="allow_tracking_help" class="form-text">We'll attempt to click on the button allowing the website captured to violate your privacy.</div>
</div>
</div>
</div>
<div class="row mb-3">
<label for="java_script_enabled" class="col-sm-2 col-form-check-label">Enable <a href="https://playwright.dev/python/docs/emulation#javascript-enabled">JavaScript</a>:</label>
<div class="col-sm-10">
<div class="form-check">
<input class="form-check-input" type="checkbox" id="java_script_enabled" name="java_script_enabled" aria-describedby="java_script_enabled_help"
{% if predefined_settings.get('java_script_enabled', true) is true %}checked="checked"{% endif %}>
<div id="java_script_enabled_help" class="form-text">If disabled, the browser will not run any JavaScript when rendering the page.</div>
</div>
</div>
</div>
<!-- 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="https://my.website.org/path">
<div class="alert alert-info" role="alert">
Sets the Referrer HTTP header.
</div>
</div>
</div>
<div class="row mb-3">
<label for="locale" class="col-sm-2 col-form-label">Browser <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Language">locale</a> (Accept-Language):</label>
<div class="col-sm-10">
<input type="text" class="form-control" name="locale" id="locale" placeholder="fr-CH, fr;q=0.9, en;q=0.8, de;q=0.7, *;q=0.5">
<div class="alert alert-info" role="alert">
Sets the Accept-Language HTTP header.
</div>
</div>
</div>
<div class="row mb-3">
<label for="headers" class="col-sm-2 col-form-label">Other <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers">HTTP headers</a>:</label>
<div class="col-sm-10">
<textarea class="form-control" name="headers" id=headers rows=3 placeholder="X-Auth-Token: YWJjcmFjYWRhYnJh"></textarea>
<div class="alert alert-warning" role="alert">
The headers will be added to the request. One header per line.<br>
For <strong>Referrer</strong>, <strong>Accept-Language</strong> (Locale),
<strong>Authorization</strong> (HTTP Authentication), <strong>Cookie</strong>,
and <strong>DNT</strong> (Do Not Track),
please use the dedicated fields in this form.
</div>
</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"><a href="https://playwright.dev/python/docs/emulation#locale--timezone">Timezone</a> (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" placeholder="Europe/Vatican">
<datalist id="tzOptions">
{% for tz in all_timezones %}
<option value="{{tz}}">{{tz}}</option>
{%endfor%}
</datalist>
</div>
</div>
<div class="row mb-3">
<label for="color_scheme" class="col-sm-2 col-form-label"><a href="https://playwright.dev/python/docs/emulation#color-scheme-and-media">Color scheme</a>:</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"><a href="https://playwright.dev/python/docs/emulation#geolocation">Geolocation</a>:</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 Basic 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 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> (discontinued):</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)</option>
<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 class="alert alert-info" role="alert">
Sets the DNT HTTP header.
</div>
</div>
</div>
</div>
</div>
<hr>
{% if current_user.is_authenticated %}
<!-- admin only checkbox for autoreport -->
<div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="auto-report" name="auto-report" >
<label for="auto-report" class="form-check-label">Automatically submit to investigation team</label>
</div>
<div id="collapseMailConfiguration" class="collapse">
<div class="card card-body">
<div class="row mb-3">
<label class="col-sm-3 col-form-label" for="email">Email of the sender (optional): </label>
<div class="col-sm-9">
<input class="form-control" type="text" id="email"
name="email" placeholder="myself@example.com">
</div>
</div>
<div class="row mb-3">
<label class="col-sm-3 col-form-label" for="comment">Comment (optional): </label>
<div class="col-sm-9">
<textarea class="form-control" id="comment" name="comment" rows="3"></textarea>
</div>
</div>
</div>
</div>
</div>
<hr>
{% endif %}
<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') }}'
{{get_sri('static', 'capture.js')}}
nonce="{{ csp_nonce() }}"
crossorigin="anonymous"></script>
{% endblock %}