mirror of
https://codeberg.org/timelimit/timelimit-server.git
synced 2026-08-31 19:03:45 +02:00
Save the locale during mail login processes
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* server component for the TimeLimit App
|
* server component for the TimeLimit App
|
||||||
* Copyright (C) 2019 Jonas Lochmann
|
* Copyright (C) 2019 - 2021 Jonas Lochmann
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Affero General Public License as
|
* it under the terms of the GNU Affero General Public License as
|
||||||
@@ -19,18 +19,24 @@ import * as Sequelize from 'sequelize'
|
|||||||
import { authTokenColumn, timestampColumn } from './columns'
|
import { authTokenColumn, timestampColumn } from './columns'
|
||||||
import { SequelizeAttributes } from './types'
|
import { SequelizeAttributes } from './types'
|
||||||
|
|
||||||
export interface AuthTokenAttributes {
|
export interface AuthTokenAttributesVersion1 {
|
||||||
token: string
|
token: string
|
||||||
mail: string
|
mail: string
|
||||||
createdAt: string
|
createdAt: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface AuthTokenAttributesVersion2 {
|
||||||
|
locale: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type AuthTokenAttributes = AuthTokenAttributesVersion1 & AuthTokenAttributesVersion2
|
||||||
|
|
||||||
export type AuthTokenModel = Sequelize.Model<AuthTokenAttributes> & AuthTokenAttributes
|
export type AuthTokenModel = Sequelize.Model<AuthTokenAttributes> & AuthTokenAttributes
|
||||||
export type AuthTokenModelStatic = typeof Sequelize.Model & {
|
export type AuthTokenModelStatic = typeof Sequelize.Model & {
|
||||||
new (values?: object, options?: Sequelize.BuildOptions): AuthTokenModel;
|
new (values?: object, options?: Sequelize.BuildOptions): AuthTokenModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const attributes: SequelizeAttributes<AuthTokenAttributes> = {
|
export const attributesVersion1: SequelizeAttributes<AuthTokenAttributesVersion1> = {
|
||||||
token: {
|
token: {
|
||||||
...authTokenColumn,
|
...authTokenColumn,
|
||||||
primaryKey: true
|
primaryKey: true
|
||||||
@@ -45,4 +51,17 @@ export const attributes: SequelizeAttributes<AuthTokenAttributes> = {
|
|||||||
createdAt: { ...timestampColumn }
|
createdAt: { ...timestampColumn }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const attributesVersion2: SequelizeAttributes<AuthTokenAttributesVersion2> = {
|
||||||
|
locale: {
|
||||||
|
type: Sequelize.STRING,
|
||||||
|
allowNull: false,
|
||||||
|
defaultValue: 'en'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const attributes: SequelizeAttributes<AuthTokenAttributes> = {
|
||||||
|
...attributesVersion1,
|
||||||
|
...attributesVersion2
|
||||||
|
}
|
||||||
|
|
||||||
export const createAuthtokenModel = (sequelize: Sequelize.Sequelize): AuthTokenModelStatic => sequelize.define('AuthToken', attributes) as AuthTokenModelStatic
|
export const createAuthtokenModel = (sequelize: Sequelize.Sequelize): AuthTokenModelStatic => sequelize.define('AuthToken', attributes) as AuthTokenModelStatic
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* server component for the TimeLimit App
|
* server component for the TimeLimit App
|
||||||
* Copyright (C) 2019 - 2020 Jonas Lochmann
|
* Copyright (C) 2019 - 2021 Jonas Lochmann
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Affero General Public License as
|
* it under the terms of the GNU Affero General Public License as
|
||||||
@@ -19,7 +19,7 @@ import * as Sequelize from 'sequelize'
|
|||||||
import { authTokenColumn, timestampColumn } from './columns'
|
import { authTokenColumn, timestampColumn } from './columns'
|
||||||
import { SequelizeAttributes } from './types'
|
import { SequelizeAttributes } from './types'
|
||||||
|
|
||||||
export interface MailLoginTokenAttributes {
|
export interface MailLoginTokenAttributesVersion1 {
|
||||||
mailLoginToken: string
|
mailLoginToken: string
|
||||||
receivedCode: string
|
receivedCode: string
|
||||||
mail: string
|
mail: string
|
||||||
@@ -27,12 +27,18 @@ export interface MailLoginTokenAttributes {
|
|||||||
remainingAttempts: number
|
remainingAttempts: number
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface MailLoginTokenAttributesVersion2 {
|
||||||
|
locale: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type MailLoginTokenAttributes = MailLoginTokenAttributesVersion1 & MailLoginTokenAttributesVersion2
|
||||||
|
|
||||||
export type MailLoginTokenModel = Sequelize.Model<MailLoginTokenAttributes> & MailLoginTokenAttributes
|
export type MailLoginTokenModel = Sequelize.Model<MailLoginTokenAttributes> & MailLoginTokenAttributes
|
||||||
export type MailLoginTokenModelStatic = typeof Sequelize.Model & {
|
export type MailLoginTokenModelStatic = typeof Sequelize.Model & {
|
||||||
new (values?: object, options?: Sequelize.BuildOptions): MailLoginTokenModel;
|
new (values?: object, options?: Sequelize.BuildOptions): MailLoginTokenModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const attributes: SequelizeAttributes<MailLoginTokenAttributes> = {
|
export const attributesVersion1: SequelizeAttributes<MailLoginTokenAttributesVersion1> = {
|
||||||
mailLoginToken: {
|
mailLoginToken: {
|
||||||
...authTokenColumn,
|
...authTokenColumn,
|
||||||
primaryKey: true
|
primaryKey: true
|
||||||
@@ -61,4 +67,17 @@ export const attributes: SequelizeAttributes<MailLoginTokenAttributes> = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const attributesVersion2: SequelizeAttributes<MailLoginTokenAttributesVersion2> = {
|
||||||
|
locale: {
|
||||||
|
type: Sequelize.STRING,
|
||||||
|
allowNull: false,
|
||||||
|
defaultValue: 'en'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const attributes: SequelizeAttributes<MailLoginTokenAttributes> = {
|
||||||
|
...attributesVersion1,
|
||||||
|
...attributesVersion2
|
||||||
|
}
|
||||||
|
|
||||||
export const createMailLoginTokenModel = (sequelize: Sequelize.Sequelize): MailLoginTokenModelStatic => sequelize.define('MailLoginToken', attributes) as MailLoginTokenModelStatic
|
export const createMailLoginTokenModel = (sequelize: Sequelize.Sequelize): MailLoginTokenModelStatic => sequelize.define('MailLoginToken', attributes) as MailLoginTokenModelStatic
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* server component for the TimeLimit App
|
* server component for the TimeLimit App
|
||||||
* Copyright (C) 2019 - 2020 Jonas Lochmann
|
* Copyright (C) 2019 - 2021 Jonas Lochmann
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Affero General Public License as
|
* it under the terms of the GNU Affero General Public License as
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
import { QueryInterface, Sequelize, Transaction } from 'sequelize'
|
import { QueryInterface, Sequelize, Transaction } from 'sequelize'
|
||||||
import { attributes as addDeviceTokenAttributes } from '../../adddevicetoken'
|
import { attributes as addDeviceTokenAttributes } from '../../adddevicetoken'
|
||||||
import { attributes as appAttributes } from '../../app'
|
import { attributes as appAttributes } from '../../app'
|
||||||
import { attributes as authTokenAttributes } from '../../authtoken'
|
import { attributesVersion1 as authTokenAttributes } from '../../authtoken'
|
||||||
import { attributesVersion1 as categoryAttributes } from '../../category'
|
import { attributesVersion1 as categoryAttributes } from '../../category'
|
||||||
import { attributes as categoryAppAttributes } from '../../categoryapp'
|
import { attributes as categoryAppAttributes } from '../../categoryapp'
|
||||||
import { attributesVersion1 as deviceAttributes } from '../../device'
|
import { attributesVersion1 as deviceAttributes } from '../../device'
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* server component for the TimeLimit App
|
* server component for the TimeLimit App
|
||||||
* Copyright (C) 2019 Jonas Lochmann
|
* Copyright (C) 2019 - 2021 Jonas Lochmann
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Affero General Public License as
|
* it under the terms of the GNU Affero General Public License as
|
||||||
@@ -16,7 +16,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { QueryInterface, Sequelize, Transaction } from 'sequelize'
|
import { QueryInterface, Sequelize, Transaction } from 'sequelize'
|
||||||
import { attributes as mailLoginTokenAttributes } from '../../maillogintoken'
|
import { attributesVersion1 as mailLoginTokenAttributes } from '../../maillogintoken'
|
||||||
|
|
||||||
export async function up (queryInterface: QueryInterface, sequelize: Sequelize) {
|
export async function up (queryInterface: QueryInterface, sequelize: Sequelize) {
|
||||||
await sequelize.transaction({
|
await sequelize.transaction({
|
||||||
|
|||||||
@@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
* server component for the TimeLimit App
|
||||||
|
* Copyright (C) 2019 - 2021 Jonas Lochmann
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, version 3 of the License.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { QueryInterface, Sequelize, Transaction } from 'sequelize'
|
||||||
|
import { attributesVersion2 as authTokenAttributes } from '../../authtoken'
|
||||||
|
import { attributesVersion2 as mailLoginTokenAttributes } from '../../maillogintoken'
|
||||||
|
|
||||||
|
export async function up (queryInterface: QueryInterface, sequelize: Sequelize) {
|
||||||
|
await sequelize.transaction({
|
||||||
|
type: Transaction.TYPES.EXCLUSIVE
|
||||||
|
}, async (transaction) => {
|
||||||
|
await queryInterface.addColumn('AuthTokens', 'locale', {
|
||||||
|
...authTokenAttributes.locale
|
||||||
|
}, {
|
||||||
|
transaction
|
||||||
|
})
|
||||||
|
|
||||||
|
await queryInterface.addColumn('MailLoginTokens', 'locale', {
|
||||||
|
...mailLoginTokenAttributes.locale
|
||||||
|
}, {
|
||||||
|
transaction
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function down (queryInterface: QueryInterface, sequelize: Sequelize) {
|
||||||
|
await sequelize.transaction({
|
||||||
|
type: Transaction.TYPES.EXCLUSIVE
|
||||||
|
}, async (transaction) => {
|
||||||
|
await queryInterface.removeColumn('AuthTokens', 'locale', { transaction })
|
||||||
|
await queryInterface.removeColumn('MailLoginTokens', 'locale', { transaction })
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -19,13 +19,18 @@ import { Unauthorized } from 'http-errors'
|
|||||||
import { Database, Transaction } from '../../database'
|
import { Database, Transaction } from '../../database'
|
||||||
import { generateAuthToken } from '../../util/token'
|
import { generateAuthToken } from '../../util/token'
|
||||||
|
|
||||||
export const createAuthTokenByMailAddress = async ({ mail, database, transaction }: { mail: string, database: Database, transaction: Transaction }) => {
|
export const createAuthTokenByMailAddress = async ({
|
||||||
|
mail, database, transaction, locale
|
||||||
|
}: {
|
||||||
|
mail: string, database: Database, transaction: Transaction, locale: string
|
||||||
|
}) => {
|
||||||
const token = generateAuthToken()
|
const token = generateAuthToken()
|
||||||
|
|
||||||
await database.authtoken.create({
|
await database.authtoken.create({
|
||||||
token,
|
token,
|
||||||
mail,
|
mail,
|
||||||
createdAt: Date.now().toString()
|
createdAt: Date.now().toString(),
|
||||||
|
locale
|
||||||
}, { transaction })
|
}, { transaction })
|
||||||
|
|
||||||
return token
|
return token
|
||||||
|
|||||||
@@ -91,7 +91,8 @@ export const sendLoginCode = async ({ mail, deviceAuthToken, locale, database }:
|
|||||||
receivedCode: code,
|
receivedCode: code,
|
||||||
mail,
|
mail,
|
||||||
createdAt: Date.now().toString(10),
|
createdAt: Date.now().toString(10),
|
||||||
remainingAttempts: 3
|
remainingAttempts: 3,
|
||||||
|
locale
|
||||||
}, { transaction })
|
}, { transaction })
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -143,7 +144,12 @@ export const signInByMailCode = async ({ mailLoginToken, receivedCode, database
|
|||||||
throw new Gone()
|
throw new Gone()
|
||||||
}
|
}
|
||||||
|
|
||||||
const mailAuthToken = await createAuthTokenByMailAddress({ mail: entry.mail, database, transaction })
|
const mailAuthToken = await createAuthTokenByMailAddress({
|
||||||
|
mail: entry.mail,
|
||||||
|
locale: entry.locale,
|
||||||
|
database,
|
||||||
|
transaction
|
||||||
|
})
|
||||||
|
|
||||||
return { mailAuthToken }
|
return { mailAuthToken }
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user