闭社主体 forked from https://github.com/tootsuite/mastodon
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

518 lines
23 KiB

8 years ago
7 years ago
Web Push Notifications (#3243) * feat: Register push subscription * feat: Notify when mentioned * feat: Boost, favourite, reply, follow, follow request * feat: Notification interaction * feat: Handle change of public key * feat: Unsubscribe if things go wrong * feat: Do not send normal notifications if push is enabled * feat: Focus client if open * refactor: Move push logic to WebPushSubscription * feat: Better title and body * feat: Localize messages * chore: Fix lint errors * feat: Settings * refactor: Lazy load * fix: Check if push settings exist * feat: Device-based preferences * refactor: Simplify logic * refactor: Pull request feedback * refactor: Pull request feedback * refactor: Create /api/web/push_subscriptions endpoint * feat: Spec PushSubscriptionController * refactor: WebPushSubscription => Web::PushSubscription * feat: Spec Web::PushSubscription * feat: Display first media attachment * feat: Support direction * fix: Stuff broken while rebasing * refactor: Integration with session activations * refactor: Cleanup * refactor: Simplify implementation * feat: Set VAPID keys via environment * chore: Comments * fix: Crash when no alerts * fix: Set VAPID keys in testing environment * fix: Follow link * feat: Notification actions * fix: Delete previous subscription * chore: Temporary logs * refactor: Move migration to a later date * fix: Fetch the correct session activation and misc bugs * refactor: Move migration to a later date * fix: Remove follow request (no notifications) * feat: Send administrator contact to push service * feat: Set time-to-live * fix: Do not show sensitive images * fix: Reducer crash in error handling * feat: Add badge * chore: Fix lint error * fix: Checkbox label overlap * fix: Check for payload support * fix: Rename action "type" (crash in latest Chrome) * feat: Action to expand notification * fix: Lint errors * fix: Unescape notification body * fix: Do not allow boosting if the status is hidden * feat: Add VAPID keys to the production sample environment * fix: Strip HTML tags from status * refactor: Better error messages * refactor: Handle browser not implementing the VAPID protocol (Samsung Internet) * fix: Error when target_status is nil * fix: Handle lack of image * fix: Delete reference to invalid subscriptions * feat: Better error handling * fix: Unescape HTML characters after tags are striped * refactor: Simpify code * fix: Modify to work with #4091 * Sort strings alphabetically * i18n: Updated Polish translation it annoys me that it's not fully localized :P * refactor: Use current_session in PushSubscriptionController * fix: Rebase mistake * fix: Set cacheName to mastodon * refactor: Pull request feedback * refactor: Remove logging statements * chore(yarn): Fix conflicts with master * chore(yarn): Copy latest from master * chore(yarn): Readd offline-plugin * refactor: Use save! and update! * refactor: Send notifications async * fix: Allow retry when push fails * fix: Save track for failed pushes * fix: Minify sw.js * fix: Remove account_id from fabricator
7 years ago
  1. ---
  2. en:
  3. about:
  4. about_mastodon_html: Mastodon is a social network based on open web protocols and free, open-source software. It is decentralized like e-mail.
  5. about_this: About
  6. business_email: 'Business e-mail:'
  7. closed_registrations: Registrations are currently closed on this instance. However! You can find a different instance to make an account on and get access to the very same network from there.
  8. contact: Contact
  9. description_headline: What is %{domain}?
  10. domain_count_after: other instances
  11. domain_count_before: Connected to
  12. features:
  13. humane_approach_body: Learning from failures of other networks, Mastodon aims to make ethical design choices to combat the misuse of social media.
  14. humane_approach_title: A more humane approach
  15. not_a_product_body: Mastodon is not a commercial network. No advertising, no data mining, no walled gardens. There is no central authority.
  16. not_a_product_title: You’re a person, not a product
  17. real_conversation_body: With 500 characters at your disposal and support for granular content and media warnings, you can express yourself the way you want to.
  18. real_conversation_title: Built for real conversation
  19. within_reach_body: Multiple apps for iOS, Android, and other platforms thanks to a developer-friendly API ecosystem allow you to keep up with your friends anywhere.
  20. within_reach_title: Always within reach
  21. find_another_instance: Find another instance
  22. generic_description: "%{domain} is one server in the network"
  23. get_started: Get started
  24. hosted_on: Mastodon hosted on %{domain}
  25. learn_more: Learn more
  26. links: Links
  27. other_instances: Instance list
  28. source_code: Source code
  29. status_count_after: statuses
  30. status_count_before: Who authored
  31. terms: Terms
  32. user_count_after: users
  33. user_count_before: Home to
  34. version: Version
  35. what_is_mastodon: What is Mastodon?
  36. accounts:
  37. follow: Follow
  38. followers: Followers
  39. following: Following
  40. nothing_here: There is nothing here!
  41. people_followed_by: People whom %{name} follows
  42. people_who_follow: People who follow %{name}
  43. posts: Posts
  44. remote_follow: Remote follow
  45. reserved_username: The username is reserved
  46. unfollow: Unfollow
  47. admin:
  48. accounts:
  49. are_you_sure: Are you sure?
  50. confirm: Confirm
  51. confirmed: Confirmed
  52. disable_two_factor_authentication: Disable 2FA
  53. display_name: Display name
  54. domain: Domain
  55. edit: Edit
  56. email: E-mail
  57. feed_url: Feed URL
  58. followers: Followers
  59. follows: Follows
  60. ip: IP
  61. location:
  62. all: All
  63. local: Local
  64. remote: Remote
  65. title: Location
  66. media_attachments: Media attachments
  67. moderation:
  68. all: All
  69. silenced: Silenced
  70. suspended: Suspended
  71. title: Moderation
  72. most_recent_activity: Most recent activity
  73. most_recent_ip: Most recent IP
  74. not_subscribed: Not subscribed
  75. order:
  76. alphabetic: Alphabetic
  77. most_recent: Most recent
  78. title: Order
  79. perform_full_suspension: Perform full suspension
  80. profile_url: Profile URL
  81. public: Public
  82. push_subscription_expires: PuSH subscription expires
  83. redownload: Refresh avatar
  84. reset: Reset
  85. reset_password: Reset password
  86. resubscribe: Resubscribe
  87. salmon_url: Salmon URL
  88. search: Search
  89. show:
  90. created_reports: Reports created by this account
  91. report: report
  92. targeted_reports: Reports made about this account
  93. silence: Silence
  94. statuses: Statuses
  95. subscribe: Subscribe
  96. title: Accounts
  97. undo_silenced: Undo silence
  98. undo_suspension: Undo suspension
  99. unsubscribe: Unsubscribe
  100. username: Username
  101. web: Web
  102. domain_blocks:
  103. add_new: Add new
  104. created_msg: Domain block is now being processed
  105. destroyed_msg: Domain block has been undone
  106. domain: Domain
  107. new:
  108. create: Create block
  109. hint: The domain block will not prevent creation of account entries in the database, but will retroactively and automatically apply specific moderation methods on those accounts.
  110. severity:
  111. desc_html: "<strong>Silence</strong> will make the account's posts invisible to anyone who isn't following them. <strong>Suspend</strong> will remove all of the account's content, media, and profile data."
  112. silence: Silence
  113. suspend: Suspend
  114. title: New domain block
  115. reject_media: Reject media files
  116. reject_media_hint: Removes locally stored media files and refuses to download any in the future. Irrelevant for suspensions
  117. severities:
  118. silence: Silence
  119. suspend: Suspend
  120. severity: Severity
  121. show:
  122. affected_accounts:
  123. one: One account in the database affected
  124. other: "%{count} accounts in the database affected"
  125. retroactive:
  126. silence: Unsilence all existing accounts from this domain
  127. suspend: Unsuspend all existing accounts from this domain
  128. title: Undo domain block for %{domain}
  129. undo: Undo
  130. title: Domain Blocks
  131. undo: Undo
  132. instances:
  133. account_count: Known accounts
  134. domain_name: Domain
  135. title: Known Instances
  136. reports:
  137. action_taken_by: Action taken by
  138. are_you_sure: Are you sure?
  139. comment:
  140. label: Comment
  141. none: None
  142. delete: Delete
  143. id: ID
  144. mark_as_resolved: Mark as resolved
  145. nsfw:
  146. 'false': Unhide media attachments
  147. 'true': Hide media attachments
  148. report: 'Report #%{id}'
  149. report_contents: Contents
  150. reported_account: Reported account
  151. reported_by: Reported by
  152. resolved: Resolved
  153. silence_account: Silence account
  154. status: Status
  155. suspend_account: Suspend account
  156. target: Target
  157. title: Reports
  158. unresolved: Unresolved
  159. view: View
  160. settings:
  161. contact_information:
  162. email: Business e-mail
  163. username: Contact username
  164. registrations:
  165. closed_message:
  166. desc_html: Displayed on frontpage when registrations are closed. You can use HTML tags
  167. title: Closed registration message
  168. deletion:
  169. desc_html: Allow anyone to delete their account
  170. title: Open account deletion
  171. open:
  172. desc_html: Allow anyone to create an account
  173. title: Open registration
  174. site_description:
  175. desc_html: Introductory paragraph on the frontpage and in meta tags. You can use HTML tags, in particular <code>&lt;a&gt;</code> and <code>&lt;em&gt;</code>.
  176. title: Instance description
  177. site_description_extended:
  178. desc_html: A good place for your code of conduct, rules, guidelines and other things that set your instance apart. You can use HTML tags
  179. title: Custom extended information
  180. site_terms:
  181. desc_html: You can write your own privacy policy, terms of service or other legalese. You can use HTML tags
  182. title: Custom terms of service
  183. site_title: Instance name
  184. timeline_preview:
  185. desc_html: Display public timeline on landing page
  186. title: Timeline preview
  187. title: Site Settings
  188. statuses:
  189. back_to_account: Back to account page
  190. batch:
  191. delete: Delete
  192. nsfw_off: NSFW OFF
  193. nsfw_on: NSFW ON
  194. execute: Execute
  195. failed_to_execute: Failed to execute
  196. media:
  197. hide: Hide media
  198. show: Show media
  199. title: Media
  200. no_media: No media
  201. with_media: With media
  202. title: Account statuses
  203. subscriptions:
  204. callback_url: Callback URL
  205. confirmed: Confirmed
  206. expires_in: Expires in
  207. last_delivery: Last delivery
  208. title: PubSubHubbub
  209. topic: Topic
  210. title: Administration
  211. admin_mailer:
  212. new_report:
  213. body: "%{reporter} has reported %{target}"
  214. subject: New report for %{instance} (#%{id})
  215. application_mailer:
  216. settings: 'Change e-mail preferences: %{link}'
  217. signature: Mastodon notifications from %{instance}
  218. view: 'View:'
  219. applications:
  220. invalid_url: The provided URL is invalid
  221. auth:
  222. agreement_html: By signing up you agree to <a href="%{rules_path}">our terms of service</a> and <a href="%{terms_path}">privacy policy</a>.
  223. change_password: Security
  224. delete_account: Delete account
  225. delete_account_html: If you wish to delete your account, you can <a href="%{path}">proceed here</a>. You will be asked for confirmation.
  226. didnt_get_confirmation: Didn't receive confirmation instructions?
  227. forgot_password: Forgot your password?
  228. login: Log in
  229. logout: Logout
  230. register: Sign up
  231. resend_confirmation: Resend confirmation instructions
  232. reset_password: Reset password
  233. set_new_password: Set new password
  234. authorize_follow:
  235. error: Unfortunately, there was an error looking up the remote account
  236. follow: Follow
  237. follow_request: 'You have sent a follow request to:'
  238. following: 'Success! You are now following:'
  239. post_follow:
  240. close: Or, you can just close this window.
  241. return: Return to the user's profile
  242. web: Go to web
  243. prompt_html: 'You (<strong>%{self}</strong>) have requested to follow:'
  244. title: Follow %{acct}
  245. datetime:
  246. distance_in_words:
  247. about_x_hours: "%{count}h"
  248. about_x_months: "%{count}mo"
  249. about_x_years: "%{count}y"
  250. almost_x_years: "%{count}y"
  251. half_a_minute: Just now
  252. less_than_x_minutes: "%{count}m"
  253. less_than_x_seconds: Just now
  254. over_x_years: "%{count}y"
  255. x_days: "%{count}d"
  256. x_minutes: "%{count}m"
  257. x_months: "%{count}mo"
  258. x_seconds: "%{count}s"
  259. deletes:
  260. bad_password_msg: Nice try, hackers! Incorrect password
  261. confirm_password: Enter your current password to verify your identity
  262. description_html: This will <strong>permanently, irreversibly</strong> remove content from your account and deactivate it. Your username will remain reserved to prevent future impersonations.
  263. proceed: Delete account
  264. success_msg: Your account was successfully deleted
  265. warning_html: Only deletion of content from this particular instance is guaranteed. Content that has been widely shared is likely to leave traces. Offline servers and servers that have unsubscribed from your updates will not update their databases.
  266. warning_title: Disseminated content availability
  267. errors:
  268. '403': You don't have permission to view this page.
  269. '404': The page you were looking for doesn't exist.
  270. '410': The page you were looking for doesn't exist anymore.
  271. '422':
  272. content: Security verification failed. Are you blocking cookies?
  273. title: Security verification failed
  274. '429': Throttled
  275. noscript: To use Mastodon, please enable JavaScript.
  276. exports:
  277. blocks: You block
  278. csv: CSV
  279. follows: You follow
  280. mutes: You mute
  281. storage: Media storage
  282. followers:
  283. domain: Domain
  284. explanation_html: If you want to ensure the privacy of your statuses, you must be aware of who is following you. <strong>Your private statuses are delivered to all instances where you have followers</strong>. You may wish to review them, and remove followers if you do not trust your privacy to be respected by the staff or software of those instances.
  285. followers_count: Number of followers
  286. lock_link: Lock your account
  287. purge: Remove from followers
  288. success:
  289. one: In the process of soft-blocking followers from one domain...
  290. other: In the process of soft-blocking followers from %{count} domains...
  291. true_privacy_html: Please mind that <strong>true privacy can only be achieved with end-to-end encryption</strong>.
  292. unlocked_warning_html: Anyone can follow you to immediately view your private statuses. %{lock_link} to be able to review and reject followers.
  293. unlocked_warning_title: Your account is not locked
  294. generic:
  295. changes_saved_msg: Changes successfully saved!
  296. powered_by: powered by %{link}
  297. save_changes: Save changes
  298. validation_errors:
  299. one: Something isn't quite right yet! Please review the error below
  300. other: Something isn't quite right yet! Please review %{count} errors below
  301. imports:
  302. preface: You can import data that you have exported from another instance, such as a list of the people you are following or blocking.
  303. success: Your data was successfully uploaded and will now be processed in due time
  304. types:
  305. blocking: Blocking list
  306. following: Following list
  307. muting: Muting list
  308. upload: Upload
  309. landing_strip_html: "<strong>%{name}</strong> is a user on %{link_to_root_path}. You can follow them or interact with them if you have an account anywhere in the fediverse."
  310. landing_strip_signup_html: If you don't, you can <a href="%{sign_up_path}">sign up here</a>.
  311. media_attachments:
  312. validations:
  313. images_and_video: Cannot attach a video to a status that already contains images
  314. too_many: Cannot attach more than 4 files
  315. notification_mailer:
  316. digest:
  317. body: 'Here is a brief summary of what you missed on %{instance} since your last visit on %{since}:'
  318. mention: "%{name} mentioned you in:"
  319. new_followers_summary:
  320. one: You have acquired one new follower! Yay!
  321. other: You have gotten %{count} new followers! Amazing!
  322. subject:
  323. one: "1 new notification since your last visit \U0001F418"
  324. other: "%{count} new notifications since your last visit \U0001F418"
  325. favourite:
  326. body: 'Your status was favourited by %{name}:'
  327. subject: "%{name} favourited your status"
  328. follow:
  329. body: "%{name} is now following you!"
  330. subject: "%{name} is now following you"
  331. follow_request:
  332. body: "%{name} has requested to follow you"
  333. subject: 'Pending follower: %{name}'
  334. mention:
  335. body: 'You were mentioned by %{name} in:'
  336. subject: You were mentioned by %{name}
  337. reblog:
  338. body: 'Your status was boosted by %{name}:'
  339. subject: "%{name} boosted your status"
  340. pagination:
  341. next: Next
  342. prev: Prev
  343. truncate: "&hellip;"
  344. push_notifications:
  345. favourite:
  346. title: "%{name} favourited your status"
  347. follow:
  348. title: "%{name} is now following you"
  349. mention:
  350. action_boost: 'Boost'
  351. action_expand: 'Show more'
  352. action_favourite: 'Favourite'
  353. title: "%{name} mentioned you"
  354. reblog:
  355. title: "%{name} boosted your status"
  356. subscribed:
  357. body: "You can now receive push notifications."
  358. title: "Subscription registered!"
  359. remote_follow:
  360. acct: Enter your username@domain you want to follow from
  361. missing_resource: Could not find the required redirect URL for your account
  362. proceed: Proceed to follow
  363. prompt: 'You are going to follow:'
  364. sessions:
  365. activity: Last activity
  366. browser: Browser
  367. browsers:
  368. alipay: Alipay
  369. blackberry: Blackberry
  370. chrome: Chrome
  371. edge: Microsoft Edge
  372. firefox: Firefox
  373. generic: Unknown browser
  374. ie: Internet Explorer
  375. micro_messenger: MicroMessenger
  376. nokia: Nokia S40 Ovi Browser
  377. opera: Opera
  378. phantom_js: PhantomJS
  379. qq: QQ Browser
  380. safari: Safari
  381. uc_browser: UCBrowser
  382. weibo: Weibo
  383. current_session: Current session
  384. description: "%{browser} on %{platform}"
  385. explanation: These are the web browsers currently logged in to your Mastodon account.
  386. ip: IP
  387. platforms:
  388. adobe_air: Adobe Air
  389. android: Android
  390. blackberry: Blackberry
  391. chrome_os: ChromeOS
  392. firefox_os: Firefox OS
  393. ios: iOS
  394. linux: Linux
  395. mac: Mac
  396. other: unknown platform
  397. windows: Windows
  398. windows_mobile: Windows Mobile
  399. windows_phone: Windows Phone
  400. title: Sessions
  401. settings:
  402. authorized_apps: Authorized apps
  403. back: Back to Mastodon
  404. delete: Account deletion
  405. edit_profile: Edit profile
  406. export: Data export
  407. followers: Authorized followers
  408. import: Import
  409. preferences: Preferences
  410. settings: Settings
  411. two_factor_authentication: Two-factor Authentication
  412. statuses:
  413. open_in_web: Open in web
  414. over_character_limit: character limit of %{max} exceeded
  415. show_more: Show more
  416. visibilities:
  417. private: Followers-only
  418. private_long: Only show to followers
  419. public: Public
  420. public_long: Everyone can see
  421. unlisted: Unlisted
  422. unlisted_long: Everyone can see, but not listed on public timelines
  423. stream_entries:
  424. click_to_show: Click to show
  425. reblogged: boosted
  426. sensitive_content: Sensitive content
  427. terms:
  428. body_html: |
  429. <h2>Privacy Policy</h2>
  430. <h3 id="collect">What information do we collect?</h3>
  431. <p>We collect information from you when you register on our site and gather data when you participate in the forum by reading, writing, and evaluating the content shared here.</p>
  432. <p>When registering on our site, you may be asked to enter your name and e-mail address. You may, however, visit our site without registering. Your e-mail address will be verified by an email containing a unique link. If that link is visited, we know that you control the e-mail address.</p>
  433. <p>When registered and posting, we record the IP address that the post originated from. We also may retain server logs which include the IP address of every request to our server.</p>
  434. <h3 id="use">What do we use your information for?</h3>
  435. <p>Any of the information we collect from you may be used in one of the following ways:</p>
  436. <ul>
  437. <li>To personalize your experience &mdash; your information helps us to better respond to your individual needs.</li>
  438. <li>To improve our site &mdash; we continually strive to improve our site offerings based on the information and feedback we receive from you.</li>
  439. <li>To improve customer service &mdash; your information helps us to more effectively respond to your customer service requests and support needs.</li>
  440. <li>To send periodic emails &mdash; The email address you provide may be used to send you information, notifications that you request about changes to topics or in response to your user name, respond to inquiries, and/or other requests or questions.</li>
  441. </ul>
  442. <h3 id="protect">How do we protect your information?</h3>
  443. <p>We implement a variety of security measures to maintain the safety of your personal information when you enter, submit, or access your personal information.</p>
  444. <h3 id="data-retention">What is your data retention policy?</h3>
  445. <p>We will make a good faith effort to:</p>
  446. <ul>
  447. <li>Retain server logs containing the IP address of all requests to this server no more than 90 days.</li>
  448. <li>Retain the IP addresses associated with registered users and their posts no more than 5 years.</li>
  449. </ul>
  450. <h3 id="cookies">Do we use cookies?</h3>
  451. <p>Yes. Cookies are small files that a site or its service provider transfers to your computer's hard drive through your Web browser (if you allow). These cookies enable the site to recognize your browser and, if you have a registered account, associate it with your registered account.</p>
  452. <p>We use cookies to understand and save your preferences for future visits and compile aggregate data about site traffic and site interaction so that we can offer better site experiences and tools in the future. We may contract with third-party service providers to assist us in better understanding our site visitors. These service providers are not permitted to use the information collected on our behalf except to help us conduct and improve our business.</p>
  453. <h3 id="disclose">Do we disclose any information to outside parties?</h3>
  454. <p>We do not sell, trade, or otherwise transfer to outside parties your personally identifiable information. This does not include trusted third parties who assist us in operating our site, conducting our business, or servicing you, so long as those parties agree to keep this information confidential. We may also release your information when we believe release is appropriate to comply with the law, enforce our site policies, or protect ours or others rights, property, or safety. However, non-personally identifiable visitor information may be provided to other parties for marketing, advertising, or other uses.</p>
  455. <h3 id="third-party">Third party links</h3>
  456. <p>Occasionally, at our discretion, we may include or offer third party products or services on our site. These third party sites have separate and independent privacy policies. We therefore have no responsibility or liability for the content and activities of these linked sites. Nonetheless, we seek to protect the integrity of our site and welcome any feedback about these sites.</p>
  457. <h3 id="coppa">Children's Online Privacy Protection Act Compliance</h3>
  458. <p>Our site, products and services are all directed to people who are at least 13 years old. If this server is in the USA, and you are under the age of 13, per the requirements of COPPA (<a href="https://en.wikipedia.org/wiki/Children%27s_Online_Privacy_Protection_Act">Children's Online Privacy Protection Act</a>) do not use this site.</p>
  459. <h3 id="online">Online Privacy Policy Only</h3>
  460. <p>This online privacy policy applies only to information collected through our site and not to information collected offline.</p>
  461. <h3 id="consent">Your Consent</h3>
  462. <p>By using our site, you consent to our web site privacy policy.</p>
  463. <h3 id="changes">Changes to our Privacy Policy</h3>
  464. <p>If we decide to change our privacy policy, we will post those changes on this page.</p>
  465. <p>This document is CC-BY-SA. It was last updated May 31, 2013.</p>
  466. <p>Originally adapted from the <a href="https://github.com/discourse/discourse">Discourse privacy policy</a>.
  467. title: "%{instance} Terms of Service and Privacy Policy"
  468. time:
  469. formats:
  470. default: "%b %d, %Y, %H:%M"
  471. two_factor_authentication:
  472. code_hint: Enter the code generated by your authenticator app to confirm
  473. description_html: If you enable <strong>two-factor authentication</strong>, logging in will require you to be in possession of your phone, which will generate tokens for you to enter.
  474. disable: Disable
  475. enable: Enable
  476. enabled: Two-factor authentication is enabled
  477. enabled_success: Two-factor authentication successfully enabled
  478. generate_recovery_codes: Generate recovery codes
  479. instructions_html: "<strong>Scan this QR code into Google Authenticator or a similiar TOTP app on your phone</strong>. From now on, that app will generate tokens that you will have to enter when logging in."
  480. lost_recovery_codes: Recovery codes allow you to regain access to your account if you lose your phone. If you've lost your recovery codes, you can regenerate them here. Your old recovery codes will be invalidated.
  481. manual_instructions: 'If you can''t scan the QR code and need to enter it manually, here is the plain-text secret:'
  482. recovery_codes: Backup recovery codes
  483. recovery_codes_regenerated: Recovery codes successfully regenerated
  484. recovery_instructions_html: If you ever lose access to your phone, you can use one of the recovery codes below to regain access to your account. <strong>Keep the recovery codes safe</strong>. For example, you may print them and store them with other important documents.
  485. setup: Set up
  486. wrong_code: The entered code was invalid! Are server time and device time correct?
  487. users:
  488. invalid_email: The e-mail address is invalid
  489. invalid_otp_token: Invalid two-factor code