Skip to content

Commit

Permalink
Add sign in admin key and google
Browse files Browse the repository at this point in the history
  • Loading branch information
yunusefendi52 committed May 1, 2024
1 parent f6e3340 commit 0731611
Show file tree
Hide file tree
Showing 6 changed files with 95 additions and 74 deletions.
45 changes: 18 additions & 27 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,42 +1,33 @@
# Nuxt 3 Minimal Starter
## DistApp

Look at the [Nuxt 3 documentation](https://nuxt.com/docs/getting-started/introduction) to learn more.
Distribute Android and iOS app. Alternative App Center Distribution with option to self-hosted your self

## Setup

Make sure to install the dependencies:
#### Ensure you have the required .env

```bash
# yarn
yarn install

# npm
npm install

# pnpm
pnpm install
NUXT_DB_URL=
NUXT_DB_AUTH_TOKEN=
NUXT_S3_ENDPOINT=
NUXT_S3_ACCESS_KEY_ID=
NUXT_S3_SECRET_ACCESS_KEY=
NUXT_JWT_KEY=
NUXT_SIGNIN_KEY=
NUXT_GOOGLE_CLIENT_ID=
NUXT_GOOGLE_CLIENT_SECRET=
NUXT_ADMIN_KEY_KEY=
NUXT_PUBLIC_ADMIN_KEY_ENABLE=
```

## Development Server

Start the development server on `http://localhost:3000`
#### Make sure to install the dependencies:

```bash
npm run dev
ban install
```

## Production

Build the application for production:
#### Development Server

```bash
npm run build
bun run dev
```

Locally preview production build:

```bash
npm run preview
```

Check out the [deployment documentation](https://nuxt.com/docs/getting-started/deployment) for more information.
9 changes: 7 additions & 2 deletions nuxt.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,18 @@ export default defineNuxtConfig({
S3_ENDPOINT: '',
S3_ACCESS_KEY_ID: '',
S3_SECRET_ACCESS_KEY: '',
SIGNIN_KEY: '',
adminKey: {
key: '' // generate using openssl
},
google: {
clientSecret: '',
clientId: '761350052674-43tvrv0e5jqrls4tkheobnfpba0006o1.apps.googleusercontent.com',
clientId: '',
redirectUrl: '/api/auth/callback',
},
public: {
adminKey: {
enable: true,
},
},
},
nitro: {
Expand Down
41 changes: 29 additions & 12 deletions pages/signin.vue
Original file line number Diff line number Diff line change
@@ -1,19 +1,24 @@
<template>
<!-- <form @submit.prevent="signin">
<div class="flex flex-column gap-3">
<h4>Sign In</h4>
<InputText v-model="key" />
<Button type="submit" :loading="isPending" label="Sign In"></Button>
</div>
</form> -->
<form method="get" action="/api/auth/signin-google">
<input type="hidden" name="host" :value="host">
<Button label="Sign In with Google" type="submit" />
</form>
<div class="flex flex-column gap-4 login-container m-4">
<h4 class="text-center">DistApp</h4>
<form @submit.prevent="signin" v-if="adminKeyEnabled">
<div class="flex flex-column gap-2">
<InputText v-model="key" placeholder="Login Key" type="password" />
<Button type="submit" :loading="isPending" label="Sign In"></Button>
</div>
</form>
<form method="get" action="/api/auth/signin-google">
<input type="hidden" name="host" :value="host">
<Button icon="pi pi-google" label="Sign In with Google" type="submit" class="w-full" />
</form>
</div>
</template>

<script setup lang="ts">
const config = useRuntimeConfig()
const adminKeyEnabled = ref(config.public.adminKey.enable)
definePageMeta({
layout: 'auth-layout',
})
Expand Down Expand Up @@ -45,4 +50,16 @@ const host = ref('')
if (process.client) {
host.value = window.location.origin
}
</script>
</script>

<style scoped>
.login-container {
width: 100%;
}
@media only screen and (min-width: 600px) {
.login-container {
width: 320px;
}
}
</style>
55 changes: 37 additions & 18 deletions server/api/auth/callback.get.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,41 @@ import { users } from '~/server/db/schema'

const alg = 'HS256'

export const generateUserToken = async (
event: H3Event<EventHandlerRequest>,
signInProvider: string,
userId: string,
userEmail: string,
userRealName: string,
) => {
userId = `${signInProvider}-${userId}`
const token = await new jose.SignJWT({
sub: userId,
'email': userEmail,
'provider': signInProvider,
}).setProtectedHeader({ alg })
.setIssuedAt()
.sign(getJwtKey(event))
const db = event.context.drizzle
await db.insert(users).values({
name: userRealName,
id: userId,
}).onConflictDoNothing()
return {
token,
}
}

export const signInUser = (
event: H3Event<EventHandlerRequest>,
token: string) => {
setCookie(event, 'app-auth', token, {
httpOnly: false,
secure: true,
sameSite: 'lax',
})
}

export default defineEventHandler(async (event) => {
const query = getQuery(event)
const state = query.state?.toString()!
Expand Down Expand Up @@ -56,24 +91,8 @@ export default defineEventHandler(async (event) => {
setResponseStatus(event, 401, 'User does not have user id or email')
return
}
userId = `${signInProvider}-${userId}`
const token = await new jose.SignJWT({
sub: userId,
'email': userEmail,
'provider': signInProvider,
}).setProtectedHeader({ alg })
.setIssuedAt()
.sign(getJwtKey(event))
setCookie(event, 'app-auth', token, {
httpOnly: false,
secure: true,
sameSite: 'lax',
})
const db = event.context.drizzle
await db.insert(users).values({
name: userRealName,
id: userId,
}).onConflictDoNothing()
const { token } = await generateUserToken(event, signInProvider, userId, userEmail, userRealName)
signInUser(event, token)
await sendRedirect(event, '/')
})

Expand Down
1 change: 0 additions & 1 deletion server/api/auth/signin-google.get.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { Auth } from 'googleapis'
import * as jose from 'jose'
import { createGoogleOAuth } from '~/server/utils/utils'

const alg = 'HS256'

Expand Down
18 changes: 4 additions & 14 deletions server/api/auth/signin.post.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,15 @@
import { getJwtKey } from '~/server/utils/utils'
import * as jose from 'jose'

import { generateUserToken, signInUser } from './callback.get'
const alg = 'HS256'

export default defineEventHandler(async (event) => {
const { key } = await readBody(event)
const config = useRuntimeConfig(event)
if (key !== config.SIGNIN_KEY) { // for testing only
if (key !== config.adminKey.key) {
return setResponseStatus(event, 401)
}

const token = await new jose.SignJWT({
sub: 'b287aa5d85a040f78aa53a2ff7d53023',
}).setProtectedHeader({ alg })
.setIssuedAt()
.sign(getJwtKey(event))
setCookie(event, 'app-auth', token, {
httpOnly: false,
secure: true,
sameSite: 'lax',
})
const { token } = await generateUserToken(event, 'admin', '8ba3c4aa500f4c1e8ba84991960454c4', '[email protected]', 'Admin')
signInUser(event, token)
return {
ok: true,
}
Expand Down

0 comments on commit 0731611

Please sign in to comment.