diff --git a/README.md b/README.md index a51239e..87f9e70 100644 --- a/README.md +++ b/README.md @@ -11,8 +11,6 @@ You can post what you're drinking to your own site, or you can post to an accoun ### /auth/start -Copy from Quill. - Discover IndieAuth + Micropub endpoints. #### Authorize diff --git a/controllers/auth.php b/controllers/auth.php index a77f336..d9a6d0e 100644 --- a/controllers/auth.php +++ b/controllers/auth.php @@ -47,8 +47,8 @@ function normalizeMeURL($url) { return false; // Invalid path - if($me['path'] != '/') - return false; + // if($me['path'] != '/') + // return false; // query and fragment not allowed if(array_key_exists('query', $me) || array_key_exists('fragment', $me)) @@ -92,26 +92,27 @@ $app->get('/auth/start', function() use($app) { $tokenEndpoint = IndieAuth\Client::discoverTokenEndpoint($me); $micropubEndpoint = IndieAuth\Client::discoverMicropubEndpoint($me); - if($tokenEndpoint && $micropubEndpoint && $authorizationEndpoint) { - // Generate a "state" parameter for the request - $state = IndieAuth\Client::generateStateParameter(); - $_SESSION['auth_state'] = $state; + // Generate a "state" parameter for the request + $state = IndieAuth\Client::generateStateParameter(); + $_SESSION['auth_state'] = $state; + if($tokenEndpoint && $micropubEndpoint && $authorizationEndpoint) { $scope = 'post'; $authorizationURL = IndieAuth\Client::buildAuthorizationURL($authorizationEndpoint, $me, buildRedirectURI(), clientID(), $state, $scope); } else { - $authorizationURL = false; + $authorizationURL = IndieAuth\Client::buildAuthorizationURL('https://indieauth.com/auth', $me, buildRedirectURI(), clientID(), $state); } // If the user has already signed in before and has a micropub access token, skip // the debugging screens and redirect immediately to the auth endpoint. // This will still generate a new access token when they finish logging in. $user = ORM::for_table('users')->where('url', $me)->find_one(); - if($user && $user->micropub_access_token && !array_key_exists('restart', $params)) { + if($user && $user->access_token && !array_key_exists('restart', $params)) { $user->micropub_endpoint = $micropubEndpoint; $user->authorization_endpoint = $authorizationEndpoint; $user->token_endpoint = $tokenEndpoint; + $user->type = $micropubEndpoint ? 'micropub' : 'local'; $user->save(); $app->redirect($authorizationURL, 301); @@ -125,6 +126,7 @@ $app->get('/auth/start', function() use($app) { $user->micropub_endpoint = $micropubEndpoint; $user->authorization_endpoint = $authorizationEndpoint; $user->token_endpoint = $tokenEndpoint; + $user->type = $micropubEndpoint ? 'micropub' : 'local'; $user->save(); $html = render('auth_start', array( @@ -132,6 +134,7 @@ $app->get('/auth/start', function() use($app) { 'me' => $me, 'authorizing' => $me, 'meParts' => parse_url($me), + 'micropubUser' => $authorizationEndpoint && $tokenEndpoint && $micropubEndpoint, 'tokenEndpoint' => $tokenEndpoint, 'micropubEndpoint' => $micropubEndpoint, 'authorizationEndpoint' => $authorizationEndpoint, @@ -199,48 +202,87 @@ $app->get('/auth/callback', function() use($app) { // An authorization code is in the query string, and we want to exchange that for an access token at the token endpoint. // Discover the endpoints + $authorizationEndpoint = IndieAuth\Client::discoverAuthorizationEndpoint($me); $micropubEndpoint = IndieAuth\Client::discoverMicropubEndpoint($me); $tokenEndpoint = IndieAuth\Client::discoverTokenEndpoint($me); + $redirectToDashboardImmediately = false; + if($tokenEndpoint) { + // Exchange auth code for an access token $token = IndieAuth\Client::getAccessToken($tokenEndpoint, $params['code'], $params['me'], buildRedirectURI(), clientID(), $params['state'], true); + // If a valid access token was returned, store the token info in the session and they are signed in + if(k($token['auth'], array('me','access_token','scope'))) { + $_SESSION['auth'] = $token['auth']; + $_SESSION['me'] = $params['me']; + + // TODO? + // This client requires the "post" scope. + + + // Make a request to the micropub endpoint to discover the syndication targets if any. + // Errors are silently ignored here. The user will be able to retry from the new post interface and get feedback. + // get_syndication_targets($user); + } + } else { - $token = array('auth'=>false, 'response'=>false); - } + // No token endpoint was discovered, instead, verify the auth code at the auth server or with indieauth.com - $redirectToDashboardImmediately = false; + // Never show the intermediate login confirmation page if we just authenticated them instead of got authorization + $redirectToDashboardImmediately = true; - // If a valid access token was returned, store the token info in the session and they are signed in - if(k($token['auth'], array('me','access_token','scope'))) { - $_SESSION['auth'] = $token['auth']; - $_SESSION['me'] = $params['me']; - - $user = ORM::for_table('users')->where('url', $me)->find_one(); - if($user) { - // Already logged in, update the last login date - $user->last_login = date('Y-m-d H:i:s'); - // If they have logged in before and we already have an access token, then redirect to the dashboard now - if($user->micropub_access_token) - $redirectToDashboardImmediately = true; - } else { - // New user! Store the user in the database - $user = ORM::for_table('users')->create(); - $user->url = $me; - $user->date_created = date('Y-m-d H:i:s'); + if(!$authorizationEndpoint) { + $authorizationEndpoint = 'https://indieauth.com/auth'; } - $user->micropub_endpoint = $micropubEndpoint; - $user->access_token = $token['auth']['access_token']; - $user->token_scope = $token['auth']['scope']; - $user->token_response = $token['response']; - $user->save(); - $_SESSION['user_id'] = $user->id(); - // Make a request to the micropub endpoint to discover the syndication targets if any. - // Errors are silently ignored here. The user will be able to retry from the new post interface and get feedback. - get_syndication_targets($user); + $token['auth'] = IndieAuth\Client::verifyIndieAuthCode($authorizationEndpoint, $params['code'], $params['me'], buildRedirectURI(), clientID(), $params['state']); + + if(k($token['auth'], 'me')) { + $token['response'] = ''; // hack becuase the verify call doesn't actually return the real response + $token['auth']['scope'] = ''; + $token['auth']['access_token'] = ''; + $_SESSION['auth'] = $token['auth']; + $_SESSION['me'] = $params['me']; + } } + + // Verify the login actually succeeded + if(!array_key_exists('me', $_SESSION)) { + $html = render('auth_error', array( + 'title' => 'Sign-In Failed', + 'error' => 'Unable to verify the sign-in attempt', + 'errorDescription' => '' + )); + $app->response()->body($html); + return; + } + + + $user = ORM::for_table('users')->where('url', $me)->find_one(); + if($user) { + // Already logged in, update the last login date + $user->last_login = date('Y-m-d H:i:s'); + // If they have logged in before and we already have an access token, then redirect to the dashboard now + if($user->access_token) + $redirectToDashboardImmediately = true; + } else { + // New user! Store the user in the database + $user = ORM::for_table('users')->create(); + $user->url = $me; + $user->date_created = date('Y-m-d H:i:s'); + $user->last_login = date('Y-m-d H:i:s'); + } + $user->micropub_endpoint = $micropubEndpoint; + $user->access_token = $token['auth']['access_token']; + $user->token_scope = $token['auth']['scope']; + $user->token_response = $token['response']; + $user->save(); + $_SESSION['user_id'] = $user->id(); + + + unset($_SESSION['auth_state']); if($redirectToDashboardImmediately) { diff --git a/controllers/controllers.php b/controllers/controllers.php index c2110a3..844c6eb 100644 --- a/controllers/controllers.php +++ b/controllers/controllers.php @@ -52,8 +52,8 @@ $app->get('/new', function() use($app) { $html = render('new-post', array( 'title' => 'New Post', 'micropub_endpoint' => $user->micropub_endpoint, - 'micropub_scope' => $user->micropub_scope, - 'micropub_access_token' => $user->micropub_access_token, + 'token_scope' => $user->token_scope, + 'access_token' => $user->access_token, 'response_date' => $user->last_micropub_response_date, 'syndication_targets' => json_decode($user->syndication_targets, true), 'test_response' => $test_response, diff --git a/public/bootstrap/css/bootstrap-theme.css b/public/bootstrap/css/bootstrap-theme.css index a406992..ed8e66f 100644 --- a/public/bootstrap/css/bootstrap-theme.css +++ b/public/bootstrap/css/bootstrap-theme.css @@ -211,39 +211,7 @@ .navbar-fixed-bottom { border-radius: 0; } -.alert { - text-shadow: 0 1px 0 rgba(255, 255, 255, .2); - -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 1px 2px rgba(0, 0, 0, .05); - box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 1px 2px rgba(0, 0, 0, .05); -} -.alert-success { - background-image: -webkit-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%); - background-image: linear-gradient(to bottom, #dff0d8 0%, #c8e5bc 100%); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0); - background-repeat: repeat-x; - border-color: #b2dba1; -} -.alert-info { - background-image: -webkit-linear-gradient(top, #d9edf7 0%, #b9def0 100%); - background-image: linear-gradient(to bottom, #d9edf7 0%, #b9def0 100%); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0); - background-repeat: repeat-x; - border-color: #9acfea; -} -.alert-warning { - background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%); - background-image: linear-gradient(to bottom, #fcf8e3 0%, #f8efc0 100%); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0); - background-repeat: repeat-x; - border-color: #f5e79e; -} -.alert-danger { - background-image: -webkit-linear-gradient(top, #f2dede 0%, #e7c3c3 100%); - background-image: linear-gradient(to bottom, #f2dede 0%, #e7c3c3 100%); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0); - background-repeat: repeat-x; - border-color: #dca7a7; -} + .progress { background-image: -webkit-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%); background-image: linear-gradient(to bottom, #ebebeb 0%, #f5f5f5 100%); diff --git a/public/bootstrap/css/bootstrap-theme.min.css b/public/bootstrap/css/bootstrap-theme.min.css deleted file mode 100644 index ba4bd28..0000000 --- a/public/bootstrap/css/bootstrap-theme.min.css +++ /dev/null @@ -1,7 +0,0 @@ -/*! - * Bootstrap v3.1.1 (http://getbootstrap.com) - * Copyright 2011-2014 Twitter, Inc. - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - */ - -.btn-default,.btn-primary,.btn-success,.btn-info,.btn-warning,.btn-danger{text-shadow:0 -1px 0 rgba(0,0,0,.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075)}.btn-default:active,.btn-primary:active,.btn-success:active,.btn-info:active,.btn-warning:active,.btn-danger:active,.btn-default.active,.btn-primary.active,.btn-success.active,.btn-info.active,.btn-warning.active,.btn-danger.active{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn:active,.btn.active{background-image:none}.btn-default{background-image:-webkit-linear-gradient(top,#fff 0,#e0e0e0 100%);background-image:linear-gradient(to bottom,#fff 0,#e0e0e0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#dbdbdb;text-shadow:0 1px 0 #fff;border-color:#ccc}.btn-default:hover,.btn-default:focus{background-color:#e0e0e0;background-position:0 -15px}.btn-default:active,.btn-default.active{background-color:#e0e0e0;border-color:#dbdbdb}.btn-primary{background-image:-webkit-linear-gradient(top,#428bca 0,#2d6ca2 100%);background-image:linear-gradient(to bottom,#428bca 0,#2d6ca2 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff2d6ca2', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#2b669a}.btn-primary:hover,.btn-primary:focus{background-color:#2d6ca2;background-position:0 -15px}.btn-primary:active,.btn-primary.active{background-color:#2d6ca2;border-color:#2b669a}.btn-success{background-image:-webkit-linear-gradient(top,#5cb85c 0,#419641 100%);background-image:linear-gradient(to bottom,#5cb85c 0,#419641 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#3e8f3e}.btn-success:hover,.btn-success:focus{background-color:#419641;background-position:0 -15px}.btn-success:active,.btn-success.active{background-color:#419641;border-color:#3e8f3e}.btn-info{background-image:-webkit-linear-gradient(top,#5bc0de 0,#2aabd2 100%);background-image:linear-gradient(to bottom,#5bc0de 0,#2aabd2 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#28a4c9}.btn-info:hover,.btn-info:focus{background-color:#2aabd2;background-position:0 -15px}.btn-info:active,.btn-info.active{background-color:#2aabd2;border-color:#28a4c9}.btn-warning{background-image:-webkit-linear-gradient(top,#f0ad4e 0,#eb9316 100%);background-image:linear-gradient(to bottom,#f0ad4e 0,#eb9316 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#e38d13}.btn-warning:hover,.btn-warning:focus{background-color:#eb9316;background-position:0 -15px}.btn-warning:active,.btn-warning.active{background-color:#eb9316;border-color:#e38d13}.btn-danger{background-image:-webkit-linear-gradient(top,#d9534f 0,#c12e2a 100%);background-image:linear-gradient(to bottom,#d9534f 0,#c12e2a 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#b92c28}.btn-danger:hover,.btn-danger:focus{background-color:#c12e2a;background-position:0 -15px}.btn-danger:active,.btn-danger.active{background-color:#c12e2a;border-color:#b92c28}.thumbnail,.img-thumbnail{-webkit-box-shadow:0 1px 2px rgba(0,0,0,.075);box-shadow:0 1px 2px rgba(0,0,0,.075)}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus{background-image:-webkit-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);background-color:#e8e8e8}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{background-image:-webkit-linear-gradient(top,#428bca 0,#357ebd 100%);background-image:linear-gradient(to bottom,#428bca 0,#357ebd 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff357ebd', GradientType=0);background-color:#357ebd}.navbar-default{background-image:-webkit-linear-gradient(top,#fff 0,#f8f8f8 100%);background-image:linear-gradient(to bottom,#fff 0,#f8f8f8 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);border-radius:4px;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 5px rgba(0,0,0,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 5px rgba(0,0,0,.075)}.navbar-default .navbar-nav>.active>a{background-image:-webkit-linear-gradient(top,#ebebeb 0,#f3f3f3 100%);background-image:linear-gradient(to bottom,#ebebeb 0,#f3f3f3 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff3f3f3', GradientType=0);-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,.075);box-shadow:inset 0 3px 9px rgba(0,0,0,.075)}.navbar-brand,.navbar-nav>li>a{text-shadow:0 1px 0 rgba(255,255,255,.25)}.navbar-inverse{background-image:-webkit-linear-gradient(top,#3c3c3c 0,#222 100%);background-image:linear-gradient(to bottom,#3c3c3c 0,#222 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.navbar-inverse .navbar-nav>.active>a{background-image:-webkit-linear-gradient(top,#222 0,#282828 100%);background-image:linear-gradient(to bottom,#222 0,#282828 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff222222', endColorstr='#ff282828', GradientType=0);-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,.25);box-shadow:inset 0 3px 9px rgba(0,0,0,.25)}.navbar-inverse .navbar-brand,.navbar-inverse .navbar-nav>li>a{text-shadow:0 -1px 0 rgba(0,0,0,.25)}.navbar-static-top,.navbar-fixed-top,.navbar-fixed-bottom{border-radius:0}.alert{text-shadow:0 1px 0 rgba(255,255,255,.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 2px rgba(0,0,0,.05);box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 2px rgba(0,0,0,.05)}.alert-success{background-image:-webkit-linear-gradient(top,#dff0d8 0,#c8e5bc 100%);background-image:linear-gradient(to bottom,#dff0d8 0,#c8e5bc 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0);border-color:#b2dba1}.alert-info{background-image:-webkit-linear-gradient(top,#d9edf7 0,#b9def0 100%);background-image:linear-gradient(to bottom,#d9edf7 0,#b9def0 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0);border-color:#9acfea}.alert-warning{background-image:-webkit-linear-gradient(top,#fcf8e3 0,#f8efc0 100%);background-image:linear-gradient(to bottom,#fcf8e3 0,#f8efc0 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0);border-color:#f5e79e}.alert-danger{background-image:-webkit-linear-gradient(top,#f2dede 0,#e7c3c3 100%);background-image:linear-gradient(to bottom,#f2dede 0,#e7c3c3 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0);border-color:#dca7a7}.progress{background-image:-webkit-linear-gradient(top,#ebebeb 0,#f5f5f5 100%);background-image:linear-gradient(to bottom,#ebebeb 0,#f5f5f5 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0)}.progress-bar{background-image:-webkit-linear-gradient(top,#428bca 0,#3071a9 100%);background-image:linear-gradient(to bottom,#428bca 0,#3071a9 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff3071a9', GradientType=0)}.progress-bar-success{background-image:-webkit-linear-gradient(top,#5cb85c 0,#449d44 100%);background-image:linear-gradient(to bottom,#5cb85c 0,#449d44 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0)}.progress-bar-info{background-image:-webkit-linear-gradient(top,#5bc0de 0,#31b0d5 100%);background-image:linear-gradient(to bottom,#5bc0de 0,#31b0d5 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0)}.progress-bar-warning{background-image:-webkit-linear-gradient(top,#f0ad4e 0,#ec971f 100%);background-image:linear-gradient(to bottom,#f0ad4e 0,#ec971f 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0)}.progress-bar-danger{background-image:-webkit-linear-gradient(top,#d9534f 0,#c9302c 100%);background-image:linear-gradient(to bottom,#d9534f 0,#c9302c 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0)}.list-group{border-radius:4px;-webkit-box-shadow:0 1px 2px rgba(0,0,0,.075);box-shadow:0 1px 2px rgba(0,0,0,.075)}.list-group-item.active,.list-group-item.active:hover,.list-group-item.active:focus{text-shadow:0 -1px 0 #3071a9;background-image:-webkit-linear-gradient(top,#428bca 0,#3278b3 100%);background-image:linear-gradient(to bottom,#428bca 0,#3278b3 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff3278b3', GradientType=0);border-color:#3278b3}.panel{-webkit-box-shadow:0 1px 2px rgba(0,0,0,.05);box-shadow:0 1px 2px rgba(0,0,0,.05)}.panel-default>.panel-heading{background-image:-webkit-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0)}.panel-primary>.panel-heading{background-image:-webkit-linear-gradient(top,#428bca 0,#357ebd 100%);background-image:linear-gradient(to bottom,#428bca 0,#357ebd 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff357ebd', GradientType=0)}.panel-success>.panel-heading{background-image:-webkit-linear-gradient(top,#dff0d8 0,#d0e9c6 100%);background-image:linear-gradient(to bottom,#dff0d8 0,#d0e9c6 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0)}.panel-info>.panel-heading{background-image:-webkit-linear-gradient(top,#d9edf7 0,#c4e3f3 100%);background-image:linear-gradient(to bottom,#d9edf7 0,#c4e3f3 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0)}.panel-warning>.panel-heading{background-image:-webkit-linear-gradient(top,#fcf8e3 0,#faf2cc 100%);background-image:linear-gradient(to bottom,#fcf8e3 0,#faf2cc 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0)}.panel-danger>.panel-heading{background-image:-webkit-linear-gradient(top,#f2dede 0,#ebcccc 100%);background-image:linear-gradient(to bottom,#f2dede 0,#ebcccc 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0)}.well{background-image:-webkit-linear-gradient(top,#e8e8e8 0,#f5f5f5 100%);background-image:linear-gradient(to bottom,#e8e8e8 0,#f5f5f5 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);border-color:#dcdcdc;-webkit-box-shadow:inset 0 1px 3px rgba(0,0,0,.05),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 3px rgba(0,0,0,.05),0 1px 0 rgba(255,255,255,.1)} \ No newline at end of file diff --git a/views/auth_error.php b/views/auth_error.php new file mode 100644 index 0000000..b1db246 --- /dev/null +++ b/views/auth_error.php @@ -0,0 +1,8 @@ +
+ + +

