Skip to content

Commit

Permalink
Merge branch 'sc_admin_table' of https://github.com/island-is/island.is
Browse files Browse the repository at this point in the history
… into sc_admin_table
  • Loading branch information
albinagu committed Oct 21, 2024
2 parents 3177163 + d0c5b30 commit faa8b17
Show file tree
Hide file tree
Showing 5 changed files with 180 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -162,8 +162,8 @@ const OldAgePensionTemplate: ApplicationTemplate<
},
pendingAction: {
title: coreSIAStatesMessages.tryggingastofnunSubmittedTitle,
content: coreSIAStatesMessages.tryggingastofnunSubmittedContent,
displayStatus: 'info',
content: statesMessages.oldAgePensionSubmittedContent,
displayStatus: 'warning',
},
historyLogs: [
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -516,4 +516,11 @@ export const statesMessages = defineMessages({
defaultMessage: 'Umsókn vegna ellilífeyris hefur verið samþykkt',
description: 'The application for old-age pension has been approved',
},
oldAgePensionSubmittedContent: {
id: 'oap.application:oldAgePensionSubmittedContent#markdown',
defaultMessage:
'Umsókn þín er í bið eftir yfirferð. Hægt er að breyta umsókn þar til hún er tekin til yfirferðar. Athugið að ef ekki er búið að skila inn tekjuáætlun þarf að gera það hér.',
description:
'Your application is awaiting review. It is possible to edit the application until it is under review. Please note that if you have not submitted an income plan, you must do so here.',
},
})
1 change: 1 addition & 0 deletions libs/nest/core/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from './lib/decorators/nationalId.decorator'
export * from './lib/decorators/ParsedUserAgent.decorator'
export * from './lib/validators/isPersonNationalId.decorator'
export * from './lib/validators/isNationalId.decorator'
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import { parseUserAgent } from './ParsedUserAgent.decorator'

describe('parseUserAgent Function', () => {
it('should parse new iOS app user agent', () => {
// Arrange
const userAgentString = 'IslandIsApp (1.0.0) Build/321 (ios/9.0.0)'

// Act
const result = parseUserAgent(userAgentString)

// Assert
expect(result).toEqual({
ua: userAgentString,
os: { name: 'iOS', version: '9.0.0' },
app: { name: 'IslandIsApp', version: '1.0.0', build: 321 },
})
})

it('should parse new Android app user agent', () => {
// Arrange
const userAgentString = 'IslandIsApp (2.1.0) Build/123 (android/11.0.0)'

// Act
const result = parseUserAgent(userAgentString)

// Assert
expect(result).toEqual({
ua: userAgentString,
os: { name: 'Android', version: '11.0.0' },
app: { name: 'IslandIsApp', version: '2.1.0', build: 123 },
})
})

it('should parse old iOS app user agent', () => {
// Arrange
const userAgentString = 'IslandApp/144 CFNetwork/1498.700.2 Darwin/23.6.0'

// Act
const result = parseUserAgent(userAgentString)

// Assert
expect(result).toEqual({
ua: userAgentString,
os: { name: 'iOS' },
app: { name: 'IslandIsApp' },
})
})

it('should parse old Android app user agent', () => {
// Arrange
const userAgentString = 'okhttp/4.9.2'

// Act
const result = parseUserAgent(userAgentString)

// Assert
expect(result).toEqual({
ua: userAgentString,
os: { name: 'Android' },
app: { name: 'IslandIsApp' },
})
})

it('should return empty app and os for unknown user agent', () => {
// Arrange
const userAgentString = 'UnknownUserAgent/1.0'

// Act
const result = parseUserAgent(userAgentString)

// Assert
expect(result).toEqual({
ua: userAgentString,
os: {},
app: {},
})
})
})
92 changes: 92 additions & 0 deletions libs/nest/core/src/lib/decorators/ParsedUserAgent.decorator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import { getRequest } from '@island.is/auth-nest-tools'
import { createParamDecorator, ExecutionContext } from '@nestjs/common'

// Old iOS app user agents:
// - IslandApp/144 CFNetwork/1498.700.2 Darwin/23.6.0

// Old Android app user agents. We associate it with IslandIsApp, assuming
// there are no other React Native android apps calling our API.
// - okhttp/4.9.2

// New app user agents
// - IslandIsApp (1.0.0}) Build/321 (ios/9.0.0)
// - IslandIsApp (1.0.0}) Build/321 (android/9.0.0)

export interface UserAgent {
ua: string
os: {
name?: 'iOS' | 'Android'
version?: string
}
app: {
name?: 'IslandIsApp'
version?: string
build?: number
}
}

/**
* Parses the user agent string and returns an object with the user agent, os and app information.
*
* Only supports parsing IslandIsApp user agents to start with but the interface is
* future compatible if we want to parse more user agents with ua-parser-js.
*/
export const parseUserAgent = (userAgentString: string): UserAgent => {
const userAgent: UserAgent = {
ua: userAgentString,
os: {},
app: {},
}

// Match new app user agents
const newAppRegex =
/IslandIsApp \(([^)]+)\) Build\/(\d+) \((ios|android)\/([^)]+)\)/
const newAppMatch = userAgentString.match(newAppRegex)

if (newAppMatch) {
userAgent.app.name = 'IslandIsApp'
userAgent.app.version = newAppMatch[1]
userAgent.app.build = parseInt(newAppMatch[2], 10)
userAgent.os.name = newAppMatch[3] === 'ios' ? 'iOS' : 'Android'
userAgent.os.version = newAppMatch[4]
return userAgent
}

// Match old iOS app user agents
const oldIosRegex = /IslandApp\/\d+ CFNetwork\/[^\s]+ Darwin\/[^\s]+/
const oldIosMatch = userAgentString.match(oldIosRegex)

if (oldIosMatch) {
userAgent.app.name = 'IslandIsApp'
userAgent.os.name = 'iOS'
return userAgent
}

// Match old Android app user agents
const oldAndroidRegex = /okhttp\/[^\s]+/
const oldAndroidMatch = userAgentString.match(oldAndroidRegex)

if (oldAndroidMatch) {
userAgent.app.name = 'IslandIsApp'
userAgent.os.name = 'Android'
return userAgent
}

// Default return, if no patterns matched
return userAgent
}

/**
* Decorator that parses the user agent string from the request headers and returns an object with the user agent, os
* and app information.
*
* Only supports parsing IslandIsApp user agents for now.
*/
export const ParsedUserAgent = createParamDecorator(
(_: unknown, context: ExecutionContext): UserAgent => {
const request = getRequest(context)
const userAgentString = request.headers['user-agent'] || ''

return parseUserAgent(userAgentString)
},
)

0 comments on commit faa8b17

Please sign in to comment.