Skip to content

Commit

Permalink
feat(worker): ✨ user operations
Browse files Browse the repository at this point in the history
  • Loading branch information
willin committed Dec 28, 2023
1 parent 639ab4e commit 7cf7133
Show file tree
Hide file tree
Showing 11 changed files with 141 additions and 13 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ Free IDaas And Single Sign-On Service
- `/api/users` GET
- `/api/users/:id` GET/PUT/POST
- `/api/users/:id/forbidden` PUT/POST
- `/api/users/:id/:provider` DELETE

## 赞助 Sponsor

Expand Down
47 changes: 47 additions & 0 deletions apps/sso/src/routes/api/users.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { zBodyValidator } from '@hono-dev/zod-body-validator';
import { Hono } from 'hono';
// import { cache } from 'hono/cache';
import { z } from 'zod';
import { AvailableProviders } from '../../config';
import { guard } from '../../middleware/guard';
import { PaginationQuerySchema } from '../../types';

Expand Down Expand Up @@ -55,4 +56,50 @@ router.on(
}
);

router.on(
['POST', 'PUT'],
'/users/:id',
guard(),
zBodyValidator(
z.object({
username: z.string(),
display_name: z.string(),
avatar: z.string()
})
),
async (c) => {
const s = c.get('services');
const viewer = c.get('viewer');
const id = c.req.param('id');
if (viewer.type !== 'admin' && viewer.id !== id) {
return c.json({ error: 'forbidden' }, 403);
}
const body = c.req.valid('form');
const result = await s.user.updateUser(id, body);
return c.json({ result });
}
);

router.delete(
'/users/:id/:provider',
guard(),
zValidator(
'param',
z.object({
id: z.string(),
provider: z.enum(AvailableProviders)
})
),
async (c) => {
const s = c.get('services');
const { id, provider } = c.req.valid('param');
const viewer = c.get('viewer');
if (viewer.type !== 'admin' && viewer.id !== id) {
return c.json({ error: 'forbidden' }, 403);
}
const result = await s.user.unbindThirdUser(id, provider);
return c.json({ result });
}
);