error ?>

+ +

errorDescription ?>

+ +
\ No newline at end of file diff --git a/views/auth_start.php b/views/auth_start.php index 8635f07..23425c4 100644 --- a/views/auth_start.php +++ b/views/auth_start.php @@ -1,58 +1,32 @@
-
-

Authorization Endpoint

+ micropubUser): ?> -

The authorization endpoint tells this app where to direct your browser to sign you in.

+

Awesome! We found your Micropub endpoint!

- authorizationEndpoint): ?> -
Found your authorization endpoint: authorizationEndpoint ?>
- -
Could not find your authorization endpoint!
-

You need to set your authorization endpoint in a <link> tag on your home page.

- - -
- -
-

Token Endpoint

+
+ Click below to authorize this app to create posts at your Micropub endpoint. +
-

The token endpoint is where this app will make a request to get an access token after obtaining authorization.

- - tokenEndpoint): ?> -
Found your token endpoint: tokenEndpoint ?>
-
Could not find your token endpoint!
-

You need to set your token endpoint in a <link> tag on your home page.

- - -
+

Would you like to use a hosted account?

-
-

Micropub Endpoint

+
+ It looks like your site doesn't support Micropub. + You can still use this site to track what you drink, and the posts will live here instead of on your own site. +
-

The Micropub endpoint is the URL this app will use to post new photos.

