diff options
28 files changed, 233 insertions, 89 deletions
@@ -11,6 +11,11 @@ https://quill.p3k.io/ By submitting code to this project, you agree to irrevocably release it under the same license as this project. +### Credits + +Quill icon designed by [http://thenounproject.com/term/quill/17013/ Juan Pablo Bravo from the Noun Project] + + ### License Copyright 2013 by Aaron Parecki diff --git a/composer.json b/composer.json index 76a91ec..c771330 100644 --- a/composer.json +++ b/composer.json @@ -7,6 +7,7 @@ "indieweb/mention-client": "0.*", "indieweb/date-formatter": "0.1.*", "indieauth/client": "0.1.3", - "mpratt/relativetime": ">=1.0" + "mpratt/relativetime": ">=1.0", + "firebase/php-jwt": "dev-master" } } diff --git a/composer.lock b/composer.lock index 4b20a2c..41b6052 100644 --- a/composer.lock +++ b/composer.lock @@ -3,9 +3,53 @@ "This file locks the dependencies of your project to a known state", "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file" ], - "hash": "a734a0ce213069a3ecf69c1d2a32b25f", + "hash": "676692118149f622d7ca2349f775eb8c", "packages": [ { + "name": "firebase/php-jwt", + "version": "dev-master", + "target-dir": "Firebase/PHP-JWT", + "source": { + "type": "git", + "url": "https://github.com/firebase/php-jwt.git", + "reference": "53669d621149e49c2a428722a62acfef3342c260" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/firebase/php-jwt/zipball/53669d621149e49c2a428722a62acfef3342c260", + "reference": "53669d621149e49c2a428722a62acfef3342c260", + "shasum": "" + }, + "require": { + "php": ">=5.2.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "Authentication/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Neuman Vong", + "email": "neuman+pear@twilio.com", + "role": "Developer" + }, + { + "name": "Anant Narayanan", + "email": "anant@php.net", + "role": "Developer" + } + ], + "description": "A simple library to encode and decode JSON Web Tokens (JWT) in PHP. Should conform to the current spec.", + "homepage": "https://github.com/firebase/php-jwt", + "time": "2013-09-03 20:55:18" + }, + { "name": "indieauth/client", "version": "0.1.3", "source": { @@ -410,7 +454,8 @@ ], "minimum-stability": "stable", "stability-flags": { - "saltybeagle/savant3": 20 + "saltybeagle/savant3": 20, + "firebase/php-jwt": 20 }, "platform": [ diff --git a/controllers/auth.php b/controllers/auth.php index 7caaba3..7caddd3 100644 --- a/controllers/auth.php +++ b/controllers/auth.php @@ -67,11 +67,6 @@ $app->get('/', function($format='html') use($app) { $res->body($html); }); -$app->get('/signin', function() use($app) { - $html = render('signin', array('title' => 'Sign In')); - $app->response()->body($html); -}); - $app->get('/auth/start', function() use($app) { $req = $app->request(); diff --git a/controllers/controllers.php b/controllers/controllers.php index 3ff111e..5b28bb8 100644 --- a/controllers/controllers.php +++ b/controllers/controllers.php @@ -63,6 +63,47 @@ $app->get('/docs', function() use($app) { $app->response()->body($html); }); +$app->get('/add-to-home', function() use($app) { + $params = $app->request()->params(); + + if(array_key_exists('token', $params) && !session('add-to-home-started')) { + + // Verify the token and sign the user in + try { + $data = JWT::decode($params['token'], Config::$jwtSecret); + $_SESSION['user_id'] = $data->user_id; + $_SESSION['me'] = $data->me; + $app->redirect('/new', 301); + } catch(DomainException $e) { + header('X-Error: DomainException'); + $app->redirect('/', 301); + } catch(UnexpectedValueException $e) { + header('X-Error: UnexpectedValueException'); + $app->redirect('/', 301); + } + + } else { + + if($user=require_login($app)) { + if(array_key_exists('start', $params)) { + $_SESSION['add-to-home-started'] = true; + + $token = JWT::encode(array( + 'user_id' => $_SESSION['user_id'], + 'me' => $_SESSION['me'], + 'created_at' => time() + ), Config::$jwtSecret); + + $app->redirect('/add-to-home?token='.$token, 301); + } else { + unset($_SESSION['add-to-home-started']); + $html = render('add-to-home', array('title' => 'Quill')); + $app->response()->body($html); + } + } + } +}); + $app->post('/micropub/post', function() use($app) { if($user=require_login($app)) { $params = $app->request()->params(); diff --git a/lib/config.template.php b/lib/config.template.php index 5dd1bf7..f8a1ab2 100644 --- a/lib/config.template.php +++ b/lib/config.template.php @@ -7,5 +7,7 @@ class Config { public static $dbName = 'quill'; public static $dbUsername = 'quill'; public static $dbPassword = ''; + + public static $jwtSecret = 'xxx'; } diff --git a/public/css/style.css b/public/css/style.css index 4f53d68..7872e7e 100644 --- a/public/css/style.css +++ b/public/css/style.css @@ -1,9 +1,23 @@ body { - padding-top: 70px; + padding-top: 10px; +} + +.header { + font-family:; "Helvetica Neue",Helvetica,Arial,sans-serif; + font-size: 22px; + font-weight: 500; + color: #888; + border-bottom: 6px #ddd solid; +} + +.narrow { + max-width: 700px; + margin-right: auto; + margin-left: auto; } .footer { - padding: 40px; + padding: 0; margin-top: 20px; text-align: center; color: #999; @@ -11,6 +25,25 @@ body { border-top: 1px #e5e5e5 solid; } +.footer .nav { + max-width: 700px; + margin-right: auto; + margin-left: auto; +} + +.footer .credits { + padding: 20px; + font-size: 12px; +} + + +.jumbotron .tagline { + font-size: 23px; +} +.jumbotron p { + font-size: 18px; +} + /** * Bootstrap callouts diff --git a/public/images/indiepost-ui.png b/public/images/indiepost-ui.png Binary files differdeleted file mode 100644 index d7a4a2e..0000000 --- a/public/images/indiepost-ui.png +++ /dev/null diff --git a/public/images/quill-icon-114.png b/public/images/quill-icon-114.png Binary files differnew file mode 100644 index 0000000..2ad3540 --- /dev/null +++ b/public/images/quill-icon-114.png diff --git a/public/images/quill-icon-144.png b/public/images/quill-icon-144.png Binary files differnew file mode 100644 index 0000000..6f85b29 --- /dev/null +++ b/public/images/quill-icon-144.png diff --git a/public/images/quill-icon-57.png b/public/images/quill-icon-57.png Binary files differnew file mode 100644 index 0000000..2d4d156 --- /dev/null +++ b/public/images/quill-icon-57.png diff --git a/public/images/quill-icon-72.png b/public/images/quill-icon-72.png Binary files differnew file mode 100644 index 0000000..2329af6 --- /dev/null +++ b/public/images/quill-icon-72.png diff --git a/public/images/quill-icon.psd b/public/images/quill-icon.psd Binary files differnew file mode 100644 index 0000000..22a869d --- /dev/null +++ b/public/images/quill-icon.psd diff --git a/public/images/quill-logo-128.png b/public/images/quill-logo-128.png Binary files differnew file mode 100644 index 0000000..a01e833 --- /dev/null +++ b/public/images/quill-logo-128.png diff --git a/public/images/quill-logo-144.png b/public/images/quill-logo-144.png Binary files differnew file mode 100644 index 0000000..b84866b --- /dev/null +++ b/public/images/quill-logo-144.png diff --git a/public/images/quill-logo.png b/public/images/quill-logo.png Binary files differnew file mode 100644 index 0000000..cafc507 --- /dev/null +++ b/public/images/quill-logo.png diff --git a/public/images/quill-ui.png b/public/images/quill-ui.png Binary files differnew file mode 100644 index 0000000..d7de77a --- /dev/null +++ b/public/images/quill-ui.png diff --git a/views/add-to-home.php b/views/add-to-home.php new file mode 100644 index 0000000..857e959 --- /dev/null +++ b/views/add-to-home.php @@ -0,0 +1,6 @@ +<div class="narrow"> + <?= partial('partials/header') ?> + + <div style="margin: 20px;">Add this page to your home screen!<br /><br />The next time you visit it, you will be signed in.</div> + +</div>
\ No newline at end of file diff --git a/views/auth_callback.php b/views/auth_callback.php index 44c2daa..7274cd7 100644 --- a/views/auth_callback.php +++ b/views/auth_callback.php @@ -1,3 +1,6 @@ +<div class="narrow"> + <?= partial('partials/header') ?> + <?php if($this->tokenEndpoint): ?> <?php if(!$this->auth): ?> @@ -66,3 +69,5 @@ <?php endif; ?> + +</div>
\ No newline at end of file diff --git a/views/auth_error.php b/views/auth_error.php index 818ded4..58728b5 100644 --- a/views/auth_error.php +++ b/views/auth_error.php @@ -1,4 +1,8 @@ -<h2><?= $this->error ?></h2> +<div class="narrow"> + <?= partial('partials/header') ?> -<p><?= $this->errorDescription ?></p> + <h2><?= $this->error ?></h2> + <p><?= $this->errorDescription ?></p> + +<?div>
\ No newline at end of file diff --git a/views/auth_start.php b/views/auth_start.php index 819fd65..70dc83d 100644 --- a/views/auth_start.php +++ b/views/auth_start.php @@ -1,3 +1,6 @@ +<div class="narrow"> + <?= partial('partials/header') ?> + <div id="authorization_endpoint"> <h3>Authorization Endpoint</h3> @@ -52,3 +55,4 @@ <?php endif; ?> +</div>
\ No newline at end of file diff --git a/views/creating-a-micropub-endpoint.php b/views/creating-a-micropub-endpoint.php index 617b52f..d911ce6 100644 --- a/views/creating-a-micropub-endpoint.php +++ b/views/creating-a-micropub-endpoint.php @@ -1,5 +1,8 @@ +<div class="narrow"> + <?= partial('partials/header') ?> + <?php ob_start() ?> -## The Micropub Endpoint +## Creating a Micropub Endpoint After a client has obtained an access token and discovered the user's Micropub endpoint it is ready to make requests to create posts. @@ -88,3 +91,4 @@ and optionally an HTML or other body with more information. Below is a list of p <?= Markdown(ob_get_clean()) ?> +</div>
\ No newline at end of file diff --git a/views/dashboard.php b/views/dashboard.php index 120d0bf..ff3d897 100644 --- a/views/dashboard.php +++ b/views/dashboard.php @@ -1,6 +1,7 @@ + <div class="narrow"> + <?= partial('partials/header') ?> - <div style="max-width: 700px; margin: 0 auto;"> - <form role="form"> + <form role="form" style="margin-top: 20px;"> <div class="form-group"> <label for="note_content"><code>content</code></label> diff --git a/views/docs.php b/views/docs.php index f9d5384..48fd0d8 100644 --- a/views/docs.php +++ b/views/docs.php @@ -1,26 +1,31 @@ -<h2>Introduction</h2> +<div class="narrow"> + <?= partial('partials/header') ?> -<div class="col-xs-6 col-md-4" style="float: right;"> - <span class="thumbnail"><img src="/images/indiepost-ui.png"></span> -</div> + <h2>Introduction</h2> -<p>This is a simple <a href="http://indiewebcamp.com/micropub">Micropub</a> client for - creating text posts on your own website. To use it, you will need to turn your website - into an OAuth provider, and implement a Micropub endpoint that this app will send - requests to.</p> + <div class="col-xs-6 col-md-4" style="float: right;"> + <span class="thumbnail"><img src="/images/quill-ui.png"></span> + </div> -<p>Once you've signed in, you'll see an interface like the one shown which you can use to - write a post. Clicking "post" will make a Micropub request to your endpoint.<p> + <p>This is a simple <a href="http://indiewebcamp.com/micropub">Micropub</a> client for + creating text posts on your own website. To use it, you will need to turn your website + into an OAuth provider, and implement a Micropub endpoint that this app will send + requests to.</p> -<h2>Configuring Endpoints</h2> + <p>Once you've signed in, you'll see an interface like the one shown which you can use to + write a post. Clicking "post" will make a Micropub request to your endpoint.<p> -<h3>Authorization Endpoint</h3> -<?= partial('partials/auth-endpoint-help') ?> + <h2>Configuring Endpoints</h2> -<h3>Token Endpoint</h3> -<?= partial('partials/token-endpoint-help') ?> + <h3>Authorization Endpoint</h3> + <?= partial('partials/auth-endpoint-help') ?> -<h3>Micropub Endpoint</h3> -<?= partial('partials/micropub-endpoint-help') ?> + <h3>Token Endpoint</h3> + <?= partial('partials/token-endpoint-help') ?> -<p>The <a href="/creating-a-micropub-endpoint">Creating a Micropub Endpoint</a> tutorial will walk you through how to handle incoming POST requests from apps like this.</p> + <h3>Micropub Endpoint</h3> + <?= partial('partials/micropub-endpoint-help') ?> + + <p>The <a href="/creating-a-micropub-endpoint">Creating a Micropub Endpoint</a> tutorial will walk you through how to handle incoming POST requests from apps like this.</p> + +</div>
\ No newline at end of file diff --git a/views/index.php b/views/index.php index 9232f8e..f653de7 100644 --- a/views/index.php +++ b/views/index.php @@ -1,9 +1,19 @@ +<div class="narrow"> + <div class="jumbotron"> - <h2>Quill</h2> - <p>How does it work?</p> - <ol> - <li>Sign in with your domain</li> - <li>Post a note!</li> - </ol> - <p><a href="/signin" class="btn btn-primary btn-lg" role="button">Get Started »</a></p> + <h1><img src="/images/quill-logo-144.png" height="72" style="margin-bottom: 13px;">Quill</h1> + + <p class="tagline">Quill is a simple app for posting text notes to your website.</p> + + <p>To use Quill, sign in with your domain. Your website will need to support <a href="http://indiewebcamp.com/micropub">Micropub</a> for creating new posts.</p> + + <form action="/auth/start" method="get" class="form-inline"> + <input type="text" name="me" placeholder="http://me.com" value="" class="form-control"> + <input type="submit" value="Sign In" class="btn btn-primary"> + <input type="hidden" name="client_id" value="https://quill.p3k.io"> + <input type="hidden" name="redirect_uri" value="https://quill.p3k.io/auth/callback"> + </form> + </div> + +</div>
\ No newline at end of file diff --git a/views/layout.php b/views/layout.php index 24f5df3..a70f99a 100644 --- a/views/layout.php +++ b/views/layout.php @@ -12,6 +12,11 @@ <link rel="stylesheet" href="/bootstrap/css/bootstrap-theme.min.css"> <link rel="stylesheet" href="/css/style.css"> + <link rel="apple-touch-icon" sizes="57x57" href="/images/quill-icon-57.png"> + <link rel="apple-touch-icon" sizes="72x72" href="/images/quill-icon-72.png"> + <link rel="apple-touch-icon" sizes="114x114" href="/images/quill-icon-114.png"> + <link rel="apple-touch-icon" sizes="144x144" href="/images/quill-icon-144.png"> + <script src="/js/jquery-1.7.1.min.js"></script> </head> @@ -30,56 +35,40 @@ </script> -<div class="navbar navbar-inverse navbar-fixed-top"> +<div class="page"> + <div class="container"> - <div class="navbar-header"> - <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse"> - <span class="sr-only">Toggle navigation</span> - <span class="icon-bar"></span> - <span class="icon-bar"></span> - <span class="icon-bar"></span> - </button> - <a class="navbar-brand" href="/">Quill</a> - </div> - <div class="navbar-collapse collapse"> + <?= $this->fetch($this->page . '.php') ?> + </div> + + <div class="footer"> + <div class="nav"> <ul class="nav navbar-nav"> + <? if(session('me')) { ?> <li><a href="/new">New Post</a></li> <? } ?> + <li><a href="/docs">Docs</a></li> - <!-- <li><a href="/about">About</a></li> --> - <!-- <li><a href="/contact">Contact</a></li> --> </ul> - <? if(session('me')) { ?> - <ul class="nav navbar-nav navbar-right"> - <li><a href="/user?domain=<?= urlencode(session('me')) ?>"><?= session('me') ?></a></li> + <ul class="nav navbar-nav navbar-right"> + <? if(session('me')) { ?> + <li><a href="/add-to-home?start">Add to Home Screen</a></li> + <li><span class="navbar-text"><?= preg_replace('/https?:\/\//','',session('me')) ?></span></li> <li><a href="/signout">Sign Out</a></li> - </ul> - <? } else if(property_exists($this, 'authorizing')) { ?> - <ul class="nav navbar-right"> + <? } else if(property_exists($this, 'authorizing')) { ?> <li class="navbar-text"><?= $this->authorizing ?></li> - </ul> - <? } else { ?> - <ul class="nav navbar-right" style="font-size: 8pt;"> - <li><a href="https://indieauth.com/setup">What's This?</a></li> - </ul> - <form action="/auth/start" method="get" class="navbar-form navbar-right"> - <input type="text" name="me" placeholder="yourdomain.com" class="form-control" /> - <button type="submit" class="btn">Sign In</button> - <input type="hidden" name="redirect_uri" value="https://<?= $_SERVER['SERVER_NAME'] ?>/indieauth" /> - </form> - <? } ?> - </div> - </div> -</div> - -<div class="page"> + <? } else { ?> + <form action="/auth/start" method="get" class="navbar-form"> + <input type="text" name="me" placeholder="yourdomain.com" class="form-control" /> + <button type="submit" class="btn">Sign In</button> + <input type="hidden" name="redirect_uri" value="https://<?= $_SERVER['SERVER_NAME'] ?>/indieauth" /> + </form> + <? } ?> - <div class="container"> - <?= $this->fetch($this->page . '.php') ?> - </div> + </ul> + </div> - <div class="footer"> <p class="credits">© <?=date('Y')?> by <a href="http://aaronparecki.com">Aaron Parecki</a>. This code is <a href="https://github.com/aaronpk/Quill">open source</a>. Feel free to send a pull request, or <a href="https://github.com/aaronpk/Quill/issues">file an issue</a>.</p> diff --git a/views/partials/header.php b/views/partials/header.php new file mode 100644 index 0000000..ef9f15a --- /dev/null +++ b/views/partials/header.php @@ -0,0 +1,4 @@ +<div class="header"> + <img src="/images/quill-logo.png" width="42" height="42"> + Quill +</div>
\ No newline at end of file diff --git a/views/signin.php b/views/signin.php deleted file mode 100644 index 8e52c92..0000000 --- a/views/signin.php +++ /dev/null @@ -1,10 +0,0 @@ - -<form action="/auth/start" method="get"> - <input type="text" name="me" placeholder="http://me.com" value="" class="form-control"><br> - - <input type="hidden" name="client_id" value="https://quill.p3k.io"> - <input type="hidden" name="redirect_uri" value="https://quill.p3k.io/auth/callback"> - - <input type="submit" value="Sign In" class="btn btn-primary"> -</form> - |