Skip to content

Commit a322aea

Browse files
committed
feat: auth route
1 parent 272384c commit a322aea

File tree

4 files changed

+166
-0
lines changed

4 files changed

+166
-0
lines changed

src/routes/auth/fetch.js

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*
2+
* Copyright 2025 Adobe. All rights reserved.
3+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License. You may obtain a copy
5+
* of the License at http://www.apache.org/licenses/LICENSE-2.0
6+
*
7+
* Unless required by applicable law or agreed to in writing, software distributed under
8+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9+
* OF ANY KIND, either express or implied. See the License for the specific language
10+
* governing permissions and limitations under the License.
11+
*/
12+
13+
import { assertAuthorization } from '../../utils/auth.js';
14+
import { errorResponse } from '../../utils/http.js';
15+
16+
/**
17+
* @param {Context} ctx
18+
*/
19+
export default async function fetch(ctx) {
20+
const { config } = ctx;
21+
22+
await assertAuthorization(ctx);
23+
24+
const token = await ctx.env.KEYS.get(config.siteKey);
25+
if (!token) {
26+
return errorResponse(404);
27+
}
28+
29+
return new Response(JSON.stringify({ token }), {
30+
headers: {
31+
'Content-Type': 'application/json',
32+
},
33+
});
34+
}

src/routes/auth/handler.js

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*
2+
* Copyright 2025 Adobe. All rights reserved.
3+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License. You may obtain a copy
5+
* of the License at http://www.apache.org/licenses/LICENSE-2.0
6+
*
7+
* Unless required by applicable law or agreed to in writing, software distributed under
8+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9+
* OF ANY KIND, either express or implied. See the License for the specific language
10+
* governing permissions and limitations under the License.
11+
*/
12+
13+
import { errorResponse } from '../../utils/http.js';
14+
import fetch from './fetch.js';
15+
import update from './update.js';
16+
import rotate from './rotate.js';
17+
18+
/**
19+
* @type {Record<string, Record<string, (ctx: Context, req: Request) => Promise<Response>>>}
20+
*/
21+
const handlers = {
22+
token: {
23+
GET: fetch,
24+
PUT: update,
25+
POST: rotate,
26+
},
27+
};
28+
29+
/**
30+
* @param {Context} ctx
31+
* @param {Request} req
32+
* @returns {Promise<Response>}
33+
*/
34+
export default async function handler(ctx, req) {
35+
const {
36+
info: { method },
37+
url: { pathname },
38+
} = ctx;
39+
const [subRoute] = pathname.split('/').filter(Boolean).slice(['org', 'site', 'route'].length);
40+
41+
const fn = handlers[subRoute]?.[method];
42+
if (!fn) {
43+
return errorResponse(404);
44+
}
45+
return fn(ctx, req);
46+
}

src/routes/auth/rotate.js

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*
2+
* Copyright 2025 Adobe. All rights reserved.
3+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License. You may obtain a copy
5+
* of the License at http://www.apache.org/licenses/LICENSE-2.0
6+
*
7+
* Unless required by applicable law or agreed to in writing, software distributed under
8+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9+
* OF ANY KIND, either express or implied. See the License for the specific language
10+
* governing permissions and limitations under the License.
11+
*/
12+
13+
import { assertAuthorization } from '../../utils/auth.js';
14+
import { errorResponse } from '../../utils/http.js';
15+
import { updateToken } from './update.js';
16+
17+
/**
18+
* @param {Context} ctx
19+
*/
20+
export default async function rotate(ctx) {
21+
const { data } = ctx;
22+
if (data.token) {
23+
return errorResponse(400, 'token can not be provided on rotate');
24+
}
25+
26+
await assertAuthorization(ctx);
27+
28+
const token = await updateToken(ctx);
29+
return new Response(JSON.stringify({ token }), {
30+
headers: {
31+
'Content-Type': 'application/json',
32+
},
33+
});
34+
}

src/routes/auth/update.js

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/*
2+
* Copyright 2025 Adobe. All rights reserved.
3+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License. You may obtain a copy
5+
* of the License at http://www.apache.org/licenses/LICENSE-2.0
6+
*
7+
* Unless required by applicable law or agreed to in writing, software distributed under
8+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9+
* OF ANY KIND, either express or implied. See the License for the specific language
10+
* governing permissions and limitations under the License.
11+
*/
12+
13+
import { assertAuthorization } from '../../utils/auth.js';
14+
import { errorResponse, errorWithResponse } from '../../utils/http.js';
15+
16+
const generateToken = () => crypto.randomUUID().toUpperCase();
17+
18+
/**
19+
*
20+
* @param {Context} ctx
21+
* @param {string} [token]
22+
* @returns {Promise<string>}
23+
*/
24+
export async function updateToken(ctx, token = generateToken()) {
25+
const { config } = ctx;
26+
try {
27+
await ctx.env.KEYS.put(config.siteKey, token);
28+
} catch (e) {
29+
ctx.log.error('failed to update token', e);
30+
throw errorWithResponse(500, 'failed to update token');
31+
}
32+
return token;
33+
}
34+
35+
/**
36+
* @param {Context} ctx
37+
*/
38+
export default async function update(ctx) {
39+
const { data } = ctx;
40+
if (!data.token || typeof data.token !== 'string') {
41+
return errorResponse(400, 'missing or invalid token');
42+
}
43+
44+
await assertAuthorization(ctx);
45+
46+
const token = await updateToken(ctx, data.token);
47+
return new Response(JSON.stringify({ token }), {
48+
headers: {
49+
'Content-Type': 'application/json',
50+
},
51+
});
52+
}

0 commit comments

Comments
 (0)