- - micropubEndpoint): ?> -
Found your Micropub endpoint: micropubEndpoint ?>
- -
Could not find your Micropub endpoint!
-

You need to set your Micropub endpoint in a <link> tag on your home page.

- -
- -authorizationURL): ?> - -

Ready!

- -

Clicking the button below will take you to your authorization server which is where you will allow this app to be able to post to your site.

+ micropubUser ? 'Authorize' : 'Sign In' ?> - Authorize - +
+ Your authorization endpoint: authorizationEndpoint ?: 'none' ?>
+ Your token endpoint: tokenEndpoint ?: 'none' ?>
+ Your Micropub endpoint: micropubEndpoint ?: 'none' ?> +
\ No newline at end of file diff --git a/views/docs.php b/views/docs.php index 94856a1..92998bd 100644 --- a/views/docs.php +++ b/views/docs.php @@ -4,7 +4,7 @@

Introduction

- +

This is a simple Micropub client for @@ -20,41 +20,17 @@

Configuring Endpoints

Authorization Endpoint

+

The authorization endpoint tells this app where to direct your browser to sign you in.

Token Endpoint

+

The token endpoint is where this app will make a request to get an access token after obtaining authorization.

Micropub Endpoint

+

The Micropub endpoint is the URL this app will use to post new photos.

