Skip to content

Commit 3be32fb

Browse files
committed
update auth api
1 parent 79e54db commit 3be32fb

File tree

2 files changed

+103
-203
lines changed

2 files changed

+103
-203
lines changed

includes/API/Auth.php

Lines changed: 57 additions & 150 deletions
Original file line numberDiff line numberDiff line change
@@ -10,193 +10,100 @@
1010

1111
namespace WCPOS\WooCommercePOS\API;
1212

13-
use WP_Error;
13+
use const WCPOS\WooCommercePOS\SHORT_NAME;
14+
use WP_REST_Controller;
1415
use WP_REST_Request;
1516
use WP_REST_Response;
1617
use WP_REST_Server;
17-
use WP_REST_Controller;
18-
use WCPOS\WooCommercePOS\Services\Auth as AuthService;
19-
use const WCPOS\WooCommercePOS\SHORT_NAME;
2018

21-
/**
22-
*
23-
*/
2419
class Auth extends WP_REST_Controller {
25-
/**
26-
* Endpoint namespace.
27-
*
28-
* @var string
29-
*/
20+
/**
21+
* Endpoint namespace.
22+
*
23+
* @var string
24+
*/
3025
protected $namespace = SHORT_NAME . '/v1';
3126

3227
/**
3328
* Route base.
3429
*
3530
* @var string
3631
*/
37-
protected $rest_base = 'jwt';
32+
protected $rest_base = 'auth';
3833

3934
/**
4035
* Stores constructor.
4136
*/
4237
public function __construct() {
4338
}
4439

45-
/**
46-
*
47-
*/
4840
public function register_routes(): void {
49-
// Generate JWT token
41+
// Test authorization method support (public endpoint)
5042
register_rest_route(
5143
$this->namespace,
52-
'/' . $this->rest_base . '/authorize',
44+
'/' . $this->rest_base . '/test',
5345
array(
5446
'methods' => WP_REST_Server::READABLE,
55-
'callback' => array( $this, 'generate_token' ),
56-
'permission_callback' => function ( WP_REST_Request $request ) {
57-
// special case for user=demo param
58-
if ( $request->get_param( 'user' ) === 'demo' ) {
59-
return true;
60-
}
61-
62-
$authorization = $request->get_header( 'authorization' );
63-
64-
return ! is_null( $authorization );
65-
},
66-
)
67-
);
68-
69-
// Validate JWT token
70-
register_rest_route(
71-
$this->namespace,
72-
'/' . $this->rest_base . '/validate',
73-
array(
74-
'methods' => WP_REST_Server::CREATABLE,
75-
'callback' => array( $this, 'validate_token' ),
76-
'permission_callback' => '__return_true',
77-
'args' => array(
78-
'jwt' => array(
79-
'description' => __( 'JWT token.', 'woocommerce-pos' ),
80-
'type' => 'string',
81-
),
82-
),
83-
)
84-
);
85-
86-
// Refresh JWT token
87-
register_rest_route(
88-
$this->namespace,
89-
'/' . $this->rest_base . '/refresh',
90-
array(
91-
'methods' => WP_REST_Server::CREATABLE,
92-
'callback' => array( $this, 'refresh_token' ),
93-
'permission_callback' => '__return_true',
94-
'args' => array(
95-
'jwt' => array(
96-
'description' => __( 'JWT token.', 'woocommerce-pos' ),
97-
'type' => 'string',
98-
),
99-
),
100-
)
101-
);
102-
103-
// Revoke JWT token
104-
register_rest_route(
105-
$this->namespace,
106-
'/' . $this->rest_base . '/revoke',
107-
array(
108-
'methods' => WP_REST_Server::CREATABLE,
109-
'callback' => array( $this, 'revoke_token' ),
110-
'permission_callback' => '__return_true',
111-
'args' => array(
112-
'jwt' => array(
113-
'description' => __( 'JWT token.', 'woocommerce-pos' ),
114-
'type' => 'string',
115-
),
116-
),
47+
'callback' => array( $this, 'test_authorization' ),
48+
'permission_callback' => '__return_true', // Public endpoint - no authentication required
11749
)
11850
);
11951
}
12052

12153

12254
/**
123-
* Get the user and password in the request body and generate a JWT.
55+
* Test authorization method endpoint.
12456
*
125-
* @NOTE - not allowing REST Auth at the moment
57+
* This public endpoint tests whether the server supports Authorization headers
58+
* or requires query parameters for authorization. This is important because
59+
* some servers block Authorization headers for security reasons.
12660
*
127-
* @param WP_REST_Request $request
128-
* @return WP_Error|WP_REST_Response
61+
* @param WP_REST_Request $request The REST request object.
62+
*
63+
* @return WP_REST_Response
12964
*/
130-
public function generate_token( WP_REST_Request $request ) {
131-
$token = str_replace( 'Basic ', '', $request->get_header( 'authorization' ) );
132-
$decoded = base64_decode( $token, true );
133-
list($username, $password) = explode( ':', $decoded );
134-
135-
/** Try to authenticate the user with the passed credentials*/
136-
$user = wp_authenticate( $username, $password );
137-
138-
// If the authentication fails return an error
139-
if ( is_wp_error( $user ) ) {
140-
$error_code = $user->get_error_code();
141-
142-
$user_data = new WP_Error(
143-
'woocommerce_pos_' . $error_code,
144-
$user->get_error_message( $error_code ),
145-
array(
146-
'status' => 403,
147-
)
148-
);
149-
} else {
150-
$auth_service = AuthService::instance();
151-
$user_data = $auth_service->get_user_data( $user );
152-
$stores = array_map(
153-
function ( $store ) {
154-
return $store->get_data();
155-
},
156-
wcpos_get_stores()
157-
);
158-
$user_data['stores'] = $stores;
65+
public function test_authorization( WP_REST_Request $request ): WP_REST_Response {
66+
// Check for Authorization header
67+
$header_auth = $request->get_header( 'authorization' );
68+
$has_header_auth = ! empty( $header_auth );
69+
70+
// Check for authorization query parameter
71+
$param_auth = $request->get_param( 'authorization' );
72+
$has_param_auth = ! empty( $param_auth );
73+
74+
// Only return success if we received authorization via at least one method
75+
if ( ! $has_header_auth && ! $has_param_auth ) {
76+
return rest_ensure_response( array(
77+
'status' => 'error',
78+
'message' => 'No authorization token detected',
79+
) );
15980
}
16081

161-
/**
162-
* Let the user modify the data before sending it back
163-
*
164-
* @param {object} $data
165-
* @param {WP_User} $user
166-
*
167-
* @returns {object} Response data
168-
*
169-
* @since 1.0.0
170-
*
171-
* @hook woocommerce_pos_jwt_auth_token_before_dispatch
172-
*/
173-
$user_data = apply_filters( 'woocommerce_pos_jwt_auth_token_before_dispatch', $user_data, $user );
174-
175-
return rest_ensure_response( $user_data );
176-
}
82+
$response_data = array(
83+
'status' => 'success',
84+
'message' => 'Authorization token detected successfully',
85+
);
17786

178-
/**
179-
* Validate JWT Token.
180-
*
181-
* @param WP_REST_Request $request
182-
* @return WP_REST_Response
183-
*/
184-
public function validate_token( WP_REST_Request $request ): WP_REST_Response {
185-
$token = $request->get_param( 'jwt' );
186-
$auth_service = AuthService::instance();
187-
$result = $auth_service->validate_token( $token );
188-
return rest_ensure_response( $result );
189-
}
87+
// Add authorization details
88+
$response_data['received_header_auth'] = $has_header_auth;
89+
if ( $has_header_auth ) {
90+
$response_data['header_value'] = $header_auth;
91+
}
19092

191-
/**
192-
* Refresh JWT Token.
193-
*/
194-
public function refresh_token(): void {
195-
}
93+
$response_data['received_param_auth'] = $has_param_auth;
94+
if ( $has_param_auth ) {
95+
$response_data['param_value'] = $param_auth;
96+
}
19697

197-
/**
198-
* Revoke JWT Token.
199-
*/
200-
public function revoke_token(): void {
98+
// Indicate which method was used
99+
if ( $has_header_auth && $has_param_auth ) {
100+
$response_data['auth_method'] = 'both';
101+
} elseif ( $has_header_auth ) {
102+
$response_data['auth_method'] = 'header';
103+
} else {
104+
$response_data['auth_method'] = 'param';
105+
}
106+
107+
return rest_ensure_response( $response_data );
201108
}
202109
}

includes/Templates/Frontend.php

Lines changed: 46 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
namespace WCPOS\WooCommercePOS\Templates;
99

1010
use Ramsey\Uuid\Uuid;
11+
use WCPOS\WooCommercePOS\Admin\Permalink;
1112
use const WCPOS\WooCommercePOS\PLUGIN_URL;
1213
use WCPOS\WooCommercePOS\Services\Auth;
1314
use const WCPOS\WooCommercePOS\SHORT_NAME;
@@ -83,11 +84,14 @@ public function head(): void {
8384
* Output the footer scripts.
8485
*/
8586
public function footer(): void {
86-
$development = isset( $_ENV['DEVELOPMENT'] ) && $_ENV['DEVELOPMENT'];
87-
$user = wp_get_current_user();
88-
$github_url = 'https://cdn.jsdelivr.net/gh/wcpos/web-bundle@1.8/';
89-
$auth_service = Auth::instance();
90-
$stores = array_map(
87+
$development = isset( $_ENV['DEVELOPMENT'] ) && $_ENV['DEVELOPMENT'];
88+
$user = wp_get_current_user();
89+
$cdn_base_url = $development ? 'http://localhost:4567/build/' : 'https://cdn.jsdelivr.net/gh/wcpos/web-bundle@1.8/build/';
90+
$wcpos_permalink_slug = Permalink::get_slug();
91+
$wcpos_permalink_slug = empty( $wcpos_permalink_slug ) ? 'pos' : $wcpos_permalink_slug;
92+
$wcpos_permalink_slug = '/' . ltrim( $wcpos_permalink_slug, '/' );
93+
$auth_service = Auth::instance();
94+
$stores = array_map(
9195
function ( $store ) {
9296
return $store->get_data();
9397
},
@@ -108,7 +112,7 @@ function ( $store ) {
108112

109113
$vars = array(
110114
'version' => VERSION,
111-
'manifest' => $github_url . 'metadata.json',
115+
'manifest' => $cdn_base_url . 'metadata.json',
112116
'homepage' => woocommerce_pos_url(),
113117
'logout_url' => $this->pos_logout_url(),
114118
'site' => array(
@@ -145,7 +149,6 @@ function ( $store ) {
145149
*/
146150
$vars = apply_filters( 'woocommerce_pos_inline_vars', $vars );
147151
$initial_props = wp_json_encode( $vars );
148-
$dev_bundle = site_url( '/entry.bundle?platform=web&dev=true&hot=false&transform.routerRoot=app' );
149152

150153
/**
151154
* Add path to worker scripts.
@@ -183,53 +186,43 @@ function loadCSS(source, callback) {
183186
184187
var idbWorker = '{$idbWorker}';
185188
var initialProps = {$initial_props};
189+
var cdnBaseUrl = '{$cdn_base_url}';
190+
var baseUrl = '{$wcpos_permalink_slug}';
186191
</script>" . "\n";
187-
188-
// The actual app bundle
189-
if ( $development ) {
190-
// Development Mode
191-
echo "<script>
192-
getScript('{$dev_bundle}', function() {
193-
console.log('Development JavaScript bundle loaded');
194-
});
195-
</script>" . "\n";
196-
} else {
197-
// Production Mode
198-
echo "<script>
199-
var request = new Request(initialProps.manifest);
200-
201-
window.fetch(request)
202-
.then(function(response) { return response.json(); })
203-
.then(function(data) {
204-
var baseUrl = '{$github_url}';
205-
var bundle = data.fileMetadata.web.bundle;
206-
var bundleUrl = baseUrl + bundle;
207-
208-
// Check if CSS file is specified in the manifest
209-
if (data.fileMetadata.web.css) {
210-
var cssFile = data.fileMetadata.web.css;
211-
var cssUrl = baseUrl + cssFile;
212-
213-
// Load CSS first
214-
loadCSS(cssUrl, function() {
215-
console.log('CSS loaded');
216-
// Load JavaScript after CSS is loaded
217-
getScript(bundleUrl, function() {
218-
console.log('JavaScript bundle loaded');
219-
});
220-
});
221-
} else {
222-
// If no CSS file, load JavaScript immediately
223-
getScript(bundleUrl, function() {
224-
console.log('JavaScript bundle loaded');
225-
});
226-
}
227-
})
228-
.catch(function(error) {
229-
console.error('Error fetching manifest:', error);
230-
});
231-
</script>" . "\n";
232-
}
192+
193+
echo "<script>
194+
var request = new Request(initialProps.manifest);
195+
196+
window.fetch(request)
197+
.then(function(response) { return response.json(); })
198+
.then(function(data) {
199+
var bundle = data.fileMetadata.web.bundle;
200+
var bundleUrl = cdnBaseUrl + bundle;
201+
202+
// Check if CSS file is specified in the manifest
203+
if (data.fileMetadata.web.css) {
204+
var cssFile = data.fileMetadata.web.css;
205+
var cssUrl = cdnBaseUrl + cssFile;
206+
207+
// Load CSS first
208+
loadCSS(cssUrl, function() {
209+
console.log('CSS loaded');
210+
// Load JavaScript after CSS is loaded
211+
getScript(bundleUrl, function() {
212+
console.log('JavaScript bundle loaded');
213+
});
214+
});
215+
} else {
216+
// If no CSS file, load JavaScript immediately
217+
getScript(bundleUrl, function() {
218+
console.log('JavaScript bundle loaded');
219+
});
220+
}
221+
})
222+
.catch(function(error) {
223+
console.error('Error fetching manifest:', error);
224+
});
225+
</script>" . "\n";
233226
}
234227

235228
private function pos_logout_url() {

0 commit comments

Comments
 (0)