export { router };
2 changes: 1 addition & 1 deletion apps/sso/src/routes/auth/afdian.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ router.get('/afdian/*', async (c) => {
// Bind thid login method to the user
if (!bindedUid) {
await s.user.bindThirdUser(viewer.id, 'afdian', formattedUser);
return c.redirect('/dashboard');
return callbackOrBindRedirect(c, '/dashboard');
}
}
// Register the user
Expand Down
2 changes: 1 addition & 1 deletion apps/sso/src/routes/auth/alipay.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ router.get('/alipay/*', async (c) => {
// Bind thid login method to the user
if (!bindedUid) {
await s.user.bindThirdUser(viewer.id, 'alipay', formattedUser);
return c.redirect('/dashboard');
return callbackOrBindRedirect(c, '/dashboard');
}
}
// Register the user
Expand Down
2 changes: 1 addition & 1 deletion apps/sso/src/routes/auth/github.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ router.get('/github/*', async (c) => {
// Bind thid login method to the user
if (!bindedUid) {
await s.user.bindThirdUser(viewer.id, 'github', formattedUser);
return c.redirect('/dashboard');
return callbackOrBindRedirect(c, '/dashboard');
}
}
// Register the user
Expand Down
4 changes: 3 additions & 1 deletion apps/website/src/app.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ import type { App as Apps, User, ThirdUser } from '$lib/types';
declare global {
namespace App {
// interface Error {}
// interface Locals {}
interface Locals {
user: User & { thirdparty: ThirdUser[] };
}
interface PageData {
user: User & { thirdparty: ThirdUser[] };
apps: Apps[];
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import type { Actions } from './$types';

export const actions: Actions = {
save: async ({ request, fetch }) => {
const form = await request.formData();
const body = Object.fromEntries(form.entries());
const { id, ...rest } = body;
const res = await fetch(`/api/users/${id}`, {
method: 'PUT',
body: JSON.stringify(rest),
headers: {
'content-type': 'application/json'
}
});
const result = await res.json();
return result;
},
unbind: async ({ request, fetch }) => {
const form = await request.formData();
const body = Object.fromEntries(form.entries());
const res = await fetch(`/api/users/${body.id}/${body.provider}`, {
method: 'DELETE',
body: JSON.stringify({}),
headers: {
'content-type': 'application/json'
}
});
const result = await res.json();
return result;
}
};
21 changes: 14 additions & 7 deletions apps/website/src/routes/[[lang=locale]]/dashboard/me/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,17 @@
loading = false;
};
}
function confirmOperation(e: Event) {
if (!confirm($t('common.confirm'))) {
e.preventDefault();
return false;
}
}
</script>

<form action="?/save" method="POST" use:enhance={handleSubmit}>
<input type='hidden' name='id' value={$page.data.user.id} />
<div class="form-control w-full my-2">
<label class="label">
<span class="label-text">{$t('user.username')}</span>
Expand Down Expand Up @@ -86,8 +94,10 @@
<p>{$t('common.created_at')}: {thirdUser.created_at}</p>
<div class='card-actions justify-end'>
<form action="?/unbind" method="POST" use:enhance={handleSubmit}>
<input type='hidden' name='id' value={$page.data.user.id} />
<div class='form-control w-full my-2'>
<button type='submit' name='provider' value={thirdUser.provider} class='btn btn-primary'
<button type='submit' name='provider' value={thirdUser.provider} class='btn btn-secondary'
on:click={confirmOperation}
disabled={loading ||$page.data.user?.thirdparty?.length === 1}
class:btn-disabled={loading ||$page.data.user?.thirdparty?.length === 1}
>
Expand All @@ -110,14 +120,11 @@
<div class='card-body'>
<h2 class='card-title capitalize'>{getProviderName(provider)}</h2>
<div class='card-actions justify-end'>
<form action="?/bind" method="POST" use:enhance={handleSubmit}>
<form>
<div class='form-control w-full my-2'>
<button type='submit' name='provider' value={provider} class='btn btn-primary'
disabled={loading}
class:btn-disabled={loading}
>
<a class='btn btn-primary' href={`/auth/${provider}?returnTo=${$page.url.pathname}`}>
{$t('user.bind')}
</button>
</a>
</div>
</form>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,12 @@
<td>
<div class="avatar">
<div class="w-8 rounded">
<img src={user.avatar} alt={user.displayName} />
<img src={user.avatar} alt={user.display_name} />
</div>
</div>
</td>
<td>{user.username}</td>
<td>{user.displayName}</td>
<td>{user.display_name}</td>
<td>{$t(`user.${user.type}`)}</td>
<td>{user.created_at}</td>
<td>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import type { Actions } from './$types';

export const actions: Actions = {
save: async ({ request, fetch, params }) => {
const form = await request.formData();
const body = Object.fromEntries(form.entries());
const res = await fetch(`/api/users/${params.id}`, {
method: 'PUT',
body: JSON.stringify(body),
headers: {
'content-type': 'application/json'
}
});
const result = await res.json();
return result;
},
unbind: async ({ request, fetch, params }) => {
const form = await request.formData();
const body = Object.fromEntries(form.entries());
console.log(body);
const res = await fetch(`/api/users/${params.id}/${body.provider}`, {
method: 'DELETE',
body: JSON.stringify({}),
headers: {
'content-type': 'application/json'
}
});
const result = await res.json();
console.log(JSON.stringify(result, null, 2));
return result;
}
};
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,13 @@
loading = false;
};
}
function confirmOperation(e: Event) {
if (!confirm($t('common.confirm'))) {
e.preventDefault();
return false;
}
}
</script>

<form action="?/save" method="POST" use:enhance={handleSubmit}>
Expand Down Expand Up @@ -90,6 +97,7 @@
<form action="?/unbind" method="POST" use:enhance={handleSubmit}>
<div class='form-control w-full my-2'>
<button type='submit' name='provider' value={thirdUser.provider} class='btn btn-primary'
onclick={confirmOperation}
disabled={loading ||$page.data.user?.thirdparty?.length === 1}
class:btn-disabled={loading ||$page.data.user?.thirdparty?.length === 1}
>
Expand Down

0 comments on commit 7cf7133

Please sign in to comment.