initial import for Open Source 🎉

This commit is contained in:
Jimmy Zelinskie 2019-11-12 11:09:47 -05:00
parent 1898c361f3
commit 9c0dd3b722
2048 changed files with 218743 additions and 0 deletions

28
templates/500.html Normal file
View file

@ -0,0 +1,28 @@
{% extends "error.html" %}
{% block title %}
<title>Internal Error · Quay</title>
{% endblock %}
{% block content %}
<h3>Something went wrong on our end!</h3>
<h4>
<p><a href="javascript:history.back()">Head on back</a> and retry whatever it was you were doing.</p>
<p>If the issue persists and is blocking you from getting stuff done, <a href="/contact">contact us</a>.</p>
</h4>
{% if has_billing %}
<div style="margin-top: 20px">
Current Service Status:
<span id="status-elem">(Loading)</span>
</div>
<script type="text/javascript" src="//statuspage-production.s3.amazonaws.com/se.js"></script>
<script type="text/javascript">
window.fetchStatusPage({
pageId: '8szqd6w4s277',
renderTo: '#status-elem'
});
</script>
{% endif %}
{% endblock %}

208
templates/base.html Normal file
View file

@ -0,0 +1,208 @@
<!DOCTYPE html>
<html ng-app="quay" class="{% if onprem %}onprem{% else %}hosted{% endif %}">
<head>
<base href="/">
{% block title %}
{% endblock %}
{% block added_meta %}
{% endblock %}
<meta name="viewport" content="width=device-width, initial-scale=1.0">
{% for style_url in external_styles %}
<link rel="stylesheet" href="{{ style_url }}" type="text/css">
{% endfor %}
<!-- Icons -->
<link rel="shortcut icon" href="/static/img/quay_favicon.png" type="image/png" />
<!-- /Icons -->
<!-- Hide the footer until the CSS loads properly. -->
<style type="text/css">
.page-footer {
display: none;
}
.loading-js-fade-in {
text-align: center;
}
</style>
{% block added_stylesheets %}
{% endblock %}
<script type="text/javascript">
window.__endpoints = {{ route_data|tojson|safe }}.paths;
window.__features = {{ feature_set|tojson|safe }};
window.__config = {{ config_set|tojson|safe }};
window.__oauth = {{ oauth_set|tojson|safe }};
window.__external_login = {{ external_login_set|tojson|safe }};
window.__auth_scopes = {{ scope_set|tojson|safe }};
window.__vuln_priority = {{ vuln_priority_set|tojson|safe }}
window.__token = '{{ csrf_token() }}';
window.__kubernetes_namespace = {{ kubernetes_namespace|tojson|safe }};
window.__registry_state = '{{ registry_state }}';
{% if error_code %}
window.__error_code = {{ error_code }};
{% endif %}
{% if error_info %}
window.__error_info = {{ error_info|tojson|safe }};
{% endif %}
</script>
{% for script_url in external_scripts %}
<script src="{{ script_url }}"></script>
{% endfor %}
{% block added_dependencies %}
{% endblock %}
{% for script_path in main_scripts %}
<script src="/static/{{ script_path }}"></script>
{% endfor %}
{% if sentry_public_dsn %}
<script type="text/javascript">
Raven.config('{{ sentry_public_dsn }}').install();
</script>
{% endif %}
{% if munchkin_key %}
<script type="text/javascript">
(function() {
window.__quay_munchkin_queue = []
var didInit = false;
function initMunchkin() {
if(didInit === false) {
didInit = true;
if (!window['Munchkin'] || !Munchkin.init) {
return;
}
Munchkin.init('{{ munchkin_key }}');
window.__quay_munchkin_queue.forEach(function(queue_item) {
Munchkin.munchkinFunction.apply(Munchkin, queue_item);
});
window.__quay_munchkin_queue = [];
}
}
var s = document.createElement('script');
s.type = 'text/javascript';
s.async = true;
s.src = '//munchkin.marketo.net/munchkin-beta.js';
s.onreadystatechange = function() {
if (this.readyState == 'complete' || this.readyState == 'loaded') {
initMunchkin();
}
};
s.onload = initMunchkin;
document.getElementsByTagName('head')[0].appendChild(s);
})();
</script>
{% endif %}
{% if google_analytics_key %}
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
ga('create', '{{ google_analytics_key }}', 'auto');
ga('send', 'pageview');
</script>
{% endif %}
{% if mixpanel_key %}
<!-- start Mixpanel --><script type="text/javascript">
(function(e,b){if(!b.__SV){var a,f,i,g;window.mixpanel=b;a=e.createElement("script");a.type="text/javascript";a.async=!0;a.src=("https:"===e.location.protocol?"https:":"http:")+'//cdn.mxpnl.com/libs/mixpanel-2.2.min.js';f=e.getElementsByTagName("script")[0];f.parentNode.insertBefore(a,f);b._i=[];b.init=function(a,e,d){function f(b,h){var a=h.split(".");2==a.length&&(b=b[a[0]],h=a[1]);b[h]=function(){b.push([h].concat(Array.prototype.slice.call(arguments,0)))}}var c=b;"undefined"!==
typeof d?c=b[d]=[]:d="mixpanel";c.people=c.people||[];c.toString=function(b){var a="mixpanel";"mixpanel"!==d&&(a+="."+d);b||(a+=" (stub)");return a};c.people.toString=function(){return c.toString(1)+".people (stub)"};i="disable track track_pageview track_links track_forms register register_once alias unregister identify name_tag set_config people.set people.set_once people.increment people.append people.track_charge people.clear_charges people.delete_user".split(" ");for(g=0;g<i.length;g++)f(c,i[g]);
b._i.push([a,e,d])};b.__SV=1.2}})(document,window.mixpanel||[]);
mixpanel.init("{{ mixpanel_key }}", { track_pageview : false, debug: {{ is_debug }} });</script><!-- end Mixpanel -->
{% endif %}
</head>
<body ng-class="pageClass + ' ' + (user.anonymous ? 'anon' : 'signedin')" class="co-img-bg-network">
<div id="co-l-footer-wrapper">
<nav class="navbar navbar-default header-bar co-m-navbar co-fx-box-shadow" role="navigation"></nav>
<div class="quay-message-bar"></div>
<div quay-require="['BILLING']">
<div class="quay-service-status-bar"></div>
</div>
<div id="padding-container">
<div id="co-l-view-container">
<div ng-class="newLayout ? '' : 'main-panel co-fx-box-shadow-heavy'">
{% block body_content %}
{% endblock %}
</div>
</div>
</div>
<div id="co-l-footer-push"></div>
</div>
<nav id="co-l-footer" class="page-footer hidden-xs">
<div class="col-md-12">
<ul>
{% if config_set['BRANDING']['footer_img'] %}
<li><a href="{{ config_set['BRANDING']['footer_url'] }}" ng-safenewtab><img src="{{ config_set['BRANDING']['footer_img'] }}"></a></li>
{% endif %}
<li quay-require="['BILLING']"><a href="https://docs.quay.io" ng-safenewtab>Documentation</a></li>
<li quay-require="['BILLING']"><a href="/tos" target="_self">Terms</a></li>
<li quay-require="['BILLING']"><a href="/privacy" target="_self">Privacy</a></li>
<li quay-require="['BILLING']"><a href="/security/" target="_self">Security</a></li>
<li quay-require="['BILLING']"><a href="/about/" target="_self">About</a></li>
{% if has_contact %}
<li><b><a href="{{ contact_href or '/contact/' }}" target="_self">Contact</a></b></li>
{% endif %}
<li quay-require="['BILLING']">
<span class="quay-service-status"></span>
</li>
<li>{{ version_number }}</li>
</ul>
</div>
</nav>
<!-- Modal message dialog -->
<div class="modal fade" id="couldnotloadModal" data-backdrop="static">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">Uh Oh...</h4>
</div>
<div class="modal-body">
Something went wrong when trying to load Quay! Please report this to <a href="mailto:support@quay.io">support@quay.io</a>.
</div>
<div class="modal-footer">
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
{% if google_tagmanager_key %}
<!-- Google Tag Manager (hooked up to CrossDomain) -->
<noscript><iframe src="//www.googletagmanager.com/ns.html?id={{ google_tagmanager_key }}"
height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'//www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','{{ google_tagmanager_key }}');</script>
{% endif %}
<div class="angular-tour-ui" inline="false" tour="angular_tour_current"></div>
</body>
</html>