The Creating a Micropub Endpoint tutorial will walk you through how to handle incoming POST requests from apps like this.

- - -

Syndication Targets

- -

You can provide a list of supported syndication targets that will appear as checkboxes when you are creating a new post.

- -

To do this, your Micropub endpoint will need to respond to a GET request containing a query string of q=syndicate-to. This request will be made with the access token that was generated for this app, so you can choose which syndication targets you want to allow this app to use.

- -

Below is the request and expected response that Quill looks for.

- -
GET /micropub?q=syndicate-to HTTP/1.1
-Authorization: Bearer xxxxxxxxxx
-
-HTTP/1.1 200 OK
-Content-type: application/x-www-form-urlencoded
-
-syndicate-to=syndicate-to=twitter.com%2Faaronpk%2Cfacebook.com%2Faaronpk
-
- -

The response should be a form-encoded reply with a single field, syndicate-to. The value is a comma-separated list of syndication targets. The actual values are up to your Micropub endpoint, but a good convention is to use the domain name of the service (e.g. twitter.com), or domain name and username (e.g. twitter.com/aaronpk).

- -

If you do include the domain name, Quill will be able to show icons for recognized services next to the checkboxes.

- -

Quill will check for your supported syndication targets when you sign in, but there is also a link on the new post screen to manually re-check if you'd like.

- - - \ No newline at end of file diff --git a/views/layout.php b/views/layout.php index c6c3a19..f7453d2 100644 --- a/views/layout.php +++ b/views/layout.php @@ -17,7 +17,7 @@ - + diff --git a/views/new-post.php b/views/new-post.php index fa7b9bc..01304fb 100644 --- a/views/new-post.php +++ b/views/new-post.php @@ -84,7 +84,7 @@ scope - micropub_scope ?> (should be a space-separated list of permissions including "post") + token_scope ?> (should be a space-separated list of permissions including "post") micropub endpoint @@ -92,7 +92,7 @@ access token - String of length micropub_access_token) ?>micropub_access_token) > 0) ? (', ending in ' . substr($this->micropub_access_token, -7) . '') : '' ?> (should be greater than length 0) + String of length access_token) ?>access_token) > 0) ? (', ending in ' . substr($this->access_token, -7) . '') : '' ?> (should be greater than length 0)