Initial commit: OAuth IAM Laravel application
Laravel-based OAuth/IAM service with Passport, Vue 3 frontend, and Docker Compose setup for local and production deployment. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
209
resources/js/i18n/ca.ts
Normal file
209
resources/js/i18n/ca.ts
Normal file
@@ -0,0 +1,209 @@
|
||||
import type { MessageSchema } from './es';
|
||||
|
||||
const ca: MessageSchema = {
|
||||
nav: {
|
||||
dashboard: 'Tauler',
|
||||
clients: 'Clients OAuth',
|
||||
tokens: 'Personal Access Tokens',
|
||||
authorizedApps: 'Apps autoritzades',
|
||||
users: 'Usuaris',
|
||||
analytics: 'Analítiques',
|
||||
apiDocs: 'API Docs',
|
||||
logout: 'Sortir',
|
||||
},
|
||||
common: {
|
||||
loading: 'Carregant…',
|
||||
creating: 'Creant…',
|
||||
create: 'Crear',
|
||||
save: 'Desar',
|
||||
cancel: 'Cancel·lar',
|
||||
close: 'Tancar',
|
||||
edit: 'Editar',
|
||||
delete: 'Esborrar',
|
||||
none: '(cap)',
|
||||
},
|
||||
login: {
|
||||
title: 'Entrar',
|
||||
subtitle: "Servidor OAuth2 — tauler d'administració.",
|
||||
email: 'Email',
|
||||
password: 'Contrasenya',
|
||||
submit: 'Entrar',
|
||||
submitting: 'Entrant…',
|
||||
noAccount: 'No tens compte?',
|
||||
signUp: "Registra't",
|
||||
invalidCredentials: 'Credencials no vàlides.',
|
||||
},
|
||||
register: {
|
||||
title: 'Crear compte',
|
||||
name: 'Nom',
|
||||
email: 'Email',
|
||||
password: 'Contrasenya',
|
||||
passwordConfirm: 'Confirmar contrasenya',
|
||||
submit: 'Crear compte',
|
||||
submitFirstUser: 'Crear compte d\'administrador',
|
||||
submitting: 'Creant…',
|
||||
haveAccount: 'Ja tens compte?',
|
||||
signIn: 'Entra',
|
||||
firstUserBanner: 'Encara no hi ha cap usuari. Aquest compte quedarà com a administrador, amb accés immediat (sense aprovació).',
|
||||
pendingTitle: 'Compte creat',
|
||||
pendingBody: "Un administrador ha d'aprovar el teu compte abans que puguis entrar. És possible que t'avisin fora de l'app quan estigui llest.",
|
||||
backToLogin: 'Tornar a entrar',
|
||||
},
|
||||
dashboard: {
|
||||
greeting: 'Hola, {name}',
|
||||
subtitle: "Aquest és el tauler d'administració del servidor OAuth2.",
|
||||
clientsTitle: 'Clients OAuth',
|
||||
clientsDesc: 'Registra apps (Authorization Code+PKCE, Client Credentials o Password Grant).',
|
||||
tokensTitle: 'Personal Access Tokens',
|
||||
tokensDesc: "Genera tokens d'accés directe a l'API, com API keys.",
|
||||
appsTitle: 'Apps autoritzades',
|
||||
appsDesc: 'Apps de tercers a les quals has donat accés al teu compte.',
|
||||
usersTitle: 'Usuaris',
|
||||
usersDesc: 'Alta, edició de rol/estat i baixa de comptes (només admins).',
|
||||
analyticsTitle: 'Analítiques',
|
||||
analyticsDesc: 'Sessions actives, logins per app i usuaris més actius (només admins).',
|
||||
apiTitle: 'API REST',
|
||||
apiDesc: 'Aquest servidor exposa el recurs {resource} (scopes {read}/{write}) perquè aplicacions de tercers gestionin usuaris via OAuth2. Requereix un access token de Passport. Documentació interactiva a {link}.',
|
||||
},
|
||||
clients: {
|
||||
title: 'Clients OAuth',
|
||||
subtitle: 'Apps registrades que poden demanar tokens a aquest servidor.',
|
||||
secretWarning: 'Desa aquest client secret ara, no el podràs tornar a veure:',
|
||||
clientIdLabel: 'client_id:',
|
||||
clientSecretLabel: 'client_secret:',
|
||||
newClient: 'Nou client',
|
||||
name: 'Nom',
|
||||
grantType: 'Grant type',
|
||||
grantAuthCode: 'Authorization Code + PKCE',
|
||||
grantClientCredentials: 'Client Credentials',
|
||||
grantPassword: 'Password Grant',
|
||||
redirectUris: 'Redirect URIs (separades per coma)',
|
||||
confidentialLabel: "Client confidencial (amb secret). Desmarca-ho per a un client públic que només faci servir PKCE.",
|
||||
create: 'Crear client',
|
||||
empty: 'Encara no has creat cap client.',
|
||||
revoke: 'Revocar',
|
||||
revokeConfirm: 'Vols revocar el client "{name}"? Els seus tokens deixaran de funcionar.',
|
||||
clientIdShort: 'client_id',
|
||||
redirectLabel: 'redirect',
|
||||
},
|
||||
tokens: {
|
||||
title: 'Personal Access Tokens',
|
||||
subtitle: "Tokens d'accés directe a l'API, sense passar pel flux d'authorize (tipus API key).",
|
||||
tokenWarning: 'Desa aquest token ara, no el podràs tornar a veure:',
|
||||
newToken: 'Nou token',
|
||||
name: 'Nom',
|
||||
namePlaceholder: 'El meu script',
|
||||
scopes: 'Scopes',
|
||||
create: 'Crear token',
|
||||
empty: 'Encara no has creat cap token.',
|
||||
revoke: 'Revocar',
|
||||
revokeConfirm: 'Vols revocar el token "{name}"?',
|
||||
scopesLabel: 'scopes',
|
||||
},
|
||||
authorizedApps: {
|
||||
title: 'Apps autoritzades',
|
||||
subtitle: 'Aplicacions de tercers a les quals has donat accés al teu compte.',
|
||||
empty: 'Encara no has autoritzat cap app.',
|
||||
revoke: 'Revocar accés',
|
||||
revokeConfirm: "Vols revocar l'accés de \"{name}\"?",
|
||||
scopesLabel: 'scopes',
|
||||
},
|
||||
authorize: {
|
||||
title: 'Autoritzar aplicació',
|
||||
wantsAccess: '{client} vol accedir al teu compte ({email}) amb els següents permisos:',
|
||||
noScopes: "No sol·licita permisos addicionals (accés bàsic).",
|
||||
approve: 'Autoritzar',
|
||||
cancel: 'Cancel·lar',
|
||||
notFoundTitle: 'Sol·licitud no trobada',
|
||||
notFoundBody: "Aquesta pantalla només funciona quan hi arribes redirigit per una aplicació client via {path}. Torna-ho a provar des d'aquella app.",
|
||||
goDashboard: 'Anar al tauler',
|
||||
},
|
||||
adminUsers: {
|
||||
title: 'Usuaris',
|
||||
subtitle: 'Alta, edició de rol/estat i baixa de comptes.',
|
||||
newUser: 'Nou usuari',
|
||||
name: 'Nom',
|
||||
email: 'Email',
|
||||
password: 'Contrasenya',
|
||||
role: 'Rol',
|
||||
roleUser: 'Usuari',
|
||||
roleAdmin: 'Admin',
|
||||
create: 'Crear usuari',
|
||||
colName: 'Nom',
|
||||
colEmail: 'Email',
|
||||
colRole: 'Rol',
|
||||
colStatus: 'Estat',
|
||||
active: 'Actiu',
|
||||
inactive: 'Desactivat',
|
||||
noRole: '(sense rol)',
|
||||
edit: 'Editar',
|
||||
delete: 'Esborrar',
|
||||
deleteConfirm: 'Vols esborrar l\'usuari "{name}"? Anirà a la paperera i es pot restaurar.',
|
||||
deleteFailed: "No s'ha pogut esborrar l'usuari.",
|
||||
newPassword: 'Nova contrasenya',
|
||||
noChange: '(sense canvis)',
|
||||
save: 'Desar',
|
||||
cancel: 'Cancel·lar',
|
||||
appRolesTitle: 'Rols per app',
|
||||
appRolesDesc: 'El rol global de dalt mana en aquest panell. Aquí es defineix quin rol té {name} dins de cada app quan aquella app demana el seu usuari per API.',
|
||||
noAppRoles: 'Encara no hi ha rols assignats en cap app.',
|
||||
chooseApp: 'Tria una app…',
|
||||
assign: 'Assignar',
|
||||
assignFailed: "No s'ha pogut assignar el rol.",
|
||||
trashTitle: 'Paperera',
|
||||
viewTrash: 'Veure paperera',
|
||||
viewActive: 'Veure actius',
|
||||
trashEmpty: 'No hi ha usuaris esborrats.',
|
||||
deletedAt: 'Esborrat el {date}',
|
||||
restore: 'Restaurar',
|
||||
restoreFailed: "No s'ha pogut restaurar l'usuari.",
|
||||
forceDelete: 'Esborrar definitivament',
|
||||
forceDeleteConfirm: 'Vols esborrar definitivament "{name}"? Aquesta acció no es pot desfer.',
|
||||
forceDeleteFailed: "No s'ha pogut esborrar definitivament.",
|
||||
pendingTitle: 'Pendents',
|
||||
viewPending: 'Pendents',
|
||||
pendingEmpty: "No hi ha registres pendents d'aprovació.",
|
||||
registeredAt: 'Es va registrar el {date}',
|
||||
approve: 'Aprovar',
|
||||
approveFailed: "No s'ha pogut aprovar l'usuari.",
|
||||
reject: 'Rebutjar',
|
||||
rejectConfirm: 'Vols rebutjar el registre de "{name}"? Anirà a la paperera i es pot restaurar després.',
|
||||
rejectFailed: "No s'ha pogut rebutjar el registre.",
|
||||
},
|
||||
analytics: {
|
||||
title: 'Analítiques',
|
||||
subtitle: "Sessions, logins per app i activitat d'usuaris.",
|
||||
last7: 'Últims 7 dies',
|
||||
last30: 'Últims 30 dies',
|
||||
last90: 'Últims 90 dies',
|
||||
totalUsers: 'Usuaris totals',
|
||||
activeSessions: 'Sessions actives',
|
||||
activeSessionsHint: 'tokens OAuth vigents',
|
||||
loginsToday: 'Logins avui',
|
||||
logins7d: 'Logins últims 7 dies',
|
||||
loginsByDay: 'Logins per dia',
|
||||
appsOAuth: 'Apps (OAuth)',
|
||||
panelAdmin: 'Tauler admin',
|
||||
loginsByApp: 'Logins per app',
|
||||
topUsers: 'Usuaris més actius',
|
||||
noAppLogins: 'Encara no hi ha logins d\'apps en aquest període.',
|
||||
noUserActivity: 'Encara no hi ha activitat en aquest període.',
|
||||
recentActivity: 'Activitat recent',
|
||||
hide: 'Amagar',
|
||||
viewAll: 'Veure-ho tot',
|
||||
colUser: 'Usuari',
|
||||
colApp: 'App',
|
||||
colType: 'Tipus',
|
||||
colIp: 'IP',
|
||||
colWhen: 'Quan',
|
||||
serviceNoUser: '(servei, sense usuari)',
|
||||
deletedApp: '(app esborrada)',
|
||||
recentCount: '{count} esdeveniments recents — clica "Veure-ho tot" per a la taula completa.',
|
||||
chartAriaLabel: 'Logins per dia, apilat per tipus',
|
||||
tooltipAppLabel: 'Apps (OAuth):',
|
||||
tooltipSessionLabel: 'Tauler admin:',
|
||||
barAriaLabel: "{date}: {oauth} logins d'apps, {session} al tauler admin",
|
||||
},
|
||||
};
|
||||
|
||||
export default ca;
|
||||
209
resources/js/i18n/en.ts
Normal file
209
resources/js/i18n/en.ts
Normal file
@@ -0,0 +1,209 @@
|
||||
import type { MessageSchema } from './es';
|
||||
|
||||
const en: MessageSchema = {
|
||||
nav: {
|
||||
dashboard: 'Dashboard',
|
||||
clients: 'OAuth Clients',
|
||||
tokens: 'Personal Access Tokens',
|
||||
authorizedApps: 'Authorized Apps',
|
||||
users: 'Users',
|
||||
analytics: 'Analytics',
|
||||
apiDocs: 'API Docs',
|
||||
logout: 'Sign out',
|
||||
},
|
||||
common: {
|
||||
loading: 'Loading…',
|
||||
creating: 'Creating…',
|
||||
create: 'Create',
|
||||
save: 'Save',
|
||||
cancel: 'Cancel',
|
||||
close: 'Close',
|
||||
edit: 'Edit',
|
||||
delete: 'Delete',
|
||||
none: '(none)',
|
||||
},
|
||||
login: {
|
||||
title: 'Sign in',
|
||||
subtitle: 'OAuth2 server — admin panel.',
|
||||
email: 'Email',
|
||||
password: 'Password',
|
||||
submit: 'Sign in',
|
||||
submitting: 'Signing in…',
|
||||
noAccount: "Don't have an account?",
|
||||
signUp: 'Sign up',
|
||||
invalidCredentials: 'Invalid credentials.',
|
||||
},
|
||||
register: {
|
||||
title: 'Create account',
|
||||
name: 'Name',
|
||||
email: 'Email',
|
||||
password: 'Password',
|
||||
passwordConfirm: 'Confirm password',
|
||||
submit: 'Create account',
|
||||
submitFirstUser: 'Create admin account',
|
||||
submitting: 'Creating…',
|
||||
haveAccount: 'Already have an account?',
|
||||
signIn: 'Sign in',
|
||||
firstUserBanner: "There are no users yet. This account will be the administrator, with immediate access (no approval needed).",
|
||||
pendingTitle: 'Account created',
|
||||
pendingBody: 'An administrator has to approve your account before you can sign in. You may be notified outside the app once it is ready.',
|
||||
backToLogin: 'Back to sign in',
|
||||
},
|
||||
dashboard: {
|
||||
greeting: 'Hi, {name}',
|
||||
subtitle: "This is the OAuth2 server's admin panel.",
|
||||
clientsTitle: 'OAuth Clients',
|
||||
clientsDesc: 'Register apps (Authorization Code+PKCE, Client Credentials or Password Grant).',
|
||||
tokensTitle: 'Personal Access Tokens',
|
||||
tokensDesc: 'Generate tokens for direct API access, like API keys.',
|
||||
appsTitle: 'Authorized Apps',
|
||||
appsDesc: "Third-party apps you've granted access to your account.",
|
||||
usersTitle: 'Users',
|
||||
usersDesc: 'Create, edit role/status and delete accounts (admins only).',
|
||||
analyticsTitle: 'Analytics',
|
||||
analyticsDesc: 'Active sessions, logins by app and most active users (admins only).',
|
||||
apiTitle: 'REST API',
|
||||
apiDesc: 'This server exposes the {resource} resource (scopes {read}/{write}) so third-party apps can manage users via OAuth2. Requires a Passport access token. Interactive docs at {link}.',
|
||||
},
|
||||
clients: {
|
||||
title: 'OAuth Clients',
|
||||
subtitle: 'Registered apps that can request tokens from this server.',
|
||||
secretWarning: "Save this client secret now, you won't be able to see it again:",
|
||||
clientIdLabel: 'client_id:',
|
||||
clientSecretLabel: 'client_secret:',
|
||||
newClient: 'New client',
|
||||
name: 'Name',
|
||||
grantType: 'Grant type',
|
||||
grantAuthCode: 'Authorization Code + PKCE',
|
||||
grantClientCredentials: 'Client Credentials',
|
||||
grantPassword: 'Password Grant',
|
||||
redirectUris: 'Redirect URIs (comma-separated)',
|
||||
confidentialLabel: 'Confidential client (with secret). Uncheck for a public client that only uses PKCE.',
|
||||
create: 'Create client',
|
||||
empty: "You haven't created any clients yet.",
|
||||
revoke: 'Revoke',
|
||||
revokeConfirm: 'Revoke client "{name}"? Its tokens will stop working.',
|
||||
clientIdShort: 'client_id',
|
||||
redirectLabel: 'redirect',
|
||||
},
|
||||
tokens: {
|
||||
title: 'Personal Access Tokens',
|
||||
subtitle: 'Direct API access tokens, without going through the authorize flow (like an API key).',
|
||||
tokenWarning: "Save this token now, you won't be able to see it again:",
|
||||
newToken: 'New token',
|
||||
name: 'Name',
|
||||
namePlaceholder: 'My script',
|
||||
scopes: 'Scopes',
|
||||
create: 'Create token',
|
||||
empty: "You haven't created any tokens yet.",
|
||||
revoke: 'Revoke',
|
||||
revokeConfirm: 'Revoke token "{name}"?',
|
||||
scopesLabel: 'scopes',
|
||||
},
|
||||
authorizedApps: {
|
||||
title: 'Authorized Apps',
|
||||
subtitle: "Third-party apps you've granted access to your account.",
|
||||
empty: "You haven't authorized any app yet.",
|
||||
revoke: 'Revoke access',
|
||||
revokeConfirm: 'Revoke access for "{name}"?',
|
||||
scopesLabel: 'scopes',
|
||||
},
|
||||
authorize: {
|
||||
title: 'Authorize application',
|
||||
wantsAccess: '{client} wants to access your account ({email}) with the following permissions:',
|
||||
noScopes: 'No additional permissions requested (basic access).',
|
||||
approve: 'Authorize',
|
||||
cancel: 'Cancel',
|
||||
notFoundTitle: 'Request not found',
|
||||
notFoundBody: 'This screen only works when you arrive here redirected by a client application via {path}. Try again from that app.',
|
||||
goDashboard: 'Go to dashboard',
|
||||
},
|
||||
adminUsers: {
|
||||
title: 'Users',
|
||||
subtitle: 'Create, edit role/status and delete accounts.',
|
||||
newUser: 'New user',
|
||||
name: 'Name',
|
||||
email: 'Email',
|
||||
password: 'Password',
|
||||
role: 'Role',
|
||||
roleUser: 'User',
|
||||
roleAdmin: 'Admin',
|
||||
create: 'Create user',
|
||||
colName: 'Name',
|
||||
colEmail: 'Email',
|
||||
colRole: 'Role',
|
||||
colStatus: 'Status',
|
||||
active: 'Active',
|
||||
inactive: 'Deactivated',
|
||||
noRole: '(no role)',
|
||||
edit: 'Edit',
|
||||
delete: 'Delete',
|
||||
deleteConfirm: "Delete user \"{name}\"? They'll go to the trash and can be restored.",
|
||||
deleteFailed: 'Could not delete the user.',
|
||||
newPassword: 'New password',
|
||||
noChange: '(no change)',
|
||||
save: 'Save',
|
||||
cancel: 'Cancel',
|
||||
appRolesTitle: 'Roles per app',
|
||||
appRolesDesc: 'The global role above rules this panel. Here you set what role {name} has inside each app when that app asks for their user via API.',
|
||||
noAppRoles: 'No roles assigned in any app yet.',
|
||||
chooseApp: 'Choose app…',
|
||||
assign: 'Assign',
|
||||
assignFailed: 'Could not assign the role.',
|
||||
trashTitle: 'Trash',
|
||||
viewTrash: 'View trash',
|
||||
viewActive: 'View active',
|
||||
trashEmpty: 'No deleted users.',
|
||||
deletedAt: 'Deleted on {date}',
|
||||
restore: 'Restore',
|
||||
restoreFailed: 'Could not restore the user.',
|
||||
forceDelete: 'Delete permanently',
|
||||
forceDeleteConfirm: 'Permanently delete "{name}"? This action cannot be undone.',
|
||||
forceDeleteFailed: 'Could not permanently delete the user.',
|
||||
pendingTitle: 'Pending',
|
||||
viewPending: 'Pending',
|
||||
pendingEmpty: 'No registrations pending approval.',
|
||||
registeredAt: 'Registered on {date}',
|
||||
approve: 'Approve',
|
||||
approveFailed: 'Could not approve the user.',
|
||||
reject: 'Reject',
|
||||
rejectConfirm: 'Reject the registration for "{name}"? It will go to the trash and can be restored later.',
|
||||
rejectFailed: 'Could not reject the registration.',
|
||||
},
|
||||
analytics: {
|
||||
title: 'Analytics',
|
||||
subtitle: 'Sessions, logins by app and user activity.',
|
||||
last7: 'Last 7 days',
|
||||
last30: 'Last 30 days',
|
||||
last90: 'Last 90 days',
|
||||
totalUsers: 'Total users',
|
||||
activeSessions: 'Active sessions',
|
||||
activeSessionsHint: 'valid OAuth tokens',
|
||||
loginsToday: 'Logins today',
|
||||
logins7d: 'Logins last 7 days',
|
||||
loginsByDay: 'Logins by day',
|
||||
appsOAuth: 'Apps (OAuth)',
|
||||
panelAdmin: 'Admin panel',
|
||||
loginsByApp: 'Logins by app',
|
||||
topUsers: 'Most active users',
|
||||
noAppLogins: 'No app logins in this period yet.',
|
||||
noUserActivity: 'No activity in this period yet.',
|
||||
recentActivity: 'Recent activity',
|
||||
hide: 'Hide',
|
||||
viewAll: 'View all',
|
||||
colUser: 'User',
|
||||
colApp: 'App',
|
||||
colType: 'Type',
|
||||
colIp: 'IP',
|
||||
colWhen: 'When',
|
||||
serviceNoUser: '(service, no user)',
|
||||
deletedApp: '(deleted app)',
|
||||
recentCount: '{count} recent events — click "View all" for the full table.',
|
||||
chartAriaLabel: 'Logins by day, stacked by type',
|
||||
tooltipAppLabel: 'Apps (OAuth):',
|
||||
tooltipSessionLabel: 'Admin panel:',
|
||||
barAriaLabel: '{date}: {oauth} app logins, {session} to admin panel',
|
||||
},
|
||||
};
|
||||
|
||||
export default en;
|
||||
208
resources/js/i18n/es.ts
Normal file
208
resources/js/i18n/es.ts
Normal file
@@ -0,0 +1,208 @@
|
||||
const es = {
|
||||
nav: {
|
||||
dashboard: 'Dashboard',
|
||||
clients: 'Clientes OAuth',
|
||||
tokens: 'Personal Access Tokens',
|
||||
authorizedApps: 'Apps autorizadas',
|
||||
users: 'Usuarios',
|
||||
analytics: 'Analíticas',
|
||||
apiDocs: 'API Docs',
|
||||
logout: 'Salir',
|
||||
},
|
||||
common: {
|
||||
loading: 'Cargando…',
|
||||
creating: 'Creando…',
|
||||
create: 'Crear',
|
||||
save: 'Guardar',
|
||||
cancel: 'Cancelar',
|
||||
close: 'Cerrar',
|
||||
edit: 'Editar',
|
||||
delete: 'Borrar',
|
||||
none: '(ninguno)',
|
||||
},
|
||||
login: {
|
||||
title: 'Ingresar',
|
||||
subtitle: 'Servidor OAuth2 — panel de administración.',
|
||||
email: 'Email',
|
||||
password: 'Contraseña',
|
||||
submit: 'Ingresar',
|
||||
submitting: 'Ingresando…',
|
||||
noAccount: '¿No tenés cuenta?',
|
||||
signUp: 'Registrate',
|
||||
invalidCredentials: 'Credenciales inválidas.',
|
||||
},
|
||||
register: {
|
||||
title: 'Crear cuenta',
|
||||
name: 'Nombre',
|
||||
email: 'Email',
|
||||
password: 'Contraseña',
|
||||
passwordConfirm: 'Confirmar contraseña',
|
||||
submit: 'Crear cuenta',
|
||||
submitFirstUser: 'Crear cuenta de administrador',
|
||||
submitting: 'Creando…',
|
||||
haveAccount: '¿Ya tenés cuenta?',
|
||||
signIn: 'Ingresá',
|
||||
firstUserBanner: 'Todavía no hay ningún usuario. Esta cuenta va a quedar como administradora, con acceso inmediato (sin aprobación).',
|
||||
pendingTitle: 'Cuenta creada',
|
||||
pendingBody: 'Un administrador tiene que aprobar tu cuenta antes de que puedas ingresar. Te va a poder avisar por fuera de la app cuando esté lista.',
|
||||
backToLogin: 'Volver a ingresar',
|
||||
},
|
||||
dashboard: {
|
||||
greeting: 'Hola, {name}',
|
||||
subtitle: 'Este es el panel de administración del servidor OAuth2.',
|
||||
clientsTitle: 'Clientes OAuth',
|
||||
clientsDesc: 'Registrá apps (Authorization Code+PKCE, Client Credentials o Password Grant).',
|
||||
tokensTitle: 'Personal Access Tokens',
|
||||
tokensDesc: 'Generá tokens de acceso directo a la API, como API keys.',
|
||||
appsTitle: 'Apps autorizadas',
|
||||
appsDesc: 'Apps de terceros a las que le diste acceso a tu cuenta.',
|
||||
usersTitle: 'Usuarios',
|
||||
usersDesc: 'Alta, edición de rol/estado y baja de cuentas (solo admins).',
|
||||
analyticsTitle: 'Analíticas',
|
||||
analyticsDesc: 'Sesiones activas, logins por app y usuarios más activos (solo admins).',
|
||||
apiTitle: 'API REST',
|
||||
apiDesc: 'Este servidor expone el recurso {resource} (scopes {read}/{write}) para que aplicaciones de terceros gestionen usuarios vía OAuth2. Requiere un access token de Passport. Documentación interactiva en {link}.',
|
||||
},
|
||||
clients: {
|
||||
title: 'Clientes OAuth',
|
||||
subtitle: 'Apps registradas que pueden pedir tokens a este servidor.',
|
||||
secretWarning: 'Guardá este client secret ahora, no se puede volver a ver:',
|
||||
clientIdLabel: 'client_id:',
|
||||
clientSecretLabel: 'client_secret:',
|
||||
newClient: 'Nuevo cliente',
|
||||
name: 'Nombre',
|
||||
grantType: 'Grant type',
|
||||
grantAuthCode: 'Authorization Code + PKCE',
|
||||
grantClientCredentials: 'Client Credentials',
|
||||
grantPassword: 'Password Grant',
|
||||
redirectUris: 'Redirect URIs (separadas por coma)',
|
||||
confidentialLabel: 'Cliente confidencial (con secret). Desmarcá para un cliente público que solo use PKCE.',
|
||||
create: 'Crear cliente',
|
||||
empty: 'Todavía no creaste ningún cliente.',
|
||||
revoke: 'Revocar',
|
||||
revokeConfirm: '¿Revocar el cliente "{name}"? Sus tokens dejarán de funcionar.',
|
||||
clientIdShort: 'client_id',
|
||||
redirectLabel: 'redirect',
|
||||
},
|
||||
tokens: {
|
||||
title: 'Personal Access Tokens',
|
||||
subtitle: 'Tokens de acceso directo a la API, sin pasar por el flujo de authorize (tipo API key).',
|
||||
tokenWarning: 'Guardá este token ahora, no se puede volver a ver:',
|
||||
newToken: 'Nuevo token',
|
||||
name: 'Nombre',
|
||||
namePlaceholder: 'Mi script',
|
||||
scopes: 'Scopes',
|
||||
create: 'Crear token',
|
||||
empty: 'Todavía no creaste ningún token.',
|
||||
revoke: 'Revocar',
|
||||
revokeConfirm: '¿Revocar el token "{name}"?',
|
||||
scopesLabel: 'scopes',
|
||||
},
|
||||
authorizedApps: {
|
||||
title: 'Apps autorizadas',
|
||||
subtitle: 'Aplicaciones de terceros a las que le diste acceso a tu cuenta.',
|
||||
empty: 'No autorizaste ninguna app todavía.',
|
||||
revoke: 'Revocar acceso',
|
||||
revokeConfirm: '¿Revocar el acceso de "{name}"?',
|
||||
scopesLabel: 'scopes',
|
||||
},
|
||||
authorize: {
|
||||
title: 'Autorizar aplicación',
|
||||
wantsAccess: '{client} quiere acceder a tu cuenta ({email}) con los siguientes permisos:',
|
||||
noScopes: 'No solicita permisos adicionales (acceso básico).',
|
||||
approve: 'Autorizar',
|
||||
cancel: 'Cancelar',
|
||||
notFoundTitle: 'Solicitud no encontrada',
|
||||
notFoundBody: 'Esta pantalla solo funciona cuando llegás acá redirigido por una aplicación cliente vía {path}. Volvé a intentar desde esa app.',
|
||||
goDashboard: 'Ir al dashboard',
|
||||
},
|
||||
adminUsers: {
|
||||
title: 'Usuarios',
|
||||
subtitle: 'Alta, edición de rol/estado y baja de cuentas.',
|
||||
newUser: 'Nuevo usuario',
|
||||
name: 'Nombre',
|
||||
email: 'Email',
|
||||
password: 'Contraseña',
|
||||
role: 'Rol',
|
||||
roleUser: 'Usuario',
|
||||
roleAdmin: 'Admin',
|
||||
create: 'Crear usuario',
|
||||
colName: 'Nombre',
|
||||
colEmail: 'Email',
|
||||
colRole: 'Rol',
|
||||
colStatus: 'Estado',
|
||||
active: 'Activo',
|
||||
inactive: 'Desactivado',
|
||||
noRole: '(sin rol)',
|
||||
edit: 'Editar',
|
||||
delete: 'Borrar',
|
||||
deleteConfirm: '¿Borrar al usuario "{name}"? Va a la papelera y se puede restaurar.',
|
||||
deleteFailed: 'No se pudo borrar el usuario.',
|
||||
newPassword: 'Nueva contraseña',
|
||||
noChange: '(sin cambios)',
|
||||
save: 'Guardar',
|
||||
cancel: 'Cancelar',
|
||||
appRolesTitle: 'Roles por app',
|
||||
appRolesDesc: 'El rol global de arriba manda en este panel. Acá se define qué rol tiene {name} dentro de cada app cuando esa app pide su usuario por API.',
|
||||
noAppRoles: 'Sin roles asignados en ninguna app todavía.',
|
||||
chooseApp: 'Elegir app…',
|
||||
assign: 'Asignar',
|
||||
assignFailed: 'No se pudo asignar el rol.',
|
||||
trashTitle: 'Papelera',
|
||||
viewTrash: 'Ver papelera',
|
||||
viewActive: 'Ver activos',
|
||||
trashEmpty: 'No hay usuarios borrados.',
|
||||
deletedAt: 'Borrado el {date}',
|
||||
restore: 'Restaurar',
|
||||
restoreFailed: 'No se pudo restaurar el usuario.',
|
||||
forceDelete: 'Borrar definitivamente',
|
||||
forceDeleteConfirm: '¿Borrar definitivamente a "{name}"? Esta acción no se puede deshacer.',
|
||||
forceDeleteFailed: 'No se pudo borrar definitivamente.',
|
||||
pendingTitle: 'Pendientes',
|
||||
viewPending: 'Pendientes',
|
||||
pendingEmpty: 'No hay registros pendientes de aprobación.',
|
||||
registeredAt: 'Se registró el {date}',
|
||||
approve: 'Aprobar',
|
||||
approveFailed: 'No se pudo aprobar el usuario.',
|
||||
reject: 'Rechazar',
|
||||
rejectConfirm: '¿Rechazar el registro de "{name}"? Va a la papelera y se puede restaurar después.',
|
||||
rejectFailed: 'No se pudo rechazar el registro.',
|
||||
},
|
||||
analytics: {
|
||||
title: 'Analíticas',
|
||||
subtitle: 'Sesiones, logins por app y actividad de usuarios.',
|
||||
last7: 'Últimos 7 días',
|
||||
last30: 'Últimos 30 días',
|
||||
last90: 'Últimos 90 días',
|
||||
totalUsers: 'Usuarios totales',
|
||||
activeSessions: 'Sesiones activas',
|
||||
activeSessionsHint: 'tokens OAuth vigentes',
|
||||
loginsToday: 'Logins hoy',
|
||||
logins7d: 'Logins últimos 7 días',
|
||||
loginsByDay: 'Logins por día',
|
||||
appsOAuth: 'Apps (OAuth)',
|
||||
panelAdmin: 'Panel admin',
|
||||
loginsByApp: 'Logins por app',
|
||||
topUsers: 'Usuarios más activos',
|
||||
noAppLogins: 'Todavía no hay logins de apps en este período.',
|
||||
noUserActivity: 'Todavía no hay actividad en este período.',
|
||||
recentActivity: 'Actividad reciente',
|
||||
hide: 'Ocultar',
|
||||
viewAll: 'Ver todo',
|
||||
colUser: 'Usuario',
|
||||
colApp: 'App',
|
||||
colType: 'Tipo',
|
||||
colIp: 'IP',
|
||||
colWhen: 'Cuándo',
|
||||
serviceNoUser: '(servicio, sin usuario)',
|
||||
deletedApp: '(app borrada)',
|
||||
recentCount: '{count} eventos recientes — click en "Ver todo" para la tabla completa.',
|
||||
chartAriaLabel: 'Logins por día, apilado por tipo',
|
||||
tooltipAppLabel: 'Apps (OAuth):',
|
||||
tooltipSessionLabel: 'Panel admin:',
|
||||
barAriaLabel: '{date}: {oauth} logins de apps, {session} al panel admin',
|
||||
},
|
||||
};
|
||||
|
||||
export default es;
|
||||
export type MessageSchema = typeof es;
|
||||
20
resources/js/i18n/index.ts
Normal file
20
resources/js/i18n/index.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import { createI18n } from 'vue-i18n';
|
||||
import ca from './ca';
|
||||
import en from './en';
|
||||
import es, { type MessageSchema } from './es';
|
||||
|
||||
const SUPPORTED = ['es', 'en', 'ca'] as const;
|
||||
type Locale = (typeof SUPPORTED)[number];
|
||||
|
||||
function isSupported(locale: string): locale is Locale {
|
||||
return (SUPPORTED as readonly string[]).includes(locale);
|
||||
}
|
||||
|
||||
const i18n = createI18n<[MessageSchema], Locale>({
|
||||
legacy: false,
|
||||
locale: isSupported(window.__LOCALE__) ? window.__LOCALE__ : 'es',
|
||||
fallbackLocale: 'es',
|
||||
messages: { en, es, ca },
|
||||
});
|
||||
|
||||
export default i18n;
|
||||
Reference in New Issue
Block a user