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

build: release v6.89.0 #6894

Closed
wants to merge 9 commits into from
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,27 @@ All notable changes to this project will be documented in this file. Dates are d

Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).

#### [v6.89.0](https://github.com/opengovsg/FormSG/compare/v6.88.0...v6.89.0)

- feat: myinfo for storage-mode [`#6870`](https://github.com/opengovsg/FormSG/pull/6870)
- feat: announcement modal and what's new for myinfo storage-mode [`#6892`](https://github.com/opengovsg/FormSG/pull/6892)
- chore: remove eb shift frontend feature flags [`#6869`](https://github.com/opengovsg/FormSG/pull/6869)
- chore(deps-dev): bump @types/lodash from 4.14.200 to 4.14.201 in /shared [`#6888`](https://github.com/opengovsg/FormSG/pull/6888)
- chore(deps): bump axios from 1.2.1 to 1.6.0 in /frontend [`#6887`](https://github.com/opengovsg/FormSG/pull/6887)
- fix(deps): bump axios from 1.2.1 to 1.6.0 [`#6886`](https://github.com/opengovsg/FormSG/pull/6886)
- fix(deps): bump type-fest from 4.5.0 to 4.7.1 in /shared [`#6883`](https://github.com/opengovsg/FormSG/pull/6883)
- build: merge release 6.88.0 into develop [`#6882`](https://github.com/opengovsg/FormSG/pull/6882)
- build: release v6.88.0 [`#6881`](https://github.com/opengovsg/FormSG/pull/6881)

#### [v6.88.0](https://github.com/opengovsg/FormSG/compare/v6.87.0...v6.88.0)

> 9 November 2023

- chore: add note to update guide to sync with file exts [`#6876`](https://github.com/opengovsg/FormSG/pull/6876)
- fix(datepicker): webkit-related stylings [`#6875`](https://github.com/opengovsg/FormSG/pull/6875)
- build: merge release 6.87.0 into develop [`#6879`](https://github.com/opengovsg/FormSG/pull/6879)
- build: release v6.87.0 [`#6878`](https://github.com/opengovsg/FormSG/pull/6878)
- chore: bump version to v6.88.0 [`352ae5c`](https://github.com/opengovsg/FormSG/commit/352ae5c49ed30d73450364f8b4d6048e21f72ee2)

#### [v6.87.0](https://github.com/opengovsg/FormSG/compare/v6.86.0...v6.87.0)

Expand Down
37 changes: 36 additions & 1 deletion __tests__/e2e/encrypt-submission.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import mongoose from 'mongoose'
import { featureFlags } from 'shared/constants/feature-flags'
import { BasicField, FormResponseMode } from 'shared/types'
import {
BasicField,
FormAuthType,
FormResponseMode,
MyInfoAttribute,
} from 'shared/types'

import { IFeatureFlagModel, IFormModel } from 'src/types'

Expand All @@ -19,6 +24,7 @@ import {
} from './helpers'
import {
createBlankVersion,
createMyInfoField,
createOptionalVersion,
deleteDocById,
getSettings,
Expand Down Expand Up @@ -143,4 +149,33 @@ test.describe('Storage form submission', () => {
)
await deleteDocById(Form, form._id)
})

test('Create and submit storage mode form with MyInfo fields', async ({
page,
}) => {
// Define
const formFields = [
// Short answer
createMyInfoField(MyInfoAttribute.Name, 'LIM YONG XIANG', true),
// Dropdown
createMyInfoField(MyInfoAttribute.Sex, 'MALE', true),
// Date
createMyInfoField(MyInfoAttribute.DateOfBirth, '06/10/1980', true),
// Mobile
createMyInfoField(MyInfoAttribute.MobileNo, '97399245', false),
// Unverified
createMyInfoField(MyInfoAttribute.WorkpassStatus, 'Live', false),
]
const formLogics = NO_LOGIC
const formSettings = getSettings({
authType: FormAuthType.MyInfo,
})

// Test
await runEncryptSubmissionTest(page, Form, {
formFields,
formLogics,
formSettings,
})
})
})
5 changes: 3 additions & 2 deletions __tests__/integration/helpers/express-auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import * as OtpUtils from 'src/app/utils/otp'

const MOCK_VALID_OTP = '123456'
const MOCK_OTP_PREFIX = 'ABC'
const ADMIN_LOGIN_SESSION_COOKIE_NAME = 'formsg.connect.sid'

/**
* Integration test helper to create an authenticated session where the user
Expand Down Expand Up @@ -50,7 +51,7 @@ export const createAuthedSession = async (
// Assert
// Should have session cookie returned.
const sessionCookie = request.cookies.find(
(cookie) => cookie.name === 'connect.sid',
(cookie) => cookie.name === ADMIN_LOGIN_SESSION_COOKIE_NAME,
)
expect(sessionCookie).toBeDefined()

Expand All @@ -68,7 +69,7 @@ export const logoutSession = async (request: Session): Promise<Session> => {
expect(response.status).toEqual(200)

const sessionCookie = request.cookies.find(
(cookie) => cookie.name === 'connect.sid',
(cookie) => cookie.name === ADMIN_LOGIN_SESSION_COOKIE_NAME,
)
expect(sessionCookie).not.toBeDefined()

Expand Down
2 changes: 1 addition & 1 deletion __tests__/integration/helpers/express-setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const testSessionMiddlewares = () => {
saveUninitialized: false,
resave: false,
secret: 'test-session-secret',
name: 'connect.sid',
name: 'formsg.connect.sid',
store: new session.MemoryStore(),
})

Expand Down
18 changes: 9 additions & 9 deletions frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions frontend/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "form-frontend",
"version": "6.88.0",
"version": "6.89.0",
"homepage": ".",
"private": true,
"dependencies": {
Expand All @@ -15,7 +15,7 @@
"@stablelib/base64": "^1.0.1",
"@stripe/react-stripe-js": "^1.15.0",
"@stripe/stripe-js": "^1.44.1",
"axios": "^1.2.1",
"axios": "^1.6.0",
"broadcast-channel": "^4.13.0",
"browser-image-compression": "^2.0.2",
"comlink": "^4.3.1",
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/constants/localStorage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export const LOCAL_STORAGE_EVENT = 'local-storage'
* Key to store whether a user has seen the rollout announcements before.
*/
export const ROLLOUT_ANNOUNCEMENT_KEY_PREFIX =
'has-seen-rollout-announcement-20231026-'
'has-seen-rollout-announcement-20231116-'

/**
* Key to store whether the admin has seen the feature tour in localStorage.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,7 @@ import { Box, Text } from '@chakra-ui/react'
import { useFeatureIsOn, useGrowthBook } from '@growthbook/growthbook-react'

import { featureFlags } from '~shared/constants'
import {
AdminFormDto,
FormAuthType,
FormResponseMode,
MyInfoAttribute,
} from '~shared/types'
import { AdminFormDto, FormAuthType, MyInfoAttribute } from '~shared/types'

import { GUIDE_EMAIL_MODE } from '~constants/links'
import { ADMINFORM_SETTINGS_SINGPASS_SUBROUTE } from '~constants/routes'
Expand Down Expand Up @@ -113,14 +108,12 @@ export const MyInfoFieldPanel = () => {
)

// myInfo should be disabled if
// 1. form response mode is not email mode
// 2. form auth type is not myInfo
// 3. # of myInfo fields >= 30
// 1. form auth type is not myInfo
// 2. # of myInfo fields >= 30
const isMyInfoDisabled = useMemo(
() =>
form
? form.form_fields.filter(isMyInfo).length >= 30 ||
form.responseMode !== FormResponseMode.Email ||
(form.authType !== FormAuthType.MyInfo &&
form.authType !== FormAuthType.SGID_MyInfo)
: true,
Expand Down Expand Up @@ -232,14 +225,10 @@ export const MyInfoFieldPanel = () => {
)
}

type MyInfoTextProps = Pick<
AdminFormDto,
'authType' | 'responseMode' | 'form_fields'
>
type MyInfoTextProps = Pick<AdminFormDto, 'authType' | 'form_fields'>

const MyInfoText = ({
authType,
responseMode,
form_fields,
}: MyInfoTextProps): JSX.Element => {
const isMyInfoDisabled =
Expand All @@ -249,10 +238,6 @@ const MyInfoText = ({
[form_fields],
)

if (responseMode !== FormResponseMode.Email) {
return <Text>MyInfo fields are not available in Storage mode forms.</Text>
}

if (isMyInfoDisabled) {
return (
<Text>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import { isMyInfo } from '~features/myinfo/utils'

import { useMutateFormSettings } from '../../mutations'

import { AUTHTYPE_TO_TEXT, STORAGE_MODE_AUTHTYPES } from './constants'
import { FORM_AUTHTYPES } from './constants'
import { EsrvcIdBox } from './EsrvcIdBox'

const esrvcidRequired = (authType: FormAuthType) => {
Expand All @@ -42,13 +42,11 @@ interface AuthSettingsSectionProps {
export const AuthSettingsSectionSkeleton = (): JSX.Element => {
return (
<Radio.RadioGroup>
{Object.entries(STORAGE_MODE_AUTHTYPES).map(
([authType, textToRender]) => (
<Radio isDisabled key={authType}>
<Skeleton>{textToRender}</Skeleton>
</Radio>
),
)}
{Object.entries(FORM_AUTHTYPES).map(([authType, textToRender]) => (
<Radio isDisabled key={authType}>
<Skeleton>{textToRender}</Skeleton>
</Radio>
))}
</Radio.RadioGroup>
)
}
Expand Down Expand Up @@ -116,12 +114,9 @@ export const AuthSettingsSection = ({
[isDisabled, mutateFormAuthType, settings.authType],
)

const radioOptions: [FormAuthType, string][] = useMemo(() => {
return Object.entries(AUTHTYPE_TO_TEXT[settings.responseMode]) as [
FormAuthType,
string,
][]
}, [settings.responseMode])
const radioOptions: [FormAuthType, string][] = Object.entries(
FORM_AUTHTYPES,
) as [FormAuthType, string][]

return (
<Box>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,29 +1,16 @@
import { FormAuthType, FormResponseMode } from '~shared/types/form'
import { FormAuthType } from '~shared/types/form'

export type EmailFormAuthType = FormAuthType
export type StorageFormAuthType =
| FormAuthType.NIL
| FormAuthType.SP
| FormAuthType.CP
| FormAuthType.SGID
export type StorageFormAuthType = FormAuthType

export const STORAGE_MODE_AUTHTYPES: Record<StorageFormAuthType, string> = {
[FormAuthType.NIL]: 'None',
[FormAuthType.SGID]: 'Singpass App-only Login',
[FormAuthType.SP]: 'Singpass',
[FormAuthType.CP]: 'Singpass (Corporate)',
}

// Not using STORAGE_MODE_AUTHTYPES due to wanting a different order.
export const EMAIL_MODE_AUTHTYPES: Record<EmailFormAuthType, string> = {
export const FORM_AUTHTYPES: Record<
StorageFormAuthType | EmailFormAuthType,
string
> = {
[FormAuthType.NIL]: 'None',
[FormAuthType.SGID]: 'Singpass App-only Login',
[FormAuthType.SGID_MyInfo]: 'Singpass App-only with Myinfo',
[FormAuthType.SP]: 'Singpass',
[FormAuthType.MyInfo]: 'Singpass with Myinfo',
[FormAuthType.CP]: 'Singpass (Corporate)',
}
export const AUTHTYPE_TO_TEXT = {
[FormResponseMode.Email]: EMAIL_MODE_AUTHTYPES,
[FormResponseMode.Encrypt]: STORAGE_MODE_AUTHTYPES,
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { useEffect, useMemo } from 'react'
import { useEffect } from 'react'

import { FormResponseMode } from '~shared/types'

import { useFormTemplate } from '~features/admin-form/common/queries'
import { isMyInfo } from '~features/myinfo/utils'
import {
CreateFormFlowStates,
CreateFormWizardContext,
Expand All @@ -23,11 +22,6 @@ export const useUseTemplateWizardContext = (
/* enabled= */ !!formId,
)

const containsMyInfoFields = useMemo(
() => !!templateFormData?.form.form_fields.find((ff) => isMyInfo(ff)),
[templateFormData?.form.form_fields],
)

const { formMethods, currentStep, direction, keypair, setCurrentStep } =
useCommonFormWizardProvider()

Expand All @@ -41,18 +35,9 @@ export const useUseTemplateWizardContext = (

reset({
...getValues(),
responseMode: containsMyInfoFields
? FormResponseMode.Email
: FormResponseMode.Encrypt,
title: `[Template] ${templateFormData?.form.title}`,
})
}, [
reset,
getValues,
containsMyInfoFields,
isTemplateFormLoading,
templateFormData?.form.title,
])
}, [reset, getValues, isTemplateFormLoading, templateFormData?.form.title])

const { handleSubmit } = formMethods

Expand Down Expand Up @@ -98,7 +83,6 @@ export const useUseTemplateWizardContext = (
formMethods,
handleDetailsSubmit,
handleCreateStorageModeForm,
containsMyInfoFields,
modalHeader: 'Duplicate form',
}
}
Expand Down
Loading
Loading