92
templates/error.html Normal file
View file

@ -0,0 +1,92 @@
<html class="{% if onprem %}onprem{% else %}hosted{% endif %}">
<head>
{% block title %}
{% endblock %}
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css">
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.no-icons.min.css">
<link href='//fonts.googleapis.com/css?family=Droid+Sans:400,700' rel='stylesheet' type='text/css'>
<style type="text/css">
.ship-header {
width: 100%;
height: 400px;
position: relative;
}
.ship-header div.layer {
position: absolute;
top: 0px;
bottom: 0px;
left: 0px;
right: 0px;
}
.ship-header .background {
background-size: cover;
background-image: url(/static/img/500/background.svg);
}
.ship-header .ship {
background-size: cover;
background-image: url(/static/img/500/ship.svg);
position: absolute;
top: 0px;
bottom: 0px;
right: 0px;
width: 19%;
}
.ship-header .water {
background-size: cover;
background-image: url(/static/img/500/water.svg);
}
@-webkit-keyframes steaming {
0% {
-webkit-transform: translateX(0px) scaleX(1);
}
50% {
-webkit-transform: translateX(-180%) scaleX(1);
}
51% {
-webkit-transform: translateX(-180%) scaleX(-1);
}
99% {
-webkit-transform: translateX(0px) scaleX(-1);
}
100% {
-webkit-transform: translateX(0px) scaleX(1);
}
}
.ship-header .ship {
-webkit-animation-name: steaming;
-webkit-animation-duration: 30s;
-webkit-animation-iteration-count: infinite;
-webkit-animation-timing-function: linear;
}
.information {
padding: 30px;
text-align: center;
}
.information h3 {
margin-bottom: 20px;
}
</style>
</head>
<body>
<div id="header" class="ship-header">
<div class="background layer"></div>
<div id="ship" class="ship"></div>
<div class="water layer"></div>
</div>
<div class="information">
<img src="{{ config_set['BRANDING']['logo'] or '/static/img/Quay_horizontal_color.svg' }}" style="max-height: 50px;">
{% block content %}
{% endblock %}
</div>
</body>
</html>

