Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: login sso feat: add privacy policy google auth docs:documentation supabase google auth #141

Merged
merged 3 commits into from
Nov 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
NEXT_PUBLIC_SUPABASE_URL=
NEXT_PUBLIC_SUPABASE_ANON_KEY=

API_KEY=
SUPABASE_GOOGLE_AUTH_ID=
SUPABASE_GOOGLE_AUTH_SECRET=
API_KEY=
66 changes: 51 additions & 15 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,33 +46,69 @@ Este mensaje indica que se han añadido instrucciones de instalación local en e

¡Gracias por contribuir! Tu ayuda hace una gran diferencia para el proyecto.

<br/>

## Desarrollo local - levantar db de desarrollo local

### Pre requisitos

- [docker](https://docs.docker.com/engine/install/) y [docker compose](https://docs.docker.com/compose/install/)
- [cli de supabase](https://supabase.com/docs/guides/local-development/cli/getting-started)
- [Docker](https://docs.docker.com/engine/install/) y [Docker Compose](https://docs.docker.com/compose/install/)
- [Supabase CLI](https://supabase.com/docs/guides/local-development/cli/getting-started)

### Instalar self hosted supabase
Si ya tienes cualquiera de los dos, **actualizalos para evitar errores**.

```
Si usas docker desktop en Windows, esta es la configuración que deberías tener.
<img src="https://supabase.com/docs/_next/image?url=%2Fdocs%2Fimg%2Fguides%2Fcli%2Fdocker-win.png&w=3840&q=75&dpl=dpl_EU6MXvnLKJuwyo4VfbBx9GiJt9Qx" style="margin: 10px 0px; width: 55rem;">

### Iniciar supabase en local

Entramos en la carpeta del repositorio

```bash
cd ${DIRECTORIO_DE_EMERGENCY_CV}
supabase login
supabase init
supabase link --project-ref nmvcsenkfqbdlfdtiqdo
```

Iniciamos la base de datos (**tener docker encendido**)

```bash
supabase start
```

### Para hacer cambios en el schema
Si no vemos las tablas ni los datos de ejemplo cargados podemos refrescar la base de datos con:

```bash
supabase db reset
```

### Hacer cambios en el schema

- Editar como queremos que sea en local (studio de supabase)
- Ejecutar el comando:
#### Crear migracion automatica

Nos interesa usar esta opción, cuando queremos **editar la base de datos desde el studio web**

Cuando acabemos de realizar los cambios en el studio web, ejecutaremos el siguiente comando para generar la migration.

```bash
supabase db diff -f nombre_migracion
```
// nombre de la migracion es indicativo, no tiene nigun efecto
supabase db diff -f ${NOMBRE_DE_LA_MIGRACION}

#### Crear migración manual

Nos interesa usar esta opción, cuando queremos **editar la base de datos con codigo SQL manual**.

Primero, creamos la el archivo migration con

```bash
supabase migration new nombre_migracion
```

Se creara un **nuevo fichero** con el nombre que hemos usado **en supabase/migrations**

En ese archivo añadiremos todo el código SQL que necesitemos

Si queremos visualizar nuestros cambios en local, podemos usar

```bash
supabase db reset
```

- Esto generara una migracion en el local, hay que añadir esto al PR y github actions lo pondra en produccion.
<br>
La migration que generemos, la añadiremos en el PR.
4 changes: 1 addition & 3 deletions src/components/UserInfo.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
import Link from 'next/link';
import { LogIn } from 'lucide-react';
import { authService } from '@/lib/service';
import { useSession } from '../context/SessionProvider';

export default function UserProfile() {
const { user } = useSession();
export default function UserProfile({ user }) {
const handleLogout = async () => {
const response = await authService.signOut();
if (!response.error) {
Expand Down
60 changes: 48 additions & 12 deletions src/components/auth/PhoneNumberDialog.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,27 +12,41 @@ import { isValidPhone } from '@/helpers/utils';
const MODAL_NAME = 'phone-number';

const PhoneForm = ({ onSubmit }) => {
const [phoneNumber, setPhoneNumber] = useState('');
const [formData, setFormData] = useState({
phoneNumber: '',
privacyPolicy: '',
});

const handleSubmit = useCallback(
(e) => {
e.preventDefault();

/* Form validation */
if (!isValidPhone(phoneNumber)) {
/* PHONE VALIDATION */
if (!isValidPhone(formData.phoneNumber)) {
alert('El teléfono de contacto no es válido.');
return;
}

const formatedPhoneNumber = formatPhoneNumber(phoneNumber);
onSubmit(formatedPhoneNumber);
setPhoneNumber('');
/* POLICY PRIVACY VALIDATION */
if (!formData.privacyPolicy) {
alert('Para continuar, debes aceptar la Política de Privacidad.');
return;
}

const formatedPhoneNumber = formatPhoneNumber(formData.phoneNumber);

onSubmit(formData.phoneNumber, formData.privacyPolicy);

setFormData({
phoneNumber: '',
privacyPolicy: '',
});
},
[onSubmit, phoneNumber],
[onSubmit, formData],
);

const handleChange = useCallback((phoneNumber) => {
setPhoneNumber(phoneNumber);
setFormData((formData) => ({ ...formData, phoneNumber }))
}, []);

return (
Expand All @@ -51,9 +65,31 @@ const PhoneForm = ({ onSubmit }) => {
Tu número de teléfono no será usado con ningún otro propósito ni compartido con terceras personas.
</p>
</div>
<PhoneInput onChange={handleChange} phoneNumber={phoneNumber} />

{/* PHONE NUMBER */}
<PhoneInput onChange={handleChange} phoneNumber={formData.phoneNumber} />

{/* PRIVACY POLICY */}
<div className="flex gap-2 items-start lg:items-center">
<input
type="checkbox"
value={formData.privacyPolicy}
onChange={(e) => setFormData({ ...formData, privacyPolicy: e.target.checked })}
className="min-w-4 min-h-4 cursor-pointer"
id="privacyPolicy"
required
/>
<label htmlFor="privacyPolicy" className="text-sm font-medium text-gray-700">
He leído y aceptado la{' '}
<a href="/politica-privacidad/" className="text-blue-400">
política de privacidad
</a>{' '}
y acepto que «ajudadana.es» recoja y guarde los datos enviados a través de este formulario.
</label>
</div>

<div className="flex justify-end space-x-2">
{/* ACCEPT AND SAVE */}
<div className="flex justify-end space-x-2 mt-2">
<button
type="submit"
className="px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2"
Expand Down Expand Up @@ -87,15 +123,15 @@ const PhoneNumberDialog = () => {
fetchNumber();
}, []);

const handleSubmit = useCallback(async (phoneNumber) => {
const handleSubmit = useCallback(async (phoneNumber, privacyPolicy) => {
const { data: session, error: errorGettingUser } = await authService.getSessionUser();

if (!session.user || errorGettingUser) {
throw new Error('Error a la hora de obtener el usuario');
}

const metadata = session.user.user_metadata;
const metadataWithPhone = { ...metadata, telefono: phoneNumber };
const metadataWithPhone = { ...metadata, telefono: phoneNumber, privacyPolicy };

const { error: updateUserError } = await authService.updateUser({
data: metadataWithPhone,
Expand Down
21 changes: 17 additions & 4 deletions src/components/layout/Sidebar.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ import {
CarTaxiFront,
} from 'lucide-react';
import UserInfo from '../UserInfo';
import { useSession } from '../../context/SessionProvider';
import { useState, useEffect } from 'react';
import { supabase } from '@/lib/supabase/client';

const menuItems = [
{
Expand Down Expand Up @@ -146,7 +147,19 @@ const menuItems = [
export default function Sidebar({ isOpen, toggle }) {
const router = useRouter();
const pathname = usePathname();
const session = useSession();

const [user, setUser] = useState(null);

useEffect(() => {
const fetchUser = async () => {
const {
data: { user },
} = await supabase.auth.getUser();
setUser(user);
};
fetchUser();
}, []);

return (
<>
{/* Quitamos el overlay con fondo negro */}
Expand Down Expand Up @@ -179,7 +192,7 @@ export default function Sidebar({ isOpen, toggle }) {
<nav className="p-4 flex-1 overflow-y-auto">
<div className="space-y-2">
{menuItems.map((item) =>
(session && session.user && session.user.email && item.isAuth) || !item.isAuth ? (
(user && user.email && item.isAuth) || !item.isAuth ? (
item.isHref ? (
<button
key={item.path}
Expand Down Expand Up @@ -235,7 +248,7 @@ export default function Sidebar({ isOpen, toggle }) {

{/* User info and login */}
<div className="p-4">
<UserInfo />
<UserInfo user={user} />
</div>

{/* Toggle button for desktop */}
Expand Down
8 changes: 4 additions & 4 deletions supabase/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -190,11 +190,11 @@ verify_enabled = true
# Use an external OAuth provider. The full list of providers are: `apple`, `azure`, `bitbucket`,
# `discord`, `facebook`, `github`, `gitlab`, `google`, `keycloak`, `linkedin_oidc`, `notion`, `twitch`,
# `twitter`, `slack`, `spotify`, `workos`, `zoom`.
[auth.external.apple]
enabled = false
client_id = ""
[auth.external.google]
enabled = true
client_id = "env(SUPABASE_GOOGLE_AUTH_ID)"
# DO NOT commit your OAuth provider secret to git. Use environment variable substitution instead:
secret = "env(SUPABASE_AUTH_EXTERNAL_APPLE_SECRET)"
secret = "env(SUPABASE_GOOGLE_AUTH_SECRET)"
# Overrides the default auth redirectUrl.
redirect_uri = ""
# Overrides the default auth provider URL. Used to support self-hosted gitlab, single-tenant Azure,
Expand Down
Loading