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 @@ +
= $this->errorDescription ?>
+ +The token endpoint is where this app will make a request to get an access token after obtaining authorization.
- - tokenEndpoint): ?> -= $this->tokenEndpoint ?>
You need to set your token endpoint in a <link>
tag on your home page.
The Micropub endpoint is the URL this app will use to post new photos.
- - micropubEndpoint): ?> -= $this->micropubEndpoint ?>
You need to set your Micropub endpoint in a <link>
tag on your home page.
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.
+ = $this->micropubUser ? 'Authorize' : 'Sign In' ?> - Authorize - += $this->authorizationEndpoint ?: 'none' ?>
= $this->tokenEndpoint ?: 'none' ?>
= $this->micropubEndpoint ?: 'none' ?>
+ This is a simple Micropub client for @@ -20,41 +20,17 @@
The authorization endpoint tells this app where to direct your browser to sign you in.
= partial('partials/auth-endpoint-help') ?>The token endpoint is where this app will make a request to get an access token after obtaining authorization.
= partial('partials/token-endpoint-help') ?>The Micropub endpoint is the URL this app will use to post new photos.
= partial('partials/micropub-endpoint-help') ?>The Creating a Micropub Endpoint tutorial will walk you through how to handle incoming POST requests from apps like this.
- - -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 @@= $this->micropub_scope ?>
(should be a space-separated list of permissions including "post")= $this->token_scope ?>
(should be a space-separated list of permissions including "post")' . substr($this->micropub_access_token, -7) . '
') : '' ?> (should be greater than length 0)' . substr($this->access_token, -7) . '
') : '' ?> (should be greater than length 0)