View file

@ -0,0 +1,27 @@
<html>
<title>OAuth Access Token · Quay</title>
<head>
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css">
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.no-icons.min.css">
<link href='//fonts.googleapis.com/css?family=Droid+Sans:400,700' rel='stylesheet' type='text/css'>
<script type="text/javascript">
function setToken() {
var hash = document.location.hash.substr(1);
var pairs = hash.split('&');
for (var i = 0; i < pairs.length; ++i) {
var pair = pairs[i];
var kv = pair.split('=');
if (kv[0] == 'access_token') {
document.getElementById('accesstoken').appendChild(document.createTextNode(kv[1]));
}
}
}
</script>
</head>
<body onload="setToken()">
<div class="container" style="margin-top: 20px">
<img src="{{ config_set['BRANDING']['logo'] }}">
<h5>Access Token: <span id="accesstoken"></span></h5>
</div>
</body>
</html>

83
templates/index.html Normal file
View file

@ -0,0 +1,83 @@
{% extends "base.html" %}
{% block title %}
<title ng-bind="title + ' · Quay'">Quay</title>
{% endblock %}
{% block added_meta %}
<base href="/">
<meta id="descriptionTag" name="description" content="Quay is the best place to build, store, and distribute your containers. Public repositories are always free." />
<meta name="google-site-verification" content="GalDznToijTsHYmLjJvE4QaB9uk_IP16aaGDz5D75T4" />
<meta name="google-site-verification" content="oio7ioMILUo9QDflvyFz8pWig1ac2eLq5IGyQuzFMh8" />
{% if aci_conversion %}
<meta name="ac-discovery" content="{{ hostname }} {{ preferred_scheme }}://{{ hostname }}/c1/aci/{name}/{version}/{ext}/{os}/{arch}/">
<meta name="ac-discovery-pubkeys" content="{{ hostname }} {{ preferred_scheme }}://{{ hostname }}/aci-signing-key">
{% endif %}
{% endblock %}
{% block body_content %}
<!-- Note: Must be in the <body> tag -->
<script src="static/standalonelib/jquery.overscroll.min.js"></script>
<div ng-view>
<div class="co-m-loader co-an-fade-in-out loading-js-fade-out">
<div class="co-m-loader-dot__one"></div>
<div class="co-m-loader-dot__two"></div>
<div class="co-m-loader-dot__three"></div>
</div>
<div class="co-alert co-alert-danger loading-js-fade-in">
The Quay application could not be loaded, which typically indicates an external library could not be loaded (usually due to an ad blocker). Please check the JavaScript console for errors.
</div>
</div>
<!-- Modal message dialog -->
<div class="modal fade" id="sessionexpiredModal" data-backdrop="static" style="display: none">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">Session Expired</h4>
</div>
<div class="modal-body">
Your user session has expired. Please <a href="javascript:void(0)" data-dismiss="modal" onclick="location = '/signin'">sign in</a> to continue.
</div>
<div class="modal-footer">
<a href="javascript:void(0)" class="btn btn-primary" data-dismiss="modal" onclick="location = '/signin'">Sign In</a>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
<!-- Modal message dialog -->
<div class="modal fade" id="cannotContactService" data-backdrop="static" style="display: none;">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">Cannot Contact External Service</h4>
</div>
<div class="modal-body">
A connection to an external service has failed. Please reload the page to try again.
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
<!-- Modal message dialog -->
<div class="modal fade" id="readOnlyService" data-backdrop="static" style="display: none;">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
<h4 class="modal-title">Service is currently read-only.</h4>
</div>
<div class="modal-body">
The service is currently in read-only mode. Pulls and other read-only operations
will succeed but all other operations are currently suspended.
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
{% endblock %}

