mirror of
https://github.com/Sonny93/my-links.git
synced 2025-12-08 22:53:25 +00:00
feat: add auth via google
This commit is contained in:
@@ -12,3 +12,4 @@ DB_PASSWORD=my-links-pwd
|
||||
DB_DATABASE=my-links
|
||||
GOOGLE_CLIENT_ID=
|
||||
GOOGLE_CLIENT_SECRET=
|
||||
GOOGLE_CLIENT_CALLBACK_URL=http://localhost:3333/auth/callback
|
||||
|
||||
@@ -38,6 +38,7 @@ export default defineConfig({
|
||||
() => import('@adonisjs/lucid/database_provider'),
|
||||
() => import('@adonisjs/auth/auth_provider'),
|
||||
() => import('@adonisjs/inertia/inertia_provider'),
|
||||
() => import('@adonisjs/ally/ally_provider'),
|
||||
],
|
||||
|
||||
/*
|
||||
|
||||
7
app/controllers/apps_controller.ts
Normal file
7
app/controllers/apps_controller.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import type { HttpContext } from '@adonisjs/core/http';
|
||||
|
||||
export default class AppsController {
|
||||
index({ inertia }: HttpContext) {
|
||||
return inertia.render('home');
|
||||
}
|
||||
}
|
||||
56
app/controllers/users_controller.ts
Normal file
56
app/controllers/users_controller.ts
Normal file
@@ -0,0 +1,56 @@
|
||||
import User from '#models/user';
|
||||
import type { HttpContext } from '@adonisjs/core/http';
|
||||
import logger from '@adonisjs/core/services/logger';
|
||||
|
||||
export default class UsersController {
|
||||
private redirectTo = '/';
|
||||
|
||||
google = ({ ally }: HttpContext) => ally.use('google').redirect();
|
||||
|
||||
async callbackAuth({ ally, auth, response, session }: HttpContext) {
|
||||
const google = ally.use('google');
|
||||
if (google.accessDenied()) {
|
||||
// TODO: translate error messages + show them in UI
|
||||
session.flash('flash', 'Access was denied');
|
||||
return response.redirect(this.redirectTo);
|
||||
}
|
||||
|
||||
if (google.stateMisMatch()) {
|
||||
session.flash('flash', 'Request expired. Retry again');
|
||||
return response.redirect(this.redirectTo);
|
||||
}
|
||||
|
||||
if (google.hasError()) {
|
||||
session.flash('flash', google.getError() || 'Something went wrong');
|
||||
return response.redirect(this.redirectTo);
|
||||
}
|
||||
|
||||
const { email, id: providerId, name, nickName, avatarUrl, token } = await google.user();
|
||||
const user = await User.updateOrCreate(
|
||||
{
|
||||
email,
|
||||
},
|
||||
{
|
||||
email,
|
||||
providerId,
|
||||
name,
|
||||
nickName,
|
||||
avatarUrl,
|
||||
token,
|
||||
}
|
||||
);
|
||||
|
||||
await auth.use('web').login(user);
|
||||
session.flash('flash', 'Successfully authenticated');
|
||||
logger.info(`[${user.email}] auth success`);
|
||||
|
||||
response.redirect('/');
|
||||
}
|
||||
|
||||
async logout({ auth, response, session }: HttpContext) {
|
||||
await auth.use('web').logout();
|
||||
session.flash('flash', 'Successfully disconnected');
|
||||
logger.info(`[${auth.user?.email}] disconnected successfully`);
|
||||
response.redirect('/');
|
||||
}
|
||||
}
|
||||
5
app/models/app_base_model.ts
Normal file
5
app/models/app_base_model.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { BaseModel, CamelCaseNamingStrategy } from '@adonisjs/lucid/orm';
|
||||
|
||||
export default class AppBaseModel extends BaseModel {
|
||||
static namingStrategy = new CamelCaseNamingStrategy();
|
||||
}
|
||||
@@ -1,30 +1,53 @@
|
||||
import type { GoogleToken } from '@adonisjs/ally/types';
|
||||
import { beforeCreate, column } from '@adonisjs/lucid/orm';
|
||||
import { DateTime } from 'luxon';
|
||||
import hash from '@adonisjs/core/services/hash';
|
||||
import { compose } from '@adonisjs/core/helpers';
|
||||
import { BaseModel, column } from '@adonisjs/lucid/orm';
|
||||
import { withAuthFinder } from '@adonisjs/auth/mixins/lucid';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
import AppBaseModel from './app_base_model.js';
|
||||
|
||||
const AuthFinder = withAuthFinder(() => hash.use('scrypt'), {
|
||||
uids: ['email'],
|
||||
passwordColumnName: 'password',
|
||||
});
|
||||
export default class User extends AppBaseModel {
|
||||
static selfAssignPrimaryKey = true;
|
||||
|
||||
export default class User extends compose(BaseModel, AuthFinder) {
|
||||
@column({ isPrimary: true })
|
||||
declare id: number;
|
||||
|
||||
@column()
|
||||
declare fullName: string | null;
|
||||
declare id: string; // UUID
|
||||
|
||||
@column()
|
||||
declare email: string;
|
||||
|
||||
@column()
|
||||
declare password: string;
|
||||
declare name: string;
|
||||
|
||||
@column.dateTime({ autoCreate: true })
|
||||
@column({ serializeAs: 'nickName' })
|
||||
declare nickName: string; // public username
|
||||
|
||||
@column({ serializeAs: 'avatarUrl' })
|
||||
declare avatarUrl: string;
|
||||
|
||||
declare isAdmin: boolean;
|
||||
|
||||
@column({ serializeAs: null })
|
||||
declare token: GoogleToken;
|
||||
|
||||
@column({ serializeAs: null })
|
||||
declare providerId: string;
|
||||
|
||||
@column.dateTime({
|
||||
autoCreate: true,
|
||||
serialize: (value: DateTime) => value.toISODate(),
|
||||
serializeAs: 'createdAt',
|
||||
})
|
||||
declare createdAt: DateTime;
|
||||
|
||||
@column.dateTime({ autoCreate: true, autoUpdate: true })
|
||||
declare updatedAt: DateTime | null;
|
||||
@column.dateTime({
|
||||
autoCreate: true,
|
||||
autoUpdate: true,
|
||||
serialize: (value: DateTime) => value.toISODate(),
|
||||
serializeAs: 'updatedAt',
|
||||
})
|
||||
declare updatedAt: DateTime;
|
||||
|
||||
@beforeCreate()
|
||||
static assignUuid(user: User) {
|
||||
user.id = uuidv4();
|
||||
user.isAdmin = false;
|
||||
}
|
||||
}
|
||||
|
||||
19
config/ally.ts
Normal file
19
config/ally.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import env from '#start/env';
|
||||
import { defineConfig, services } from '@adonisjs/ally';
|
||||
|
||||
const allyConfig = defineConfig({
|
||||
google: services.google({
|
||||
clientId: env.get('GOOGLE_CLIENT_ID'),
|
||||
clientSecret: env.get('GOOGLE_CLIENT_SECRET'),
|
||||
callbackUrl: env.get('GOOGLE_CLIENT_CALLBACK_URL'),
|
||||
prompt: 'select_account',
|
||||
display: 'page',
|
||||
scopes: ['userinfo.email', 'userinfo.profile'],
|
||||
}),
|
||||
});
|
||||
|
||||
export default allyConfig;
|
||||
|
||||
declare module '@adonisjs/ally/types' {
|
||||
interface SocialProviders extends InferSocialProviders<typeof allyConfig> {}
|
||||
}
|
||||
@@ -11,6 +11,13 @@ export default defineConfig({
|
||||
*/
|
||||
sharedData: {
|
||||
errors: (ctx) => ctx.session?.flashMessages.get('errors'),
|
||||
auth: async (ctx) => {
|
||||
await ctx.auth.check();
|
||||
return {
|
||||
user: ctx.auth.user,
|
||||
isAuthenticated: ctx.auth.isAuthenticated,
|
||||
};
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
|
||||
@@ -5,10 +5,15 @@ export default class extends BaseSchema {
|
||||
|
||||
async up() {
|
||||
this.schema.createTable(this.tableName, (table) => {
|
||||
table.increments('id').notNullable();
|
||||
table.string('full_name').nullable();
|
||||
table.string('id').notNullable();
|
||||
table.string('email', 254).notNullable().unique();
|
||||
table.string('password').notNullable();
|
||||
table.string('name', 254).notNullable();
|
||||
table.string('nick_name', 254).notNullable();
|
||||
table.text('avatar_url').notNullable();
|
||||
table.boolean('is_admin').defaultTo(0).notNullable();
|
||||
|
||||
table.json('token').notNullable();
|
||||
table.string('provider_id').notNullable();
|
||||
|
||||
table.timestamp('created_at').notNullable();
|
||||
table.timestamp('updated_at').nullable();
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import '../css/app.css';
|
||||
import { hydrateRoot } from 'react-dom/client';
|
||||
import { createInertiaApp } from '@inertiajs/react';
|
||||
/// <reference path="../../adonisrc.ts" />
|
||||
|
||||
import { resolvePageComponent } from '@adonisjs/inertia/helpers';
|
||||
import { createInertiaApp } from '@inertiajs/react';
|
||||
import { hydrateRoot } from 'react-dom/client';
|
||||
import '../css/app.css';
|
||||
|
||||
const appName = import.meta.env.VITE_APP_NAME || 'AdonisJS';
|
||||
|
||||
|
||||
5
inertia/hooks/use_user.tsx
Normal file
5
inertia/hooks/use_user.tsx
Normal file
@@ -0,0 +1,5 @@
|
||||
import { usePage } from '@inertiajs/react';
|
||||
import type { InertiaPage } from '~/types/inertia';
|
||||
|
||||
const useUser = () => usePage<InertiaPage>().props.auth;
|
||||
export default useUser;
|
||||
@@ -1,17 +1,28 @@
|
||||
import { InferPageProps } from '@adonisjs/inertia/types';
|
||||
import { Head } from '@inertiajs/react';
|
||||
import useUser from '~/hooks/use_user';
|
||||
import type AppsController from '../../app/controllers/apps_controller';
|
||||
|
||||
export default function Home(_: InferPageProps<AppsController, 'index'>) {
|
||||
const { isAuthenticated, user } = useUser();
|
||||
|
||||
export default function Home(props: { version: number }) {
|
||||
return (
|
||||
<>
|
||||
<Head title="Homepage" />
|
||||
|
||||
<div className="container">
|
||||
<div className="title">AdonisJS {props.version} x Inertia x React</div>
|
||||
<div className="title">AdonisJS x Inertia x React</div>
|
||||
|
||||
<span>
|
||||
Learn more about AdonisJS and Inertia.js by visiting the{' '}
|
||||
<a href="https://docs.adonisjs.com/guides/inertia">AdonisJS documentation</a>.
|
||||
</span>
|
||||
|
||||
<span>{isAuthenticated ? 'Authenticated' : 'Not authenticated'}</span>
|
||||
<span>
|
||||
{isAuthenticated ? <a href="/auth/logout">Logout</a> : <a href="/auth/login">Login</a>}
|
||||
</span>
|
||||
<pre>{JSON.stringify(user, null, 2)}</pre>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
|
||||
4
inertia/types/app.d.ts
vendored
Normal file
4
inertia/types/app.d.ts
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
import { Serialize } from '@tuyau/utils/types';
|
||||
import type UserModel from '../../app/models/user';
|
||||
|
||||
type User = Serialize<UserModel>;
|
||||
8
inertia/types/inertia.d.ts
vendored
Normal file
8
inertia/types/inertia.d.ts
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
import type { User } from './app';
|
||||
|
||||
export type InertiaPage<T extends Record<string, unknown> = Record<string, unknown>> = T & {
|
||||
auth: {
|
||||
user?: User;
|
||||
isAuthenticated: boolean;
|
||||
};
|
||||
};
|
||||
259
package-lock.json
generated
259
package-lock.json
generated
@@ -9,6 +9,7 @@
|
||||
"version": "0.0.0",
|
||||
"license": "UNLICENSED",
|
||||
"dependencies": {
|
||||
"@adonisjs/ally": "^5.0.2",
|
||||
"@adonisjs/auth": "^9.2.0",
|
||||
"@adonisjs/core": "^6.8.0",
|
||||
"@adonisjs/cors": "^2.2.1",
|
||||
@@ -25,7 +26,8 @@
|
||||
"pg": "^8.11.5",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
"reflect-metadata": "^0.2.2"
|
||||
"reflect-metadata": "^0.2.2",
|
||||
"uuid": "^9.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@adonisjs/assembler": "^7.5.1",
|
||||
@@ -39,6 +41,7 @@
|
||||
"@types/node": "^20.12.7",
|
||||
"@types/react": "^18.3.1",
|
||||
"@types/react-dom": "^18.3.0",
|
||||
"@types/uuid": "^9.0.8",
|
||||
"@vitejs/plugin-react": "^4.2.1",
|
||||
"eslint": "^8.57.0",
|
||||
"hot-hook": "^0.2.1",
|
||||
@@ -70,6 +73,21 @@
|
||||
"node": ">=18.16.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@adonisjs/ally": {
|
||||
"version": "5.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@adonisjs/ally/-/ally-5.0.2.tgz",
|
||||
"integrity": "sha512-/A53dXiFwwwi9SM8U5dIffesCcNbklHqoME8zHYYO4KQ+dzg9CnubBtgcvH1XRJV8v52FgyUnPFFHDd8J3zI9A==",
|
||||
"dependencies": {
|
||||
"@poppinss/oauth-client": "^5.1.2",
|
||||
"@poppinss/utils": "^6.7.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.16.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@adonisjs/core": "^6.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@adonisjs/application": {
|
||||
"version": "8.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@adonisjs/application/-/application-8.2.2.tgz",
|
||||
@@ -436,6 +454,11 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@adonisjs/inertia/node_modules/@tuyau/utils": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@tuyau/utils/-/utils-0.0.1.tgz",
|
||||
"integrity": "sha512-Vi2uT9yuy0jZkaW0c1nMgja266DcIoF+/UK0HGMlTH/FUrmKiQLtu64PKBKZtibkezN4nlw3po4SZKvH37SklA=="
|
||||
},
|
||||
"node_modules/@adonisjs/logger": {
|
||||
"version": "6.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@adonisjs/logger/-/logger-6.0.3.tgz",
|
||||
@@ -2111,6 +2134,18 @@
|
||||
"uid-safe": "2.1.5"
|
||||
}
|
||||
},
|
||||
"node_modules/@poppinss/oauth-client": {
|
||||
"version": "5.1.3",
|
||||
"resolved": "https://registry.npmjs.org/@poppinss/oauth-client/-/oauth-client-5.1.3.tgz",
|
||||
"integrity": "sha512-cjgac/0pwk/J+x1Jei/cAHTzstCuZE7KRfmdVhClb9zMUskw477rZPZ86dg1LBghw+IGaPtnAgmxTV9pNWG9ZQ==",
|
||||
"dependencies": {
|
||||
"@poppinss/utils": "^6.7.3",
|
||||
"got": "^14.2.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.16.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@poppinss/prompts": {
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/@poppinss/prompts/-/prompts-3.1.3.tgz",
|
||||
@@ -2560,6 +2595,17 @@
|
||||
"@swc/counter": "^0.1.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@szmarczak/http-timer": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz",
|
||||
"integrity": "sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==",
|
||||
"dependencies": {
|
||||
"defer-to-connect": "^2.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.16"
|
||||
}
|
||||
},
|
||||
"node_modules/@tokenizer/token": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz",
|
||||
@@ -2601,11 +2647,6 @@
|
||||
"integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@tuyau/utils": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@tuyau/utils/-/utils-0.0.1.tgz",
|
||||
"integrity": "sha512-Vi2uT9yuy0jZkaW0c1nMgja266DcIoF+/UK0HGMlTH/FUrmKiQLtu64PKBKZtibkezN4nlw3po4SZKvH37SklA=="
|
||||
},
|
||||
"node_modules/@types/babel__core": {
|
||||
"version": "7.20.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz",
|
||||
@@ -2668,6 +2709,11 @@
|
||||
"resolved": "https://registry.npmjs.org/@types/he/-/he-1.2.3.tgz",
|
||||
"integrity": "sha512-q67/qwlxblDzEDvzHhVkwc1gzVWxaNxeyHUBF4xElrvjL11O+Ytze+1fGpBHlr/H9myiBUaUXNnNPmBHxxfAcA=="
|
||||
},
|
||||
"node_modules/@types/http-cache-semantics": {
|
||||
"version": "4.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz",
|
||||
"integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA=="
|
||||
},
|
||||
"node_modules/@types/istanbul-lib-coverage": {
|
||||
"version": "2.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz",
|
||||
@@ -2760,6 +2806,12 @@
|
||||
"integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/uuid": {
|
||||
"version": "9.0.8",
|
||||
"resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.8.tgz",
|
||||
"integrity": "sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/validator": {
|
||||
"version": "13.11.9",
|
||||
"resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.11.9.tgz",
|
||||
@@ -3585,6 +3637,42 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/cacheable-lookup": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-7.0.0.tgz",
|
||||
"integrity": "sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==",
|
||||
"engines": {
|
||||
"node": ">=14.16"
|
||||
}
|
||||
},
|
||||
"node_modules/cacheable-request": {
|
||||
"version": "10.2.14",
|
||||
"resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-10.2.14.tgz",
|
||||
"integrity": "sha512-zkDT5WAF4hSSoUgyfg5tFIxz8XQK+25W/TLVojJTMKBaxevLBBtLxgqguAuVQB8PVW79FVjHcU+GJ9tVbDZ9mQ==",
|
||||
"dependencies": {
|
||||
"@types/http-cache-semantics": "^4.0.2",
|
||||
"get-stream": "^6.0.1",
|
||||
"http-cache-semantics": "^4.1.1",
|
||||
"keyv": "^4.5.3",
|
||||
"mimic-response": "^4.0.0",
|
||||
"normalize-url": "^8.0.0",
|
||||
"responselike": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.16"
|
||||
}
|
||||
},
|
||||
"node_modules/cacheable-request/node_modules/get-stream": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz",
|
||||
"integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/call-bind": {
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz",
|
||||
@@ -4272,6 +4360,31 @@
|
||||
"integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/decompress-response": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz",
|
||||
"integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==",
|
||||
"dependencies": {
|
||||
"mimic-response": "^3.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/decompress-response/node_modules/mimic-response": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz",
|
||||
"integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/dedent": {
|
||||
"version": "1.5.3",
|
||||
"resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.3.tgz",
|
||||
@@ -4330,6 +4443,14 @@
|
||||
"node": ">=0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/defer-to-connect": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz",
|
||||
"integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/define-data-property": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
|
||||
@@ -5481,6 +5602,14 @@
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/form-data-encoder": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-4.0.2.tgz",
|
||||
"integrity": "sha512-KQVhvhK8ZkWzxKxOr56CPulAhH3dobtuQ4+hNQ+HekH/Wp5gSOafqRAeTphQUJAIk0GBvHZgJ2ZGRWd5kphMuw==",
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
}
|
||||
},
|
||||
"node_modules/forwarded": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
|
||||
@@ -5636,7 +5765,6 @@
|
||||
"version": "8.0.1",
|
||||
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz",
|
||||
"integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==",
|
||||
"devOptional": true,
|
||||
"engines": {
|
||||
"node": ">=16"
|
||||
},
|
||||
@@ -5789,6 +5917,30 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/got": {
|
||||
"version": "14.2.1",
|
||||
"resolved": "https://registry.npmjs.org/got/-/got-14.2.1.tgz",
|
||||
"integrity": "sha512-KOaPMremmsvx6l9BLC04LYE6ZFW4x7e4HkTe3LwBmtuYYQwpeS4XKqzhubTIkaQ1Nr+eXxeori0zuwupXMovBQ==",
|
||||
"dependencies": {
|
||||
"@sindresorhus/is": "^6.1.0",
|
||||
"@szmarczak/http-timer": "^5.0.1",
|
||||
"cacheable-lookup": "^7.0.0",
|
||||
"cacheable-request": "^10.2.14",
|
||||
"decompress-response": "^6.0.0",
|
||||
"form-data-encoder": "^4.0.2",
|
||||
"get-stream": "^8.0.1",
|
||||
"http2-wrapper": "^2.2.1",
|
||||
"lowercase-keys": "^3.0.0",
|
||||
"p-cancelable": "^4.0.1",
|
||||
"responselike": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sindresorhus/got?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/graceful-fs": {
|
||||
"version": "4.2.11",
|
||||
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
|
||||
@@ -5939,6 +6091,11 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"node_modules/http-cache-semantics": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz",
|
||||
"integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ=="
|
||||
},
|
||||
"node_modules/http-errors": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
|
||||
@@ -5954,6 +6111,18 @@
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/http2-wrapper": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.2.1.tgz",
|
||||
"integrity": "sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==",
|
||||
"dependencies": {
|
||||
"quick-lru": "^5.1.1",
|
||||
"resolve-alpn": "^1.2.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10.19.0"
|
||||
}
|
||||
},
|
||||
"node_modules/human-signals": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz",
|
||||
@@ -6673,8 +6842,7 @@
|
||||
"node_modules/json-buffer": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
|
||||
"integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
|
||||
"dev": true
|
||||
"integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ=="
|
||||
},
|
||||
"node_modules/json-parse-even-better-errors": {
|
||||
"version": "2.3.1",
|
||||
@@ -6767,7 +6935,6 @@
|
||||
"version": "4.5.4",
|
||||
"resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
|
||||
"integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"json-buffer": "3.0.1"
|
||||
}
|
||||
@@ -7029,6 +7196,17 @@
|
||||
"get-func-name": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/lowercase-keys": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz",
|
||||
"integrity": "sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==",
|
||||
"engines": {
|
||||
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/lru-cache": {
|
||||
"version": "10.2.1",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.1.tgz",
|
||||
@@ -7184,6 +7362,17 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/mimic-response": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-4.0.0.tgz",
|
||||
"integrity": "sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==",
|
||||
"engines": {
|
||||
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/min-indent": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz",
|
||||
@@ -7462,6 +7651,14 @@
|
||||
"node": ">= 0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/p-cancelable": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-4.0.1.tgz",
|
||||
"integrity": "sha512-wBowNApzd45EIKdO1LaU+LrMBwAcjfPaYtVzV3lmfM3gf8Z4CHZsiIqlM8TZZ8okYvh5A1cP6gTfCRQtwUpaUg==",
|
||||
"engines": {
|
||||
"node": ">=14.16"
|
||||
}
|
||||
},
|
||||
"node_modules/p-event": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/p-event/-/p-event-6.0.1.tgz",
|
||||
@@ -8150,6 +8347,17 @@
|
||||
"resolved": "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz",
|
||||
"integrity": "sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg=="
|
||||
},
|
||||
"node_modules/quick-lru": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz",
|
||||
"integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/random-bytes": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/random-bytes/-/random-bytes-1.0.0.tgz",
|
||||
@@ -8580,6 +8788,11 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/resolve-alpn": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz",
|
||||
"integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g=="
|
||||
},
|
||||
"node_modules/resolve-from": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
|
||||
@@ -8589,6 +8802,20 @@
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/responselike": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/responselike/-/responselike-3.0.0.tgz",
|
||||
"integrity": "sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==",
|
||||
"dependencies": {
|
||||
"lowercase-keys": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.16"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/restore-cursor": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz",
|
||||
@@ -9909,6 +10136,18 @@
|
||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
|
||||
},
|
||||
"node_modules/uuid": {
|
||||
"version": "9.0.1",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz",
|
||||
"integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==",
|
||||
"funding": [
|
||||
"https://github.com/sponsors/broofa",
|
||||
"https://github.com/sponsors/ctavan"
|
||||
],
|
||||
"bin": {
|
||||
"uuid": "dist/bin/uuid"
|
||||
}
|
||||
},
|
||||
"node_modules/v8-compile-cache-lib": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
"@types/node": "^20.12.7",
|
||||
"@types/react": "^18.3.1",
|
||||
"@types/react-dom": "^18.3.0",
|
||||
"@types/uuid": "^9.0.8",
|
||||
"@vitejs/plugin-react": "^4.2.1",
|
||||
"eslint": "^8.57.0",
|
||||
"hot-hook": "^0.2.1",
|
||||
@@ -53,6 +54,7 @@
|
||||
"vite": "^5.2.10"
|
||||
},
|
||||
"dependencies": {
|
||||
"@adonisjs/ally": "^5.0.2",
|
||||
"@adonisjs/auth": "^9.2.0",
|
||||
"@adonisjs/core": "^6.8.0",
|
||||
"@adonisjs/cors": "^2.2.1",
|
||||
@@ -69,7 +71,8 @@
|
||||
"pg": "^8.11.5",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
"reflect-metadata": "^0.2.2"
|
||||
"reflect-metadata": "^0.2.2",
|
||||
"uuid": "^9.0.1"
|
||||
},
|
||||
"hotHook": {
|
||||
"boundaries": [
|
||||
|
||||
@@ -35,4 +35,13 @@ export default await Env.create(new URL('../', import.meta.url), {
|
||||
DB_USER: Env.schema.string(),
|
||||
DB_PASSWORD: Env.schema.string.optional(),
|
||||
DB_DATABASE: Env.schema.string(),
|
||||
|
||||
/*
|
||||
|----------------------------------------------------------
|
||||
| Variables for configuring ally package
|
||||
|----------------------------------------------------------
|
||||
*/
|
||||
GOOGLE_CLIENT_ID: Env.schema.string(),
|
||||
GOOGLE_CLIENT_SECRET: Env.schema.string(),
|
||||
GOOGLE_CLIENT_CALLBACK_URL: Env.schema.string(),
|
||||
});
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Routes file
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The routes file is used for defining the HTTP routes.
|
||||
|
|
||||
*/
|
||||
|
||||
import router from '@adonisjs/core/services/router';
|
||||
router.on('/inertia').renderInertia('home', { version: 6 });
|
||||
|
||||
const UsersController = () => import('#controllers/users_controller');
|
||||
const AppsController = () => import('#controllers/apps_controller');
|
||||
|
||||
router.get('/', [AppsController, 'index']);
|
||||
|
||||
router.get('/auth/login', [UsersController, 'google']);
|
||||
router.get('/auth/callback', [UsersController, 'callbackAuth']);
|
||||
router.get('/auth/logout', [UsersController, 'logout']);
|
||||
|
||||
Reference in New Issue
Block a user