14
templates/message.html Normal file
View file

@ -0,0 +1,14 @@
<html class="{% if onprem %}onprem{% else %}hosted{% endif %}">
<title>Quay</title>
<head>
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css">
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.no-icons.min.css">
<link href='//fonts.googleapis.com/css?family=Droid+Sans:400,700' rel='stylesheet' type='text/css'>
</head>
<body>
<div class="container" style="margin-top: 20px">
<img src="{{ config_set['BRANDING']['logo'] }}">
<h5>{{ message | safe }}</h5>
</div>
</body>
</html>

View file

@ -0,0 +1,31 @@
{% extends "base.html" %}
{% block title %}
<title>Confirm · Quay</title>
{% endblock %}
{% block body_content %}
<style type="text/css">
.captcha-container {
text-align: center;
margin-bottom: 20px;
}
.captcha-container div {
display: inline-block;
}
</style>
<div class="container">
<div class="col-sm-6 col-sm-offset-3">
<form name="continueForm" method="post" action="{{ callback_url }}/captcha">
<div class="captcha-container" vc-recaptcha ng-model="recaptcha_response" key="'{{ recaptcha_site_key }}'"></div>
<input type="hidden" name="recaptcha_response" value="{% raw %}{{ recaptcha_response }}{% endraw %}">
<button id="signupButton"
class="btn btn-primary btn-block" ng-disabled="continueForm.$invalid" type="submit">
Continue
</button>
</form>
</div>
</div>
{% endblock %}

120
templates/oauthorize.html Normal file
View file

@ -0,0 +1,120 @@
{% extends "base.html" %}
{% block title %}
<title>Authorize {{ application.name }} · Quay</title>
{% endblock %}
{% block body_content %}
<div class="container" ng-if="user.anonymous">
<div class="col-sm-6 col-sm-offset-3">
<div class="user-setup"></div>
</div>
</div>
<div class="container auth-container" ng-if="!user.anonymous">
<div class="auth-header">
<span class="avatar" size="48" data="{{ application.avatar }}"></span>
<h2><a href="{{ application.url }}" ng-safenewtab>{{ application.name }}</a></h2>
<h4>
<span class="avatar" size="24" data="{{ application.organization.avatar }}"
style="vertical-align: middle; margin-right: 4px;"></span>
<span style="vertical-align: middle">{{ application.organization.name }}</span>
</h4>
</div>
<div class="auth-scopes">
<div class="reason">This application would like permission to:</div>
<div class="panel-group">
{% for index, scope in enumerate(scopes) %}
<div class="scope panel panel-default {% if scope.dangerous %} dangerous {% endif %}">
<div class="panel-heading">
<h4 class="panel-title">
<div class="title-container">
<div class="title {% if not scope.dangerous %}collapsed{% endif %}" data-toggle="collapse"
data-parent="#scopeGroup" data-target="#description-{{ index }}">
<i class="fa arrow"></i>
<i class="fa {{ scope.icon }} fa-lg"></i>
<a data-toggle="collapse" href="#collapseOne">
{{ scope.title }}
</a>
{% if scope.dangerous %}
<i class="fa fa-lg fa-exclamation-triangle"
data-title="This scope grants permissions which are potentially dangerous. Be careful when authorizing it!"
data-container="body" bs-tooltip></i>
{% endif %}
</div>
</div>
</h4>
</div>
<div id="description-{{ index }}" class="panel-collapse {% if not scope.dangerous %} collapse {% else %} in {% endif %}">
<div class="panel-body">
{% if scope.dangerous %}
<div class="alert alert-warning">This scope grants permissions which are potentially dangerous. Be careful when authorizing it!</div>
{% endif %}
{{ scope.description }}
</div>
</div>
</div>
{% endfor %}
</div>
</div>
<div class="button-bar">
{% if has_dangerous_scopes %}
<button type="button" class="btn btn-warning" onclick="$('#confirmAuthorizeModal').modal()">Authorize Application</button>
{% else %}
<form method="post" action="/oauth/authorizeapp">
<input type="hidden" name="client_id" value="{{ client_id }}">
<input type="hidden" name="redirect_uri" value="{{ redirect_uri }}">
<input type="hidden" name="scope" value="{{ scope }}">
<input type="hidden" name="_csrf_token" value="{{ csrf_token_val }}">
<button type="submit" class="btn btn-success">Authorize Application</button>
</form>
{% endif %}
<form method="post" action="/oauth/denyapp">
<input type="hidden" name="client_id" value="{{ client_id }}">
<input type="hidden" name="redirect_uri" value="{{ redirect_uri }}">
<input type="hidden" name="scope" value="{{ scope }}">
<input type="hidden" name="_csrf_token" value="{{ csrf_token_val }}">
<button type="submit" class="btn btn-default">Cancel</button>
</form>
</div>
</div>
<!-- Modal message dialog -->
<div class="modal fade" id="confirmAuthorizeModal">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">Confirm Authorization</h4>
</div>
<div class="modal-body">
The application <strong>{{ application.name }}</strong> is requesting permission to perform actions which are potentially dangerous.
<br><br>
Are you sure you want to authorize this application?
</div>
<div class="modal-footer">
<form method="post" action="/oauth/authorizeapp" style="display: inline-block">
<input type="hidden" name="client_id" value="{{ client_id }}">
<input type="hidden" name="redirect_uri" value="{{ redirect_uri }}">
<input type="hidden" name="scope" value="{{ scope }}">
<input type="hidden" name="_csrf_token" value="{{ csrf_token_val }}">
<button type="submit" class="btn btn-success">Authorize Application</button>
</form>
<form method="post" action="/oauth/denyapp" style="display: inline-block">
<input type="hidden" name="client_id" value="{{ client_id }}">
<input type="hidden" name="redirect_uri" value="{{ redirect_uri }}">
<input type="hidden" name="scope" value="{{ scope }}">
<input type="hidden" name="_csrf_token" value="{{ csrf_token_val }}">
<button type="submit" class="btn btn-default">Deny</button>
</form>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
{% endblock %}

2
templates/robots.txt Normal file
View file

@ -0,0 +1,2 @@
User-agent: *
Disallow: /

58
templates/sitemap.xml Normal file
View file

@ -0,0 +1,58 @@
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>{{ baseurl }}/</loc>
<changefreq>hourly</changefreq>
<priority>0.8</priority>
</url>
<url>
<loc>{{ baseurl }}/plans/</loc>
<changefreq>monthly</changefreq>
</url>
<url>
<loc>{{ baseurl }}/tour/</loc>
<changefreq>weekly</changefreq>
</url>
<url>
<loc>{{ baseurl }}/tour/organizations</loc>
<changefreq>weekly</changefreq>
</url>
<url>
<loc>{{ baseurl }}/tour/features</loc>
<changefreq>weekly</changefreq>
</url>
<url>
<loc>{{ baseurl }}/tour/enterprise</loc>
<changefreq>weekly</changefreq>
</url>
<url>
<loc>{{ baseurl }}/contact/</loc>
<changefreq>monthly</changefreq>
</url>
<url>
<loc>{{ baseurl }}/about/</loc>
<changefreq>monthly</changefreq>
</url>
<url>
<loc>{{ baseurl }}/security/</loc>
<changefreq>monthly</changefreq>
<priority>0.4</priority>
</url>
<url>
<loc>{{ baseurl }}/tos</loc>
<changefreq>monthly</changefreq>
<priority>0.4</priority>
</url>
<url>
<loc>{{ baseurl }}/privacy</loc>
<changefreq>monthly</changefreq>
<priority>0.4</priority>
</url>
{% for namespace, reponame in public_repos -%}
<url>
<loc>{{ baseurl }}/repository/{{ namespace }}/{{ reponame }}</loc>
<changefreq>daily</changefreq>
<priority>0.3</priority>
</url>
{%- endfor %}
</urlset>